From e39a324b19271eca9fc9e30535017bb6251e8560 Mon Sep 17 00:00:00 2001 From: ibaker Date: Mon, 23 May 2022 13:26:05 +0100 Subject: [PATCH] Add `DefaultMediaSourceFactory.setDataSourceFactory` Also add this to the stable API instead of the constructor that takes `DataSource.Factory`. PiperOrigin-RevId: 450414119 --- .../exoplayer2/demo/PlayerActivity.java | 7 ++- docs/customization.md | 7 ++- docs/downloading-media.md | 3 +- docs/media-sources.md | 3 +- docs/network-stacks.md | 4 +- .../source/DefaultMediaSourceFactory.java | 53 +++++++++++++++---- 6 files changed, 60 insertions(+), 17 deletions(-) diff --git a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java index 0027a4e96a..8932b0780d 100644 --- a/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java +++ b/demos/main/src/main/java/com/google/android/exoplayer2/demo/PlayerActivity.java @@ -308,8 +308,11 @@ public class PlayerActivity extends AppCompatActivity serverSideAdsLoader = serverSideAdLoaderBuilder.build(); ImaServerSideAdInsertionMediaSource.Factory imaServerSideAdInsertionMediaSourceFactory = new ImaServerSideAdInsertionMediaSource.Factory( - serverSideAdsLoader, new DefaultMediaSourceFactory(dataSourceFactory)); - return new DefaultMediaSourceFactory(dataSourceFactory) + serverSideAdsLoader, + new DefaultMediaSourceFactory(/* context= */ this) + .setDataSourceFactory(dataSourceFactory)); + return new DefaultMediaSourceFactory(/* context= */ this) + .setDataSourceFactory(dataSourceFactory) .setDrmSessionManagerProvider(drmSessionManagerProvider) .setLocalAdInsertionComponents( this::getClientSideAdsLoader, /* adViewProvider= */ playerView) diff --git a/docs/customization.md b/docs/customization.md index b594296cd7..a2036bde75 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -59,7 +59,8 @@ DataSource.Factory cacheDataSourceFactory = ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( - new DefaultMediaSourceFactory(cacheDataSourceFactory)) + new DefaultMediaSourceFactory(context) + .setDataSourceFactory(cacheDataSourceFactory)) .build(); ~~~ {: .language-java} @@ -83,7 +84,9 @@ DataSource.Factory dataSourceFactory = () -> { }; ExoPlayer player = new ExoPlayer.Builder(context) - .setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory)) + .setMediaSourceFactory( + new DefaultMediaSourceFactory(context) + .setDataSourceFactory(dataSourceFactory)) .build(); ~~~ {: .language-java} diff --git a/docs/downloading-media.md b/docs/downloading-media.md index 3ef28bd685..70c3e3d308 100644 --- a/docs/downloading-media.md +++ b/docs/downloading-media.md @@ -319,7 +319,8 @@ DataSource.Factory cacheDataSourceFactory = ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( - new DefaultMediaSourceFactory(cacheDataSourceFactory)) + new DefaultMediaSourceFactory(context) + .setDataSourceFactory(cacheDataSourceFactory)) .build(); ~~~ {: .language-java} diff --git a/docs/media-sources.md b/docs/media-sources.md index 5d927b54e2..f7bf97b83a 100644 --- a/docs/media-sources.md +++ b/docs/media-sources.md @@ -34,7 +34,8 @@ these requirements and injected during player construction: ~~~ MediaSource.Factory mediaSourceFactory = - new DefaultMediaSourceFactory(cacheDataSourceFactory) + new DefaultMediaSourceFactory(context) + .setDataSourceFactory(cacheDataSourceFactory) .setLocalAdInsertionComponents( adsLoaderProvider, /* adViewProvider= */ playerView); ExoPlayer player = new ExoPlayer.Builder(context) diff --git a/docs/network-stacks.md b/docs/network-stacks.md index cdacdce154..763c879722 100644 --- a/docs/network-stacks.md +++ b/docs/network-stacks.md @@ -51,7 +51,9 @@ DefaultDataSource.Factory dataSourceFactory = // Inject the DefaultDataSource.Factory when creating the player. ExoPlayer player = new ExoPlayer.Builder(context) - .setMediaSourceFactory(new DefaultMediaSourceFactory(dataSourceFactory)) + .setMediaSourceFactory( + new DefaultMediaSourceFactory(context) + .setDataSourceFactory(dataSourceFactory)) .build(); ~~~ {: .language-java} diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java index 4aca4aa02c..8da2a86bd7 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java @@ -57,6 +57,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import org.checkerframework.checker.nullness.compatqual.NullableType; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; /** * The default {@link MediaSource.Factory} implementation. @@ -104,9 +105,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { private static final String TAG = "DMediaSourceFactory"; - private final DataSource.Factory dataSourceFactory; private final DelegateFactoryLoader delegateFactoryLoader; + private DataSource.Factory dataSourceFactory; @Nullable private MediaSource.Factory serverSideAdInsertionMediaSourceFactory; @Nullable private AdsLoader.Provider adsLoaderProvider; @Nullable private AdViewProvider adViewProvider; @@ -130,6 +131,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { /** * Creates a new instance. * + *

