Commit f1fe1c40 by aquilescanta Committed by Oliver Woodman

Extract HlsPlaylistTracker interface

This allows injection of custom implementations and configuration of
DefaultHlsPlaylistTracker without modifying the HlsMediaSource interface.

Issue:#2844

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=198846607
parent 798b29e3
......@@ -6,7 +6,9 @@
extractor for this ([#4297](https://github.com/google/ExoPlayer/issues/4297)).
* DASH: Fix playback getting stuck when playing representations that have both
sidx atoms and non-zero presentationTimeOffset values.
* HLS: Fix adaptation in live playlists with EXT-X-PROGRAM-DATE-TIME tags.
* HLS:
* Allow injection of custom playlist trackers.
* Fix adaptation in live playlists with EXT-X-PROGRAM-DATE-TIME tags.
* Mitigate memory leaks when `MediaSource` loads are slow to cancel
([#4249](https://github.com/google/ExoPlayer/issues/4249)).
* Fix inconsistent `Player.EventListener` invocations for recursive player state
......
......@@ -32,6 +32,7 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispat
import com.google.android.exoplayer2.source.SequenceableLoader;
import com.google.android.exoplayer2.source.SinglePeriodTimeline;
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.source.hls.playlist.DefaultHlsPlaylistTracker;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
......@@ -58,6 +59,7 @@ public final class HlsMediaSource extends BaseMediaSource
private HlsExtractorFactory extractorFactory;
private @Nullable ParsingLoadable.Parser<HlsPlaylist> playlistParser;
private @Nullable HlsPlaylistTracker playlistTracker;
private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private int minLoadableRetryCount;
private boolean allowChunklessPreparation;
......@@ -136,17 +138,38 @@ public final class HlsMediaSource extends BaseMediaSource
* Sets the parser to parse HLS playlists. The default is an instance of {@link
* HlsPlaylistParser}.
*
* <p>Must not be called after calling {@link #setPlaylistTracker} on the same builder.
*
* @param playlistParser A {@link ParsingLoadable.Parser} for HLS playlists.
* @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/
public Factory setPlaylistParser(ParsingLoadable.Parser<HlsPlaylist> playlistParser) {
Assertions.checkState(!isCreateCalled);
Assertions.checkState(playlistTracker == null, "A playlist tracker has already been set.");
this.playlistParser = Assertions.checkNotNull(playlistParser);
return this;
}
/**
* Sets the HLS playlist tracker. The default is an instance of {@link
* DefaultHlsPlaylistTracker}. Playlist trackers must not be shared by {@link HlsMediaSource}
* instances.
*
* <p>Must not be called after calling {@link #setPlaylistParser} on the same builder.
*
* @param playlistTracker A tracker for HLS playlists.
* @return This factory, for convenience.
* @throws IllegalStateException If one of the {@code create} methods has already been called.
*/
public Factory setPlaylistTracker(HlsPlaylistTracker playlistTracker) {
Assertions.checkState(!isCreateCalled);
Assertions.checkState(playlistParser == null, "A playlist parser has already been set.");
this.playlistTracker = Assertions.checkNotNull(playlistTracker);
return this;
}
/**
* Sets the factory to create composite {@link SequenceableLoader}s for when this media source
* loads data from multiple streams (video, audio etc...). The default is an instance of {@link
* DefaultCompositeSequenceableLoaderFactory}.
......@@ -187,8 +210,12 @@ public final class HlsMediaSource extends BaseMediaSource
@Override
public HlsMediaSource createMediaSource(Uri playlistUri) {
isCreateCalled = true;
if (playlistParser == null) {
playlistParser = new HlsPlaylistParser();
if (playlistTracker == null) {
playlistTracker =
new DefaultHlsPlaylistTracker(
hlsDataSourceFactory,
minLoadableRetryCount,
playlistParser != null ? playlistParser : new HlsPlaylistParser());
}
return new HlsMediaSource(
playlistUri,
......@@ -196,7 +223,7 @@ public final class HlsMediaSource extends BaseMediaSource
extractorFactory,
compositeSequenceableLoaderFactory,
minLoadableRetryCount,
playlistParser,
playlistTracker,
allowChunklessPreparation,
tag);
}
......@@ -233,12 +260,10 @@ public final class HlsMediaSource extends BaseMediaSource
private final HlsDataSourceFactory dataSourceFactory;
private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private final int minLoadableRetryCount;
private final ParsingLoadable.Parser<HlsPlaylist> playlistParser;
private final boolean allowChunklessPreparation;
private final HlsPlaylistTracker playlistTracker;
private final @Nullable Object tag;
private HlsPlaylistTracker playlistTracker;
/**
* @param manifestUri The {@link Uri} of the HLS manifest.
* @param dataSourceFactory An {@link HlsDataSourceFactory} for {@link DataSource}s for manifests,
......@@ -276,8 +301,13 @@ public final class HlsMediaSource extends BaseMediaSource
int minLoadableRetryCount,
Handler eventHandler,
MediaSourceEventListener eventListener) {
this(manifestUri, new DefaultHlsDataSourceFactory(dataSourceFactory),
HlsExtractorFactory.DEFAULT, minLoadableRetryCount, eventHandler, eventListener,
this(
manifestUri,
new DefaultHlsDataSourceFactory(dataSourceFactory),
HlsExtractorFactory.DEFAULT,
minLoadableRetryCount,
eventHandler,
eventListener,
new HlsPlaylistParser());
}
......@@ -309,7 +339,8 @@ public final class HlsMediaSource extends BaseMediaSource
extractorFactory,
new DefaultCompositeSequenceableLoaderFactory(),
minLoadableRetryCount,
playlistParser,
new DefaultHlsPlaylistTracker(
dataSourceFactory, minLoadableRetryCount, new HlsPlaylistParser()),
/* allowChunklessPreparation= */ false,
/* tag= */ null);
if (eventHandler != null && eventListener != null) {
......@@ -323,7 +354,7 @@ public final class HlsMediaSource extends BaseMediaSource
HlsExtractorFactory extractorFactory,
CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory,
int minLoadableRetryCount,
ParsingLoadable.Parser<HlsPlaylist> playlistParser,
HlsPlaylistTracker playlistTracker,
boolean allowChunklessPreparation,
@Nullable Object tag) {
this.manifestUri = manifestUri;
......@@ -331,7 +362,7 @@ public final class HlsMediaSource extends BaseMediaSource
this.extractorFactory = extractorFactory;
this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory;
this.minLoadableRetryCount = minLoadableRetryCount;
this.playlistParser = playlistParser;
this.playlistTracker = playlistTracker;
this.allowChunklessPreparation = allowChunklessPreparation;
this.tag = tag;
}
......@@ -339,9 +370,7 @@ public final class HlsMediaSource extends BaseMediaSource
@Override
public void prepareSourceInternal(ExoPlayer player, boolean isTopLevelSource) {
EventDispatcher eventDispatcher = createEventDispatcher(/* mediaPeriodId= */ null);
playlistTracker = new HlsPlaylistTracker(manifestUri, dataSourceFactory, eventDispatcher,
minLoadableRetryCount, this, playlistParser);
playlistTracker.start();
playlistTracker.start(manifestUri, eventDispatcher, /* listener= */ this);
}
@Override
......@@ -373,7 +402,6 @@ public final class HlsMediaSource extends BaseMediaSource
public void releaseSourceInternal() {
if (playlistTracker != null) {
playlistTracker.release();
playlistTracker = null;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment