From c9e4f6b429ef9033f41cab978b007b8626fb5d0e Mon Sep 17 00:00:00 2001 From: aquilescanta Date: Mon, 17 Sep 2018 10:43:57 -0700 Subject: [PATCH] Make HlsMediaSource.Factory take a factory of trackers instead of an instance This allows creating multiple HLS media sources from a single Factory, as required by the interface. Issue:#4814 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=213297850 --- RELEASENOTES.md | 2 + .../exoplayer2/source/hls/HlsMediaSource.java | 43 +++++-------------- .../playlist/DefaultHlsPlaylistTracker.java | 3 ++ .../hls/playlist/HlsPlaylistTracker.java | 18 ++++++++ 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 161a11300d3..dc4b5a5698a 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -40,6 +40,8 @@ ([#4422](https://github.com/google/ExoPlayer/issues/4422)). * Fix the bitrate being unset on primary track sample formats ([#3297](https://github.com/google/ExoPlayer/issues/3297)). + * Make `HlsMediaSource.Factory` take a factory of trackers instead of a + tracker instance ([#4814](https://github.com/google/ExoPlayer/issues/4814)). * DASH: * Support `messageData` attribute for in-manifest event streams. * Clip periods to their specified durations diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java index 79b030a0ee3..a075dacf3ae 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/HlsMediaSource.java @@ -63,8 +63,8 @@ public static final class Factory implements AdsMediaSource.MediaSourceFactory { private final HlsDataSourceFactory hlsDataSourceFactory; private HlsExtractorFactory extractorFactory; - private @Nullable HlsPlaylistParserFactory playlistParserFactory; - private @Nullable HlsPlaylistTracker playlistTracker; + private HlsPlaylistParserFactory playlistParserFactory; + private HlsPlaylistTracker.Factory playlistTrackerFactory; private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private LoadErrorHandlingPolicy loadErrorHandlingPolicy; private boolean allowChunklessPreparation; @@ -90,6 +90,8 @@ public Factory(DataSource.Factory dataSourceFactory) { */ public Factory(HlsDataSourceFactory hlsDataSourceFactory) { this.hlsDataSourceFactory = Assertions.checkNotNull(hlsDataSourceFactory); + playlistParserFactory = new DefaultHlsPlaylistParserFactory(); + playlistTrackerFactory = DefaultHlsPlaylistTracker.FACTORY; extractorFactory = HlsExtractorFactory.DEFAULT; loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy(); compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory(); @@ -131,9 +133,6 @@ public Factory setExtractorFactory(HlsExtractorFactory extractorFactory) { * *

Calling this method overrides any calls to {@link #setMinLoadableRetryCount(int)}. * - *

If {@link #setPlaylistTracker} is not called on this builder, {@code - * loadErrorHandlingPolicy} is used for creating the used {@link DefaultHlsPlaylistTracker}. - * * @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}. * @return This factory, for convenience. * @throws IllegalStateException If one of the {@code create} methods has already been called. @@ -168,35 +167,27 @@ public Factory setMinLoadableRetryCount(int minLoadableRetryCount) { * Sets the factory from which playlist parsers will be obtained. The default value is created * by calling {@link DefaultHlsPlaylistParserFactory#DefaultHlsPlaylistParserFactory()}. * - *

Must not be called after calling {@link #setPlaylistTracker} on the same builder. - * * @param playlistParserFactory An {@link HlsPlaylistParserFactory}. * @return This factory, for convenience. * @throws IllegalStateException If one of the {@code create} methods has already been called. */ public Factory setPlaylistParserFactory(HlsPlaylistParserFactory playlistParserFactory) { Assertions.checkState(!isCreateCalled); - Assertions.checkState(playlistTracker == null, "A playlist tracker has already been set."); this.playlistParserFactory = Assertions.checkNotNull(playlistParserFactory); 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. + * Sets the {@link HlsPlaylistTracker} factory. The default value is {@link + * DefaultHlsPlaylistTracker#FACTORY}. * - *

Must not be called after calling {@link #setPlaylistParserFactory} on the same builder. - * - * @param playlistTracker A tracker for HLS playlists. + * @param playlistTrackerFactory A factory for {@link HlsPlaylistTracker} instances. * @return This factory, for convenience. * @throws IllegalStateException If one of the {@code create} methods has already been called. */ - public Factory setPlaylistTracker(HlsPlaylistTracker playlistTracker) { + public Factory setPlaylistTrackerFactory(HlsPlaylistTracker.Factory playlistTrackerFactory) { Assertions.checkState(!isCreateCalled); - Assertions.checkState( - playlistParserFactory == null, "A playlist parser factory has already been set."); - this.playlistTracker = Assertions.checkNotNull(playlistTracker); + this.playlistTrackerFactory = Assertions.checkNotNull(playlistTrackerFactory); return this; } @@ -241,26 +232,14 @@ public Factory setAllowChunklessPreparation(boolean allowChunklessPreparation) { @Override public HlsMediaSource createMediaSource(Uri playlistUri) { isCreateCalled = true; - if (playlistTracker == null) { - if (playlistParserFactory == null) { - playlistTracker = - new DefaultHlsPlaylistTracker( - hlsDataSourceFactory, - loadErrorHandlingPolicy, - new DefaultHlsPlaylistParserFactory()); - } else { - playlistTracker = - new DefaultHlsPlaylistTracker( - hlsDataSourceFactory, loadErrorHandlingPolicy, playlistParserFactory); - } - } return new HlsMediaSource( playlistUri, hlsDataSourceFactory, extractorFactory, compositeSequenceableLoaderFactory, loadErrorHandlingPolicy, - playlistTracker, + playlistTrackerFactory.createTracker( + hlsDataSourceFactory, loadErrorHandlingPolicy, playlistParserFactory), allowChunklessPreparation, tag); } diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java index ac94d7307ec..4e34c556e01 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/DefaultHlsPlaylistTracker.java @@ -41,6 +41,9 @@ public final class DefaultHlsPlaylistTracker implements HlsPlaylistTracker, Loader.Callback> { + /** Factory for {@link DefaultHlsPlaylistTracker} instances. */ + public static final Factory FACTORY = DefaultHlsPlaylistTracker::new; + /** * Coefficient applied on the target duration of a playlist to determine the amount of time after * which an unchanging playlist is considered stuck. diff --git a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java index 49896bd57b0..b83ae43f47f 100644 --- a/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java +++ b/library/hls/src/main/java/com/google/android/exoplayer2/source/hls/playlist/HlsPlaylistTracker.java @@ -19,7 +19,9 @@ import android.support.annotation.Nullable; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; +import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl; +import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import java.io.IOException; /** @@ -36,6 +38,22 @@ */ public interface HlsPlaylistTracker { + /** Factory for {@link HlsPlaylistTracker} instances. */ + interface Factory { + + /** + * Creates a new tracker instance. + * + * @param dataSourceFactory The {@link HlsDataSourceFactory} to use for playlist loading. + * @param loadErrorHandlingPolicy The {@link LoadErrorHandlingPolicy} for playlist load errors. + * @param playlistParserFactory The {@link HlsPlaylistParserFactory} for playlist parsing. + */ + HlsPlaylistTracker createTracker( + HlsDataSourceFactory dataSourceFactory, + LoadErrorHandlingPolicy loadErrorHandlingPolicy, + HlsPlaylistParserFactory playlistParserFactory); + } + /** Listener for primary playlist changes. */ interface PrimaryPlaylistListener {