Skip to content

Commit

Permalink
HLS Live Streaming with DVR window and seek support added
Browse files Browse the repository at this point in the history
[Problem]
Exoplayer does not support HLS Live streaming with DVR window and seek.

[Solution]
1. Support for available seek range added.
2. Support for seek within DVR window range added.

[Known Issues]
 1. Seeking beyond the live window is handled as follows:
    a. If the seek position is less than lower bound, we start playback from the first
available chunk data.
    b. If the seek position is greater than upper bound, we start giving data from the live
edge, however, exoplayer skips frames till it gets the data corresponding
to the seeked position

 2. We assume either media sequence or program date time is always present in the media playlist.
Playlists without media sequency or program date time is not handled. Behaviour is
unpredictable.

 3. Media playlist refresh time is aggresively fixed at half the target duration.
 We are yet to honor the spec that says if the last fetch did not change
 the playlist, try again after half the target duration, otherwise
 try after the target duration.

 4. We assume that playlist always have timezone in program date time or
 never have timezone.
 If this assumption fails, live DVR functionality will be broken.

[Tests]
1. Manifests with either program date time or media sequence or both tested.
2. Manifests with variable segment duration is tested.
2. Adaptive bitrate Switching tested. Also tested the case where available
range might be different across variants.
  • Loading branch information
peddisri committed Mar 24, 2016
1 parent f954964 commit 5cce28a
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.google.android.exoplayer.dash.DashChunkSource;
import com.google.android.exoplayer.drm.StreamingDrmSessionManager;
import com.google.android.exoplayer.extractor.ExtractorSampleSource;
import com.google.android.exoplayer.hls.HlsChunkSource;
import com.google.android.exoplayer.hls.HlsSampleSource;
import com.google.android.exoplayer.metadata.MetadataTrackRenderer.MetadataRenderer;
import com.google.android.exoplayer.metadata.id3.Id3Frame;
Expand Down Expand Up @@ -63,7 +64,8 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi
SingleSampleSource.EventListener, DefaultBandwidthMeter.EventListener,
MediaCodecVideoTrackRenderer.EventListener, MediaCodecAudioTrackRenderer.EventListener,
StreamingDrmSessionManager.EventListener, DashChunkSource.EventListener, TextRenderer,
MetadataRenderer<List<Id3Frame>>, DebugTextViewHelper.Provider {
MetadataRenderer<List<Id3Frame>>, DebugTextViewHelper.Provider,
HlsChunkSource.EventListener {

/**
* Builds renderers for the player.
Expand Down Expand Up @@ -533,6 +535,9 @@ public void onAvailableRangeChanged(int sourceId, TimeRange availableRange) {
if (infoListener != null) {
infoListener.onAvailableRangeChanged(sourceId, availableRange);
}
if (playerControl != null) {
playerControl.setAvailableRange(availableRange);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ public void onSingleManifest(HlsPlaylist manifest) {
DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
HlsChunkSource chunkSource = new HlsChunkSource(true /* isMaster */, dataSource, url,
manifest, DefaultHlsTrackSelector.newDefaultInstance(context), bandwidthMeter,
timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE);
timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE,
player.getMainHandler(), player, DemoPlayer.TYPE_VIDEO);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
MAIN_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, DemoPlayer.TYPE_VIDEO);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
Expand All @@ -162,7 +163,8 @@ public void onSingleManifest(HlsPlaylist manifest) {
DataSource audioDataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
HlsChunkSource audioChunkSource = new HlsChunkSource(false /* isMaster */, audioDataSource,
url, manifest, DefaultHlsTrackSelector.newAudioInstance(), bandwidthMeter,
timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE);
timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE,
player.getMainHandler(), player,DemoPlayer.TYPE_AUDIO);
HlsSampleSource audioSampleSource = new HlsSampleSource(audioChunkSource, loadControl,
AUDIO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player,
DemoPlayer.TYPE_AUDIO);
Expand All @@ -182,7 +184,8 @@ public void onSingleManifest(HlsPlaylist manifest) {
DataSource textDataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
HlsChunkSource textChunkSource = new HlsChunkSource(false /* isMaster */, textDataSource,
url, manifest, DefaultHlsTrackSelector.newSubtitleInstance(), bandwidthMeter,
timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE);
timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE, null, null,
DemoPlayer.TYPE_VIDEO);
HlsSampleSource textSampleSource = new HlsSampleSource(textChunkSource, loadControl,
TEXT_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, mainHandler, player, DemoPlayer.TYPE_TEXT);
textRenderer = new TextTrackRenderer(textSampleSource, player, mainHandler.getLooper());
Expand Down
Loading

0 comments on commit 5cce28a

Please sign in to comment.