Note that this constructor is only useful to try and ensure that ExoPlayer's {@link + * DefaultExtractorsFactory} can be removed by ProGuard or R8. + * * @param context Any context. * @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from * its container. @@ -141,6 +145,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { /** * Creates a new instance. * + *

Note that this constructor is only useful to try and ensure that ExoPlayer's {@link + * DefaultDataSource.Factory} can be removed by ProGuard or R8. + * * @param dataSourceFactory A {@link DataSource.Factory} to create {@link DataSource} instances * for requesting media data. */ @@ -151,6 +158,10 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { /** * Creates a new instance. * + *

Note that this constructor is only useful to try and ensure that ExoPlayer's {@link + * DefaultDataSource.Factory} and {@link DefaultExtractorsFactory} can be removed by ProGuard or + * R8. + * * @param dataSourceFactory A {@link DataSource.Factory} to create {@link DataSource} instances * for requesting media data. * @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from @@ -159,7 +170,8 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { public DefaultMediaSourceFactory( DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) { this.dataSourceFactory = dataSourceFactory; - delegateFactoryLoader = new DelegateFactoryLoader(dataSourceFactory, extractorsFactory); + delegateFactoryLoader = new DelegateFactoryLoader(extractorsFactory); + delegateFactoryLoader.setDataSourceFactory(dataSourceFactory); liveTargetOffsetMs = C.TIME_UNSET; liveMinOffsetMs = C.TIME_UNSET; liveMaxOffsetMs = C.TIME_UNSET; @@ -253,6 +265,18 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { return this; } + /** + * Sets the {@link DataSource.Factory} used to create {@link DataSource} instances for requesting + * media data. + * + * @param dataSourceFactory The {@link DataSource.Factory}. + * @return This factory, for convenience. + */ + public DefaultMediaSourceFactory setDataSourceFactory(DataSource.Factory dataSourceFactory) { + this.dataSourceFactory = dataSourceFactory; + return this; + } + /** * Sets the {@link MediaSource.Factory} used to handle {@link MediaItem} instances containing a * {@link Uri} identified as resolving to content with server side ad insertion (SSAI). @@ -484,19 +508,17 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { /** Loads media source factories lazily. */ private static final class DelegateFactoryLoader { - private final DataSource.Factory dataSourceFactory; private final ExtractorsFactory extractorsFactory; private final Map> mediaSourceFactorySuppliers; private final Set supportedTypes; private final Map mediaSourceFactories; + private DataSource.@MonotonicNonNull Factory dataSourceFactory; @Nullable private DrmSessionManagerProvider drmSessionManagerProvider; @Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy; - public DelegateFactoryLoader( - DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) { - this.dataSourceFactory = dataSourceFactory; + public DelegateFactoryLoader(ExtractorsFactory extractorsFactory) { this.extractorsFactory = extractorsFactory; mediaSourceFactorySuppliers = new HashMap<>(); supportedTypes = new HashSet<>(); @@ -532,6 +554,15 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { return mediaSourceFactory; } + public void setDataSourceFactory(DataSource.Factory dataSourceFactory) { + if (dataSourceFactory != this.dataSourceFactory) { + this.dataSourceFactory = dataSourceFactory; + // TODO(b/233577470): Call MediaSource.Factory.setDataSourceFactory on each value when it + // exists on the interface. + mediaSourceFactories.clear(); + } + } + public void setDrmSessionManagerProvider( @Nullable DrmSessionManagerProvider drmSessionManagerProvider) { this.drmSessionManagerProvider = drmSessionManagerProvider; @@ -570,20 +601,20 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { clazz = Class.forName("com.google.android.exoplayer2.source.dash.DashMediaSource$Factory") .asSubclass(MediaSource.Factory.class); - mediaSourceFactorySupplier = () -> newInstance(clazz, dataSourceFactory); + mediaSourceFactorySupplier = () -> newInstance(clazz, checkNotNull(dataSourceFactory)); break; case C.CONTENT_TYPE_SS: clazz = Class.forName( "com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource$Factory") .asSubclass(MediaSource.Factory.class); - mediaSourceFactorySupplier = () -> newInstance(clazz, dataSourceFactory); + mediaSourceFactorySupplier = () -> newInstance(clazz, checkNotNull(dataSourceFactory)); break; case C.CONTENT_TYPE_HLS: clazz = Class.forName("com.google.android.exoplayer2.source.hls.HlsMediaSource$Factory") .asSubclass(MediaSource.Factory.class); - mediaSourceFactorySupplier = () -> newInstance(clazz, dataSourceFactory); + mediaSourceFactorySupplier = () -> newInstance(clazz, checkNotNull(dataSourceFactory)); break; case C.CONTENT_TYPE_RTSP: clazz = @@ -593,7 +624,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { break; case C.CONTENT_TYPE_OTHER: mediaSourceFactorySupplier = - () -> new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory); + () -> + new ProgressiveMediaSource.Factory( + checkNotNull(dataSourceFactory), extractorsFactory); break; default: // Do nothing.