From 89194dee59506cdea8eefff6158ed7fab3c991c8 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 --- .../media3/demo/main/PlayerActivity.java | 7 ++- .../source/DefaultMediaSourceFactory.java | 54 +++++++++++++++---- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java b/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java index a2e960114d..22ee82e179 100644 --- a/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java +++ b/demos/main/src/main/java/androidx/media3/demo/main/PlayerActivity.java @@ -311,8 +311,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/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/DefaultMediaSourceFactory.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/DefaultMediaSourceFactory.java index 5ffb33a7cd..7d8f367172 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/DefaultMediaSourceFactory.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/DefaultMediaSourceFactory.java @@ -58,6 +58,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. @@ -106,9 +107,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; @@ -132,6 +133,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. @@ -144,9 +148,13 @@ 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. */ + @UnstableApi public DefaultMediaSourceFactory(DataSource.Factory dataSourceFactory) { this(dataSourceFactory, new DefaultExtractorsFactory()); } @@ -154,6 +162,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 @@ -163,7 +175,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; @@ -260,6 +273,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). @@ -501,19 +526,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<>(); @@ -549,6 +572,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; @@ -587,19 +619,19 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory { clazz = Class.forName("androidx.media3.exoplayer.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("androidx.media3.exoplayer.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("androidx.media3.exoplayer.hls.HlsMediaSource$Factory") .asSubclass(MediaSource.Factory.class); - mediaSourceFactorySupplier = () -> newInstance(clazz, dataSourceFactory); + mediaSourceFactorySupplier = () -> newInstance(clazz, checkNotNull(dataSourceFactory)); break; case C.CONTENT_TYPE_RTSP: clazz = @@ -609,7 +641,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.