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
This commit is contained in:
ibaker 2021-12-22 16:36:42 +00:00 committed by tonihei
parent b63c0593b5
commit 34a1f884dc
21 changed files with 169 additions and 133 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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();

View File

@ -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,

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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 =

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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. */

View File

@ -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;
}

View File

@ -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.
*

View File

@ -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,