Commit 34a1f884 by ibaker Committed by tonihei

Add MediaSource.Factory and deprecate MediaSourceFactory

This more closely matches the pattern we have for all implementations
except DefaultMediaSourceFactory (e.g. ProgressiveMediaSource.Factory)
and other factory interfaces like (Http)DataSource.Factory.

PiperOrigin-RevId: 417826803
parent b63c0593
Showing with 169 additions and 133 deletions
......@@ -47,7 +47,7 @@ import androidx.media3.exoplayer.mediacodec.MediaCodecRenderer.DecoderInitializa
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil.DecoderQueryException;
import androidx.media3.exoplayer.offline.DownloadRequest;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ads.AdsLoader;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.util.DebugTextViewHelper;
......@@ -261,7 +261,7 @@ public class PlayerActivity extends AppCompatActivity
intent.getBooleanExtra(IntentUtil.PREFER_EXTENSION_DECODERS_EXTRA, false);
RenderersFactory renderersFactory =
DemoUtil.buildRenderersFactory(/* context= */ this, preferExtensionDecoders);
MediaSourceFactory mediaSourceFactory =
MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(dataSourceFactory)
.setAdsLoaderProvider(this::getAdsLoader)
.setAdViewProvider(playerView);
......
......@@ -53,7 +53,6 @@ import androidx.media3.exoplayer.audio.MediaCodecAudioRenderer;
import androidx.media3.exoplayer.metadata.MetadataRenderer;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.ShuffleOrder;
import androidx.media3.exoplayer.text.TextRenderer;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
......@@ -83,7 +82,7 @@ import java.util.List;
* <ul>
* <li><b>{@link MediaSource MediaSources}</b> that define the media to be played, load the media,
* and from which the loaded media can be read. MediaSources are created from {@link MediaItem
* MediaItems} by the {@link MediaSourceFactory} injected into the player {@link
* MediaItems} by the {@link MediaSource.Factory} injected into the player {@link
* Builder#setMediaSourceFactory Builder}, or can be added directly by methods like {@link
* #setMediaSource(MediaSource)}. The library provides a {@link DefaultMediaSourceFactory} for
* progressive media files, DASH, SmoothStreaming and HLS, which also includes functionality
......@@ -379,7 +378,7 @@ public interface ExoPlayer extends Player {
/* package */ Clock clock;
/* package */ long foregroundModeTimeoutMs;
/* package */ Supplier<RenderersFactory> renderersFactorySupplier;
/* package */ Supplier<MediaSourceFactory> mediaSourceFactorySupplier;
/* package */ Supplier<MediaSource.Factory> mediaSourceFactorySupplier;
/* package */ Supplier<TrackSelector> trackSelectorSupplier;
/* package */ Supplier<LoadControl> loadControlSupplier;
/* package */ Supplier<BandwidthMeter> bandwidthMeterSupplier;
......@@ -407,7 +406,7 @@ public interface ExoPlayer extends Player {
* Creates a builder.
*
* <p>Use {@link #Builder(Context, RenderersFactory)}, {@link #Builder(Context,
* MediaSourceFactory)} or {@link #Builder(Context, RenderersFactory, MediaSourceFactory)}
* MediaSource.Factory)} or {@link #Builder(Context, RenderersFactory, MediaSource.Factory)}
* instead, if you intend to provide a custom {@link RenderersFactory}, {@link
* ExtractorsFactory} or {@link DefaultMediaSourceFactory}. This is to ensure that ProGuard or
* R8 can remove ExoPlayer's {@link DefaultRenderersFactory}, {@link DefaultExtractorsFactory}
......@@ -418,7 +417,7 @@ public interface ExoPlayer extends Player {
* <ul>
* <li>{@link RenderersFactory}: {@link DefaultRenderersFactory}
* <li>{@link TrackSelector}: {@link DefaultTrackSelector}
* <li>{@link MediaSourceFactory}: {@link DefaultMediaSourceFactory}
* <li>{@link MediaSource.Factory}: {@link DefaultMediaSourceFactory}
* <li>{@link LoadControl}: {@link DefaultLoadControl}
* <li>{@link BandwidthMeter}: {@link DefaultBandwidthMeter#getSingletonInstance(Context)}
* <li>{@link LivePlaybackSpeedControl}: {@link DefaultLivePlaybackSpeedControl}
......@@ -474,7 +473,7 @@ public interface ExoPlayer extends Player {
}
/**
* Creates a builder with a custom {@link MediaSourceFactory}.
* Creates a builder with a custom {@link MediaSource.Factory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
......@@ -487,12 +486,12 @@ public interface ExoPlayer extends Player {
* MediaItem}.
*/
@UnstableApi
public Builder(Context context, MediaSourceFactory mediaSourceFactory) {
public Builder(Context context, MediaSource.Factory mediaSourceFactory) {
this(context, () -> new DefaultRenderersFactory(context), () -> mediaSourceFactory);
}
/**
* Creates a builder with a custom {@link RenderersFactory} and {@link MediaSourceFactory}.
* Creates a builder with a custom {@link RenderersFactory} and {@link MediaSource.Factory}.
*
* <p>See {@link #Builder(Context)} for a list of default values.
*
......@@ -508,7 +507,9 @@ public interface ExoPlayer extends Player {
*/
@UnstableApi
public Builder(
Context context, RenderersFactory renderersFactory, MediaSourceFactory mediaSourceFactory) {
Context context,
RenderersFactory renderersFactory,
MediaSource.Factory mediaSourceFactory) {
this(context, () -> renderersFactory, () -> mediaSourceFactory);
}
......@@ -521,7 +522,7 @@ public interface ExoPlayer extends Player {
* @param context A {@link Context}.
* @param renderersFactory A factory for creating {@link Renderer Renderers} to be used by the
* player.
* @param mediaSourceFactory A {@link MediaSourceFactory}.
* @param mediaSourceFactory A {@link MediaSource.Factory}.
* @param trackSelector A {@link TrackSelector}.
* @param loadControl A {@link LoadControl}.
* @param bandwidthMeter A {@link BandwidthMeter}.
......@@ -531,7 +532,7 @@ public interface ExoPlayer extends Player {
public Builder(
Context context,
RenderersFactory renderersFactory,
MediaSourceFactory mediaSourceFactory,
MediaSource.Factory mediaSourceFactory,
TrackSelector trackSelector,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
......@@ -549,7 +550,7 @@ public interface ExoPlayer extends Player {
private Builder(
Context context,
Supplier<RenderersFactory> renderersFactorySupplier,
Supplier<MediaSourceFactory> mediaSourceFactorySupplier) {
Supplier<MediaSource.Factory> mediaSourceFactorySupplier) {
this(
context,
renderersFactorySupplier,
......@@ -563,7 +564,7 @@ public interface ExoPlayer extends Player {
private Builder(
Context context,
Supplier<RenderersFactory> renderersFactorySupplier,
Supplier<MediaSourceFactory> mediaSourceFactorySupplier,
Supplier<MediaSource.Factory> mediaSourceFactorySupplier,
Supplier<TrackSelector> trackSelectorSupplier,
Supplier<LoadControl> loadControlSupplier,
Supplier<BandwidthMeter> bandwidthMeterSupplier,
......@@ -624,13 +625,13 @@ public interface ExoPlayer extends Player {
}
/**
* Sets the {@link MediaSourceFactory} that will be used by the player.
* Sets the {@link MediaSource.Factory} that will be used by the player.
*
* @param mediaSourceFactory A {@link MediaSourceFactory}.
* @param mediaSourceFactory A {@link MediaSource.Factory}.
* @return This builder.
* @throws IllegalStateException If {@link #build()} has already been called.
*/
public Builder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
public Builder setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
checkState(!buildCalled);
this.mediaSourceFactorySupplier = () -> mediaSourceFactory;
return this;
......
......@@ -101,7 +101,6 @@ import androidx.media3.exoplayer.analytics.AnalyticsCollector;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.ShuffleOrder;
import androidx.media3.exoplayer.trackselection.ExoTrackSelection;
import androidx.media3.exoplayer.trackselection.TrackSelector;
......@@ -144,7 +143,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
private final Timeline.Window window;
private final List<MediaSourceHolderSnapshot> mediaSourceHolderSnapshots;
private final boolean useLazyPreparation;
private final MediaSourceFactory mediaSourceFactory;
private final MediaSource.Factory mediaSourceFactory;
private final AnalyticsCollector analyticsCollector;
private final Looper applicationLooper;
private final BandwidthMeter bandwidthMeter;
......@@ -183,7 +182,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
*
* @param renderers The {@link Renderer}s.
* @param trackSelector The {@link TrackSelector}.
* @param mediaSourceFactory The {@link MediaSourceFactory}.
* @param mediaSourceFactory The {@link MediaSource.Factory}.
* @param loadControl The {@link LoadControl}.
* @param bandwidthMeter The {@link BandwidthMeter}.
* @param analyticsCollector The {@link AnalyticsCollector}.
......@@ -207,7 +206,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
public ExoPlayerImpl(
Renderer[] renderers,
TrackSelector trackSelector,
MediaSourceFactory mediaSourceFactory,
MediaSource.Factory mediaSourceFactory,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
AnalyticsCollector analyticsCollector,
......
......@@ -34,7 +34,6 @@ import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaPeriod;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.upstream.Allocator;
import androidx.media3.exoplayer.upstream.DefaultAllocator;
import androidx.media3.extractor.DefaultExtractorsFactory;
......@@ -54,7 +53,7 @@ public final class MetadataRetriever {
/**
* Retrieves the {@link TrackGroupArray} corresponding to a {@link MediaItem}.
*
* <p>This is equivalent to using {@link #retrieveMetadata(MediaSourceFactory, MediaItem)} with a
* <p>This is equivalent to using {@link #retrieveMetadata(MediaSource.Factory, MediaItem)} with a
* {@link DefaultMediaSourceFactory} and a {@link DefaultExtractorsFactory} with {@link
* Mp4Extractor#FLAG_READ_MOTION_PHOTO_METADATA} and {@link Mp4Extractor#FLAG_READ_SEF_DATA} set.
*
......@@ -72,13 +71,13 @@ public final class MetadataRetriever {
*
* <p>This method is thread-safe.
*
* @param mediaSourceFactory mediaSourceFactory The {@link MediaSourceFactory} to use to read the
* @param mediaSourceFactory mediaSourceFactory The {@link MediaSource.Factory} to use to read the
* data.
* @param mediaItem The {@link MediaItem} whose metadata should be retrieved.
* @return A {@link ListenableFuture} of the result.
*/
public static ListenableFuture<TrackGroupArray> retrieveMetadata(
MediaSourceFactory mediaSourceFactory, MediaItem mediaItem) {
MediaSource.Factory mediaSourceFactory, MediaItem mediaItem) {
return retrieveMetadata(mediaSourceFactory, mediaItem, Clock.DEFAULT);
}
......@@ -89,13 +88,13 @@ public final class MetadataRetriever {
new DefaultExtractorsFactory()
.setMp4ExtractorFlags(
Mp4Extractor.FLAG_READ_MOTION_PHOTO_METADATA | Mp4Extractor.FLAG_READ_SEF_DATA);
MediaSourceFactory mediaSourceFactory =
MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(context, extractorsFactory);
return retrieveMetadata(mediaSourceFactory, mediaItem, clock);
}
private static ListenableFuture<TrackGroupArray> retrieveMetadata(
MediaSourceFactory mediaSourceFactory, MediaItem mediaItem, Clock clock) {
MediaSource.Factory mediaSourceFactory, MediaItem mediaItem, Clock clock) {
// Recreate thread and handler every time this method is called so that it can be used
// concurrently.
return new MetadataRetrieverInternal(mediaSourceFactory, clock).retrieveMetadata(mediaItem);
......@@ -108,12 +107,12 @@ public final class MetadataRetriever {
private static final int MESSAGE_CONTINUE_LOADING = 2;
private static final int MESSAGE_RELEASE = 3;
private final MediaSourceFactory mediaSourceFactory;
private final MediaSource.Factory mediaSourceFactory;
private final HandlerThread mediaSourceThread;
private final HandlerWrapper mediaSourceHandler;
private final SettableFuture<TrackGroupArray> trackGroupsFuture;
public MetadataRetrieverInternal(MediaSourceFactory mediaSourceFactory, Clock clock) {
public MetadataRetrieverInternal(MediaSource.Factory mediaSourceFactory, Clock clock) {
this.mediaSourceFactory = mediaSourceFactory;
mediaSourceThread = new HandlerThread("ExoPlayer:MetadataRetriever");
mediaSourceThread.start();
......
......@@ -77,7 +77,6 @@ import androidx.media3.exoplayer.audio.AudioRendererEventListener;
import androidx.media3.exoplayer.metadata.MetadataOutput;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.ShuffleOrder;
import androidx.media3.exoplayer.text.TextOutput;
import androidx.media3.exoplayer.trackselection.TrackSelector;
......@@ -124,7 +123,7 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* @deprecated Use {@link ExoPlayer.Builder#Builder(Context, MediaSourceFactory)} and {@link
* @deprecated Use {@link ExoPlayer.Builder#Builder(Context, MediaSource.Factory)} and {@link
* DefaultMediaSourceFactory#DefaultMediaSourceFactory(Context, ExtractorsFactory)} instead.
*/
@Deprecated
......@@ -135,7 +134,7 @@ public class SimpleExoPlayer extends BasePlayer
/**
* @deprecated Use {@link ExoPlayer.Builder#Builder(Context, RenderersFactory,
* MediaSourceFactory)} and {@link
* MediaSource.Factory)} and {@link
* DefaultMediaSourceFactory#DefaultMediaSourceFactory(Context, ExtractorsFactory)} instead.
*/
@Deprecated
......@@ -148,7 +147,7 @@ public class SimpleExoPlayer extends BasePlayer
/**
* @deprecated Use {@link ExoPlayer.Builder#Builder(Context, RenderersFactory,
* MediaSourceFactory, TrackSelector, LoadControl, BandwidthMeter, AnalyticsCollector)}
* MediaSource.Factory, TrackSelector, LoadControl, BandwidthMeter, AnalyticsCollector)}
* instead.
*/
@Deprecated
......@@ -156,7 +155,7 @@ public class SimpleExoPlayer extends BasePlayer
Context context,
RenderersFactory renderersFactory,
TrackSelector trackSelector,
MediaSourceFactory mediaSourceFactory,
MediaSource.Factory mediaSourceFactory,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
AnalyticsCollector analyticsCollector) {
......@@ -189,10 +188,10 @@ public class SimpleExoPlayer extends BasePlayer
}
/**
* @deprecated Use {@link ExoPlayer.Builder#setMediaSourceFactory(MediaSourceFactory)} instead.
* @deprecated Use {@link ExoPlayer.Builder#setMediaSourceFactory(MediaSource.Factory)} instead.
*/
@Deprecated
public Builder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
public Builder setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
wrappedBuilder.setMediaSourceFactory(mediaSourceFactory);
return this;
}
......@@ -411,7 +410,7 @@ public class SimpleExoPlayer extends BasePlayer
Context context,
RenderersFactory renderersFactory,
TrackSelector trackSelector,
MediaSourceFactory mediaSourceFactory,
MediaSource.Factory mediaSourceFactory,
LoadControl loadControl,
BandwidthMeter bandwidthMeter,
AnalyticsCollector analyticsCollector,
......
......@@ -59,7 +59,7 @@ import java.util.Set;
import org.checkerframework.checker.nullness.compatqual.NullableType;
/**
* The default {@link MediaSourceFactory} implementation.
* The default {@link MediaSource.Factory} implementation.
*
* <p>This implementation delegates calls to {@link #createMediaSource(MediaItem)} to the following
* factories:
......@@ -93,6 +93,7 @@ import org.checkerframework.checker.nullness.compatqual.NullableType;
* configuration}, {@link #setAdsLoaderProvider} and {@link #setAdViewProvider} need to be called to
* configure the factory with the required providers.
*/
@SuppressWarnings("deprecation") // Implement deprecated type for backwards compatibility.
public final class DefaultMediaSourceFactory implements MediaSourceFactory {
/** @deprecated Use {@link AdsLoader.Provider} instead. */
......@@ -105,7 +106,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
private final DataSource.Factory dataSourceFactory;
private final DelegateFactoryLoader delegateFactoryLoader;
@Nullable private final MediaSourceFactory serverSideDaiMediaSourceFactory;
@Nullable private final MediaSource.Factory serverSideDaiMediaSourceFactory;
@Nullable private AdsLoader.Provider adsLoaderProvider;
@Nullable private AdViewProvider adViewProvider;
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
......@@ -161,14 +162,14 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
* for requesting media data.
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
* its container.
* @param serverSideDaiMediaSourceFactory A {@link MediaSourceFactory} for creating server side
* @param serverSideDaiMediaSourceFactory A {@link MediaSource.Factory} for creating server side
* inserted ad media sources.
*/
@UnstableApi
public DefaultMediaSourceFactory(
DataSource.Factory dataSourceFactory,
ExtractorsFactory extractorsFactory,
@Nullable MediaSourceFactory serverSideDaiMediaSourceFactory) {
@Nullable MediaSource.Factory serverSideDaiMediaSourceFactory) {
this.dataSourceFactory = dataSourceFactory;
// Temporary until factory registration is agreed upon.
this.serverSideDaiMediaSourceFactory = serverSideDaiMediaSourceFactory;
......@@ -324,7 +325,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
Util.inferContentTypeForUriAndMimeType(
mediaItem.localConfiguration.uri, mediaItem.localConfiguration.mimeType);
@Nullable
MediaSourceFactory mediaSourceFactory = delegateFactoryLoader.getMediaSourceFactory(type);
MediaSource.Factory mediaSourceFactory = delegateFactoryLoader.getMediaSourceFactory(type);
checkStateNotNull(
mediaSourceFactory, "No suitable media source factory found for content type: " + type);
......@@ -450,10 +451,10 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
private static final class DelegateFactoryLoader {
private final DataSource.Factory dataSourceFactory;
private final ExtractorsFactory extractorsFactory;
private final Map<Integer, @NullableType Supplier<MediaSourceFactory>>
private final Map<Integer, @NullableType Supplier<MediaSource.Factory>>
mediaSourceFactorySuppliers;
private final Set<Integer> supportedTypes;
private final Map<Integer, MediaSourceFactory> mediaSourceFactories;
private final Map<Integer, MediaSource.Factory> mediaSourceFactories;
@Nullable private DrmSessionManagerProvider drmSessionManagerProvider;
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
......@@ -475,13 +476,13 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
@SuppressWarnings("deprecation") // Forwarding to deprecated methods.
@Nullable
public MediaSourceFactory getMediaSourceFactory(@C.ContentType int contentType) {
@Nullable MediaSourceFactory mediaSourceFactory = mediaSourceFactories.get(contentType);
public MediaSource.Factory getMediaSourceFactory(@C.ContentType int contentType) {
@Nullable MediaSource.Factory mediaSourceFactory = mediaSourceFactories.get(contentType);
if (mediaSourceFactory != null) {
return mediaSourceFactory;
}
@Nullable
Supplier<MediaSourceFactory> mediaSourceFactorySupplier = maybeLoadSupplier(contentType);
Supplier<MediaSource.Factory> mediaSourceFactorySupplier = maybeLoadSupplier(contentType);
if (mediaSourceFactorySupplier == null) {
return null;
}
......@@ -500,7 +501,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
public void setDrmSessionManagerProvider(
@Nullable DrmSessionManagerProvider drmSessionManagerProvider) {
this.drmSessionManagerProvider = drmSessionManagerProvider;
for (MediaSourceFactory mediaSourceFactory : mediaSourceFactories.values()) {
for (MediaSource.Factory mediaSourceFactory : mediaSourceFactories.values()) {
mediaSourceFactory.setDrmSessionManagerProvider(drmSessionManagerProvider);
}
}
......@@ -508,7 +509,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
public void setLoadErrorHandlingPolicy(
@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
for (MediaSourceFactory mediaSourceFactory : mediaSourceFactories.values()) {
for (MediaSource.Factory mediaSourceFactory : mediaSourceFactories.values()) {
mediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy);
}
}
......@@ -522,37 +523,37 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
}
@Nullable
private Supplier<MediaSourceFactory> maybeLoadSupplier(@C.ContentType int contentType) {
private Supplier<MediaSource.Factory> maybeLoadSupplier(@C.ContentType int contentType) {
if (mediaSourceFactorySuppliers.containsKey(contentType)) {
return mediaSourceFactorySuppliers.get(contentType);
}
@Nullable Supplier<MediaSourceFactory> mediaSourceFactorySupplier = null;
@Nullable Supplier<MediaSource.Factory> mediaSourceFactorySupplier = null;
try {
Class<? extends MediaSourceFactory> clazz;
Class<? extends MediaSource.Factory> clazz;
switch (contentType) {
case C.TYPE_DASH:
clazz =
Class.forName("androidx.media3.exoplayer.dash.DashMediaSource$Factory")
.asSubclass(MediaSourceFactory.class);
.asSubclass(MediaSource.Factory.class);
mediaSourceFactorySupplier = () -> newInstance(clazz, dataSourceFactory);
break;
case C.TYPE_SS:
clazz =
Class.forName("androidx.media3.exoplayer.smoothstreaming.SsMediaSource$Factory")
.asSubclass(MediaSourceFactory.class);
.asSubclass(MediaSource.Factory.class);
mediaSourceFactorySupplier = () -> newInstance(clazz, dataSourceFactory);
break;
case C.TYPE_HLS:
clazz =
Class.forName("androidx.media3.exoplayer.hls.HlsMediaSource$Factory")
.asSubclass(MediaSourceFactory.class);
.asSubclass(MediaSource.Factory.class);
mediaSourceFactorySupplier = () -> newInstance(clazz, dataSourceFactory);
break;
case C.TYPE_RTSP:
clazz =
Class.forName("androidx.media3.exoplayer.rtsp.RtspMediaSource$Factory")
.asSubclass(MediaSourceFactory.class);
.asSubclass(MediaSource.Factory.class);
mediaSourceFactorySupplier = () -> newInstance(clazz);
break;
case C.TYPE_OTHER:
......@@ -614,8 +615,8 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
public void release() {}
}
private static MediaSourceFactory newInstance(
Class<? extends MediaSourceFactory> clazz, DataSource.Factory dataSourceFactory) {
private static MediaSource.Factory newInstance(
Class<? extends MediaSource.Factory> clazz, DataSource.Factory dataSourceFactory) {
try {
return clazz.getConstructor(DataSource.Factory.class).newInstance(dataSourceFactory);
} catch (Exception e) {
......@@ -623,7 +624,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
}
}
private static MediaSourceFactory newInstance(Class<? extends MediaSourceFactory> clazz) {
private static MediaSource.Factory newInstance(Class<? extends MediaSource.Factory> clazz) {
try {
return clazz.getConstructor().newInstance();
} catch (Exception e) {
......
......@@ -17,14 +17,20 @@ package androidx.media3.exoplayer.source;
import android.os.Handler;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.MediaItem;
import androidx.media3.common.Timeline;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.datasource.TransferListener;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.drm.DefaultDrmSessionManagerProvider;
import androidx.media3.exoplayer.drm.DrmSessionEventListener;
import androidx.media3.exoplayer.drm.DrmSessionManager;
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider;
import androidx.media3.exoplayer.upstream.Allocator;
import androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy;
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
import java.io.IOException;
/**
......@@ -46,10 +52,61 @@ import java.io.IOException;
* ExoPlayer} Javadoc. They should not be called directly from application code. Instances can be
* re-used, but only for one {@link ExoPlayer} instance simultaneously.
*/
@UnstableApi
public interface MediaSource {
/** Factory for creating {@link MediaSource MediaSources} from {@link MediaItem MediaItems}. */
interface Factory {
/**
* An instance that throws {@link UnsupportedOperationException} from {@link #createMediaSource}
* and {@link #getSupportedTypes()}.
*/
@UnstableApi
@SuppressWarnings("deprecation")
Factory UNSUPPORTED = MediaSourceFactory.UNSUPPORTED;
/**
* Sets the {@link DrmSessionManagerProvider} used to obtain a {@link DrmSessionManager} for a
* {@link MediaItem}.
*
* <p>If not set, {@link DefaultDrmSessionManagerProvider} is used.
*
* @return This factory, for convenience.
*/
@UnstableApi
Factory setDrmSessionManagerProvider(
@Nullable DrmSessionManagerProvider drmSessionManagerProvider);
/**
* Sets an optional {@link LoadErrorHandlingPolicy}.
*
* @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}, or {@code null} to use the
* {@link DefaultLoadErrorHandlingPolicy}.
* @return This factory, for convenience.
*/
@UnstableApi
Factory setLoadErrorHandlingPolicy(@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy);
/**
* Returns the {@link C.ContentType content types} supported by media sources created by this
* factory.
*/
@UnstableApi
@C.ContentType
int[] getSupportedTypes();
/**
* Creates a new {@link MediaSource} with the specified {@link MediaItem}.
*
* @param mediaItem The media item to play.
* @return The new {@link MediaSource media source}.
*/
@UnstableApi
MediaSource createMediaSource(MediaItem mediaItem);
}
/** A caller of media sources, which will be notified of source events. */
@UnstableApi
interface MediaSourceCaller {
/**
......@@ -69,6 +126,7 @@ public interface MediaSource {
*
* <p>Extends for backward-compatibility {@link androidx.media3.common.MediaPeriodId}.
*/
@UnstableApi
final class MediaPeriodId extends androidx.media3.common.MediaPeriodId {
/** See {@link androidx.media3.common.MediaPeriodId#MediaPeriodId(Object)}. */
......@@ -117,6 +175,7 @@ public interface MediaSource {
* @param handler A handler on the which listener events will be posted.
* @param eventListener The listener to be added.
*/
@UnstableApi
void addEventListener(Handler handler, MediaSourceEventListener eventListener);
/**
......@@ -125,6 +184,7 @@ public interface MediaSource {
*
* @param eventListener The listener to be removed.
*/
@UnstableApi
void removeEventListener(MediaSourceEventListener eventListener);
/**
......@@ -134,6 +194,7 @@ public interface MediaSource {
* @param handler A handler on the which listener events will be posted.
* @param eventListener The listener to be added.
*/
@UnstableApi
void addDrmEventListener(Handler handler, DrmSessionEventListener eventListener);
/**
......@@ -142,6 +203,7 @@ public interface MediaSource {
*
* @param eventListener The listener to be removed.
*/
@UnstableApi
void removeDrmEventListener(DrmSessionEventListener eventListener);
/**
......@@ -155,6 +217,7 @@ public interface MediaSource {
* <p>Any media source which has multiple windows should typically provide such an initial
* timeline to make sure the player reports the correct number of windows immediately.
*/
@UnstableApi
@Nullable
default Timeline getInitialTimeline() {
return null;
......@@ -167,17 +230,20 @@ public interface MediaSource {
*
* @return true if the source has exactly one window.
*/
@UnstableApi
default boolean isSingleWindow() {
return true;
}
/** Returns the {@link MediaItem} whose media is provided by the source. */
@UnstableApi
MediaItem getMediaItem();
/**
* @deprecated Implement {@link #prepareSource(MediaSourceCaller, TransferListener, PlayerId)}
* instead.
*/
@UnstableApi
@Deprecated
default void prepareSource(
MediaSourceCaller caller, @Nullable TransferListener mediaTransferListener) {
......@@ -203,6 +269,7 @@ public interface MediaSource {
* and other data.
* @param playerId The {@link PlayerId} of the player using this media source.
*/
@UnstableApi
void prepareSource(
MediaSourceCaller caller,
@Nullable TransferListener mediaTransferListener,
......@@ -216,6 +283,7 @@ public interface MediaSource {
* <p>Must only be called after {@link #prepareSource(MediaSourceCaller, TransferListener,
* PlayerId)}.
*/
@UnstableApi
void maybeThrowSourceInfoRefreshError() throws IOException;
/**
......@@ -228,6 +296,7 @@ public interface MediaSource {
*
* @param caller The {@link MediaSourceCaller} enabling the source.
*/
@UnstableApi
void enable(MediaSourceCaller caller);
/**
......@@ -242,6 +311,7 @@ public interface MediaSource {
* @param startPositionUs The expected start position, in microseconds.
* @return A new {@link MediaPeriod}.
*/
@UnstableApi
MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs);
/**
......@@ -251,6 +321,7 @@ public interface MediaSource {
*
* @param mediaPeriod The period to release.
*/
@UnstableApi
void releasePeriod(MediaPeriod mediaPeriod);
/**
......@@ -265,6 +336,7 @@ public interface MediaSource {
*
* @param caller The {@link MediaSourceCaller} disabling the source.
*/
@UnstableApi
void disable(MediaSourceCaller caller);
/**
......@@ -277,5 +349,6 @@ public interface MediaSource {
*
* @param caller The {@link MediaSourceCaller} to be unregistered.
*/
@UnstableApi
void releaseSource(MediaSourceCaller caller);
}
......@@ -19,14 +19,13 @@ import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.MediaItem;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.drm.DefaultDrmSessionManagerProvider;
import androidx.media3.exoplayer.drm.DrmSessionManager;
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider;
import androidx.media3.exoplayer.upstream.DefaultLoadErrorHandlingPolicy;
import androidx.media3.exoplayer.upstream.LoadErrorHandlingPolicy;
/** Factory for creating {@link MediaSource MediaSources} from {@link MediaItem MediaItems}. */
public interface MediaSourceFactory {
/** @deprecated Use {@link MediaSource.Factory}. */
@UnstableApi
@Deprecated
public interface MediaSourceFactory extends MediaSource.Factory {
/**
* An instance that throws {@link UnsupportedOperationException} from {@link #createMediaSource}
......@@ -58,44 +57,4 @@ public interface MediaSourceFactory {
throw new UnsupportedOperationException();
}
};
/**
* Sets the {@link DrmSessionManagerProvider} used to obtain a {@link DrmSessionManager} for a
* {@link MediaItem}.
*
* <p>If not set, {@link DefaultDrmSessionManagerProvider} is used.
*
* @return This factory, for convenience.
*/
@UnstableApi
MediaSourceFactory setDrmSessionManagerProvider(
@Nullable DrmSessionManagerProvider drmSessionManagerProvider);
/**
* Sets an optional {@link LoadErrorHandlingPolicy}.
*
* @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}, or {@code null} to use the
* {@link DefaultLoadErrorHandlingPolicy}.
* @return This factory, for convenience.
*/
@UnstableApi
MediaSourceFactory setLoadErrorHandlingPolicy(
@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy);
/**
* Returns the {@link C.ContentType content types} supported by media sources created by this
* factory.
*/
@UnstableApi
@C.ContentType
int[] getSupportedTypes();
/**
* Creates a new {@link MediaSource} with the specified {@link MediaItem}.
*
* @param mediaItem The media item to play.
* @return The new {@link MediaSource media source}.
*/
@UnstableApi
MediaSource createMediaSource(MediaItem mediaItem);
}
......@@ -52,6 +52,7 @@ public final class ProgressiveMediaSource extends BaseMediaSource
implements ProgressiveMediaPeriod.Listener {
/** Factory for {@link ProgressiveMediaSource}s. */
@SuppressWarnings("deprecation") // Implement deprecated type for backwards compatibility.
public static final class Factory implements MediaSourceFactory {
private final DataSource.Factory dataSourceFactory;
......
......@@ -42,7 +42,6 @@ import androidx.media3.exoplayer.source.MediaPeriod;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId;
import androidx.media3.exoplayer.source.MediaSourceEventListener;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.upstream.Allocator;
import java.io.IOException;
import java.lang.annotation.Documented;
......@@ -130,7 +129,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
new MediaPeriodId(/* periodUid= */ new Object());
private final MediaSource contentMediaSource;
private final MediaSourceFactory adMediaSourceFactory;
private final MediaSource.Factory adMediaSourceFactory;
private final AdsLoader adsLoader;
private final AdViewProvider adViewProvider;
private final DataSpec adTagDataSpec;
......@@ -162,7 +161,7 @@ public final class AdsMediaSource extends CompositeMediaSource<MediaPeriodId> {
MediaSource contentMediaSource,
DataSpec adTagDataSpec,
Object adsId,
MediaSourceFactory adMediaSourceFactory,
MediaSource.Factory adMediaSourceFactory,
AdsLoader adsLoader,
AdViewProvider adViewProvider) {
this.contentMediaSource = contentMediaSource;
......
......@@ -25,7 +25,7 @@ import androidx.media3.common.MimeTypes;
import androidx.media3.common.Player;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.test.utils.CapturingRenderersFactory;
import androidx.media3.test.utils.DumpFileAsserts;
import androidx.media3.test.utils.FakeClock;
......@@ -58,7 +58,7 @@ public class WebvttPlaybackTest {
Context applicationContext = ApplicationProvider.getApplicationContext();
CapturingRenderersFactory capturingRenderersFactory =
new CapturingRenderersFactory(applicationContext);
MediaSourceFactory mediaSourceFactory =
MediaSource.Factory mediaSourceFactory =
new DefaultMediaSourceFactory(applicationContext)
.experimentalUseProgressiveMediaSourceForSubtitles(true);
ExoPlayer player =
......
......@@ -33,9 +33,9 @@ import androidx.media3.common.Timeline;
import androidx.media3.datasource.DataSpec;
import androidx.media3.exoplayer.analytics.PlayerId;
import androidx.media3.exoplayer.source.MediaPeriod;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId;
import androidx.media3.exoplayer.source.MediaSource.MediaSourceCaller;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.SinglePeriodTimeline;
import androidx.media3.exoplayer.source.ads.AdsLoader.EventListener;
import androidx.media3.exoplayer.upstream.Allocator;
......@@ -102,7 +102,7 @@ public final class AdsMediaSourceTest {
// later.
contentMediaSource = new FakeMediaSource(/* timeline= */ null);
prerollAdMediaSource = new FakeMediaSource(/* timeline= */ null);
MediaSourceFactory adMediaSourceFactory = mock(MediaSourceFactory.class);
MediaSource.Factory adMediaSourceFactory = mock(MediaSource.Factory.class);
when(adMediaSourceFactory.createMediaSource(any(MediaItem.class)))
.thenReturn(prerollAdMediaSource);
......
......@@ -99,6 +99,7 @@ public final class DashMediaSource extends BaseMediaSource {
}
/** Factory for {@link DashMediaSource}s. */
@SuppressWarnings("deprecation") // Implement deprecated type for backwards compatibility.
public static final class Factory implements MediaSourceFactory {
private final DashChunkSource.Factory chunkSourceFactory;
......
......@@ -94,6 +94,7 @@ public final class HlsMediaSource extends BaseMediaSource
public static final int METADATA_TYPE_EMSG = 3;
/** Factory for {@link HlsMediaSource}s. */
@SuppressWarnings("deprecation") // Implement deprecated type for backwards compatibility.
public static final class Factory implements MediaSourceFactory {
private final HlsDataSourceFactory hlsDataSourceFactory;
......
......@@ -38,7 +38,7 @@ import androidx.media3.common.Timeline;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.datasource.DataSpec;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.ads.AdsLoader;
import androidx.media3.exoplayer.source.ads.AdsMediaSource;
import com.google.ads.interactivemedia.v3.api.AdDisplayContainer;
......@@ -229,7 +229,7 @@ public final class ImaAdsLoader implements AdsLoader {
/**
* Sets the MIME types to prioritize for linear ad media. If not specified, MIME types supported
* by the {@link MediaSourceFactory adMediaSourceFactory} used to construct the {@link
* by the {@link MediaSource.Factory adMediaSourceFactory} used to construct the {@link
* AdsMediaSource} will be used.
*
* @param adMediaMimeTypes The MIME types to prioritize for linear ad media. May contain {@link
......
......@@ -63,6 +63,7 @@ public final class RtspMediaSource extends BaseMediaSource {
* <li>{@link #setLoadErrorHandlingPolicy(LoadErrorHandlingPolicy)}
* </ul>
*/
@SuppressWarnings("deprecation") // Implement deprecated type for backwards compatibility.
public static final class Factory implements MediaSourceFactory {
private long timeoutMs;
......
......@@ -78,6 +78,7 @@ public final class SsMediaSource extends BaseMediaSource
}
/** Factory for {@link SsMediaSource}. */
@SuppressWarnings("deprecation") // Implement deprecated type for backwards compatibility.
public static final class Factory implements MediaSourceFactory {
private final SsChunkSource.Factory chunkSourceFactory;
......
......@@ -29,6 +29,8 @@ import androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition;
/** Fake {@link MediaSourceFactory} that creates a {@link FakeMediaSource}. */
@UnstableApi
// Implement and return deprecated type for backwards compatibility.
@SuppressWarnings("deprecation")
public final class FakeMediaSourceFactory implements MediaSourceFactory {
/** The window UID used by media sources that are created by the factory. */
......
......@@ -30,7 +30,7 @@ import androidx.media3.exoplayer.Renderer;
import androidx.media3.exoplayer.RenderersFactory;
import androidx.media3.exoplayer.SimpleExoPlayer;
import androidx.media3.exoplayer.analytics.AnalyticsCollector;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.upstream.BandwidthMeter;
import androidx.media3.exoplayer.upstream.DefaultBandwidthMeter;
......@@ -48,7 +48,7 @@ public class TestExoPlayerBuilder {
private BandwidthMeter bandwidthMeter;
@Nullable private Renderer[] renderers;
@Nullable private RenderersFactory renderersFactory;
@Nullable private MediaSourceFactory mediaSourceFactory;
@Nullable private MediaSource.Factory mediaSourceFactory;
private boolean useLazyPreparation;
private @MonotonicNonNull Looper looper;
private long seekBackIncrementMs;
......@@ -224,21 +224,21 @@ public class TestExoPlayerBuilder {
}
/**
* Returns the {@link MediaSourceFactory} that will be used by the player, or null if no {@link
* MediaSourceFactory} has been set yet and no default is available.
* Returns the {@link MediaSource.Factory} that will be used by the player, or null if no {@link
* MediaSource.Factory} has been set yet and no default is available.
*/
@Nullable
public MediaSourceFactory getMediaSourceFactory() {
public MediaSource.Factory getMediaSourceFactory() {
return mediaSourceFactory;
}
/**
* Sets the {@link MediaSourceFactory} to be used by the player.
* Sets the {@link MediaSource.Factory} to be used by the player.
*
* @param mediaSourceFactory The {@link MediaSourceFactory} to be used by the player.
* @param mediaSourceFactory The {@link MediaSource.Factory} to be used by the player.
* @return This builder.
*/
public TestExoPlayerBuilder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
public TestExoPlayerBuilder setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
this.mediaSourceFactory = mediaSourceFactory;
return this;
}
......
......@@ -22,7 +22,7 @@ import androidx.media3.common.C;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.extractor.mp4.Mp4Extractor;
/** A media transformation request. */
......@@ -94,8 +94,8 @@ public final class TransformationRequest {
* <li>The recording frame rate of the video is 120 or 240 fps.
* </ul>
*
* <p>If specifying a {@link MediaSourceFactory} using {@link
* Transformer.Builder#setMediaSourceFactory(MediaSourceFactory)}, make sure that {@link
* <p>If specifying a {@link MediaSource.Factory} using {@link
* Transformer.Builder#setMediaSourceFactory(MediaSource.Factory)}, make sure that {@link
* Mp4Extractor#FLAG_READ_SEF_DATA} is set on the {@link Mp4Extractor} used. Otherwise, the slow
* motion metadata will be ignored and the input won't be flattened.
*
......
......@@ -53,7 +53,6 @@ import androidx.media3.exoplayer.audio.AudioRendererEventListener;
import androidx.media3.exoplayer.metadata.MetadataOutput;
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
import androidx.media3.exoplayer.source.MediaSource;
import androidx.media3.exoplayer.source.MediaSourceFactory;
import androidx.media3.exoplayer.text.TextOutput;
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector;
import androidx.media3.exoplayer.video.VideoRendererEventListener;
......@@ -95,7 +94,7 @@ public final class Transformer {
private @MonotonicNonNull Context context;
// Optional fields.
private @MonotonicNonNull MediaSourceFactory mediaSourceFactory;
private MediaSource.@MonotonicNonNull Factory mediaSourceFactory;
private Muxer.Factory muxerFactory;
private boolean removeAudio;
private boolean removeVideo;
......@@ -173,14 +172,14 @@ public final class Transformer {
}
/**
* Sets the {@link MediaSourceFactory} to be used to retrieve the inputs to transform. The
* Sets the {@link MediaSource.Factory} to be used to retrieve the inputs to transform. The
* default value is a {@link DefaultMediaSourceFactory} built with the context provided in
* {@link #Builder(Context) the constructor}.
*
* @param mediaSourceFactory A {@link MediaSourceFactory}.
* @param mediaSourceFactory A {@link MediaSource.Factory}.
* @return This builder.
*/
public Builder setMediaSourceFactory(MediaSourceFactory mediaSourceFactory) {
public Builder setMediaSourceFactory(MediaSource.Factory mediaSourceFactory) {
this.mediaSourceFactory = mediaSourceFactory;
return this;
}
......@@ -473,7 +472,7 @@ public final class Transformer {
public static final int PROGRESS_STATE_NO_TRANSFORMATION = 4;
private final Context context;
private final MediaSourceFactory mediaSourceFactory;
private final MediaSource.Factory mediaSourceFactory;
private final Muxer.Factory muxerFactory;
private final boolean removeAudio;
private final boolean removeVideo;
......@@ -492,7 +491,7 @@ public final class Transformer {
private Transformer(
Context context,
MediaSourceFactory mediaSourceFactory,
MediaSource.Factory mediaSourceFactory,
Muxer.Factory muxerFactory,
boolean removeAudio,
boolean removeVideo,
......
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