mirror of
https://github.com/androidx/media.git
synced 2025-05-07 23:50:44 +08:00
Support ExtractorFactory in DefaultMediaSourceFactory.
This allows to customize extractor flags more easily when setting up the player. In addition, we need to provide a way to pass in the ExtractorFactory through the constructor chain starting in SimpleExoPlayer so that removing the DefaultExtractorsFactory is possible for R8. PiperOrigin-RevId: 330472935
This commit is contained in:
parent
3110587fbe
commit
bfe17aee3e
@ -38,6 +38,8 @@ import com.google.android.exoplayer2.audio.AuxEffectInfo;
|
|||||||
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
||||||
import com.google.android.exoplayer2.device.DeviceInfo;
|
import com.google.android.exoplayer2.device.DeviceInfo;
|
||||||
import com.google.android.exoplayer2.device.DeviceListener;
|
import com.google.android.exoplayer2.device.DeviceListener;
|
||||||
|
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||||
|
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||||
import com.google.android.exoplayer2.metadata.Metadata;
|
import com.google.android.exoplayer2.metadata.Metadata;
|
||||||
import com.google.android.exoplayer2.metadata.MetadataOutput;
|
import com.google.android.exoplayer2.metadata.MetadataOutput;
|
||||||
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
|
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
|
||||||
@ -52,6 +54,7 @@ import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
|||||||
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
import com.google.android.exoplayer2.trackselection.TrackSelector;
|
||||||
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
import com.google.android.exoplayer2.upstream.BandwidthMeter;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
||||||
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Clock;
|
import com.google.android.exoplayer2.util.Clock;
|
||||||
import com.google.android.exoplayer2.util.Log;
|
import com.google.android.exoplayer2.util.Log;
|
||||||
@ -115,9 +118,11 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
/**
|
/**
|
||||||
* Creates a builder.
|
* Creates a builder.
|
||||||
*
|
*
|
||||||
* <p>Use {@link #Builder(Context, RenderersFactory)} instead, if you intend to provide a custom
|
* <p>Use {@link #Builder(Context, RenderersFactory)} or {@link #Builder(Context,
|
||||||
* {@link RenderersFactory}. This is to ensure that ProGuard or R8 can remove ExoPlayer's {@link
|
* RenderersFactory, ExtractorsFactory)} instead, if you intend to provide a custom {@link
|
||||||
* DefaultRenderersFactory} from the APK.
|
* RenderersFactory} or a custom {@link ExtractorsFactory}. This is to ensure that ProGuard or
|
||||||
|
* R8 can remove ExoPlayer's {@link DefaultRenderersFactory} and {@link
|
||||||
|
* DefaultExtractorsFactory} from the APK.
|
||||||
*
|
*
|
||||||
* <p>The builder uses the following default values:
|
* <p>The builder uses the following default values:
|
||||||
*
|
*
|
||||||
@ -146,7 +151,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
* @param context A {@link Context}.
|
* @param context A {@link Context}.
|
||||||
*/
|
*/
|
||||||
public Builder(Context context) {
|
public Builder(Context context) {
|
||||||
this(context, new DefaultRenderersFactory(context));
|
this(context, new DefaultRenderersFactory(context), new DefaultExtractorsFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,11 +164,30 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
* player.
|
* player.
|
||||||
*/
|
*/
|
||||||
public Builder(Context context, RenderersFactory renderersFactory) {
|
public Builder(Context context, RenderersFactory renderersFactory) {
|
||||||
|
this(context, renderersFactory, new DefaultExtractorsFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a builder with a custom {@link RenderersFactory} and {@link ExtractorsFactory}.
|
||||||
|
*
|
||||||
|
* <p>See {@link #Builder(Context)} for a list of default values.
|
||||||
|
*
|
||||||
|
* @param context A {@link Context}.
|
||||||
|
* @param renderersFactory A factory for creating {@link Renderer Renderers} to be used by the
|
||||||
|
* player.
|
||||||
|
* @param extractorsFactory An {@link ExtractorsFactory} used to extract progressive media from
|
||||||
|
* its container.
|
||||||
|
*/
|
||||||
|
public Builder(
|
||||||
|
Context context, RenderersFactory renderersFactory, ExtractorsFactory extractorsFactory) {
|
||||||
this(
|
this(
|
||||||
context,
|
context,
|
||||||
renderersFactory,
|
renderersFactory,
|
||||||
new DefaultTrackSelector(context),
|
new DefaultTrackSelector(context),
|
||||||
new DefaultMediaSourceFactory(context),
|
new DefaultMediaSourceFactory(
|
||||||
|
new DefaultDataSourceFactory(
|
||||||
|
context, Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY)),
|
||||||
|
extractorsFactory),
|
||||||
new DefaultLoadControl(),
|
new DefaultLoadControl(),
|
||||||
DefaultBandwidthMeter.getSingletonInstance(context),
|
DefaultBandwidthMeter.getSingletonInstance(context),
|
||||||
new AnalyticsCollector(Clock.DEFAULT));
|
new AnalyticsCollector(Clock.DEFAULT));
|
||||||
@ -546,7 +570,7 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
Clock clock,
|
Clock clock,
|
||||||
Looper applicationLooper) {
|
Looper applicationLooper) {
|
||||||
this(
|
this(
|
||||||
new Builder(context, renderersFactory)
|
new Builder(context, renderersFactory, new DefaultExtractorsFactory())
|
||||||
.setTrackSelector(trackSelector)
|
.setTrackSelector(trackSelector)
|
||||||
.setMediaSourceFactory(mediaSourceFactory)
|
.setMediaSourceFactory(mediaSourceFactory)
|
||||||
.setLoadControl(loadControl)
|
.setLoadControl(loadControl)
|
||||||
|
@ -34,6 +34,7 @@ import com.google.android.exoplayer2.RenderersFactory;
|
|||||||
import com.google.android.exoplayer2.Timeline;
|
import com.google.android.exoplayer2.Timeline;
|
||||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
|
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||||
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
|
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
|
||||||
import com.google.android.exoplayer2.source.MediaPeriod;
|
import com.google.android.exoplayer2.source.MediaPeriod;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
@ -889,7 +890,7 @@ public final class DownloadHelper {
|
|||||||
MediaItem mediaItem,
|
MediaItem mediaItem,
|
||||||
DataSource.Factory dataSourceFactory,
|
DataSource.Factory dataSourceFactory,
|
||||||
@Nullable DrmSessionManager drmSessionManager) {
|
@Nullable DrmSessionManager drmSessionManager) {
|
||||||
return new DefaultMediaSourceFactory(dataSourceFactory)
|
return new DefaultMediaSourceFactory(dataSourceFactory, ExtractorsFactory.EMPTY)
|
||||||
.setDrmSessionManager(drmSessionManager)
|
.setDrmSessionManager(drmSessionManager)
|
||||||
.createMediaSource(mediaItem);
|
.createMediaSource(mediaItem);
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,14 @@ import com.google.android.exoplayer2.C;
|
|||||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||||
import com.google.android.exoplayer2.MediaItem;
|
import com.google.android.exoplayer2.MediaItem;
|
||||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||||
|
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
|
||||||
|
import com.google.android.exoplayer2.extractor.ExtractorsFactory;
|
||||||
import com.google.android.exoplayer2.offline.StreamKey;
|
import com.google.android.exoplayer2.offline.StreamKey;
|
||||||
import com.google.android.exoplayer2.source.ads.AdsLoader;
|
import com.google.android.exoplayer2.source.ads.AdsLoader;
|
||||||
import com.google.android.exoplayer2.source.ads.AdsLoader.AdViewProvider;
|
import com.google.android.exoplayer2.source.ads.AdsLoader.AdViewProvider;
|
||||||
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
|
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
|
|
||||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
@ -64,9 +65,10 @@ import java.util.List;
|
|||||||
* <li>{@link ProgressiveMediaSource.Factory} serves as a fallback if the item's {@link
|
* <li>{@link ProgressiveMediaSource.Factory} serves as a fallback if the item's {@link
|
||||||
* MediaItem.PlaybackProperties#uri uri} doesn't match one of the above. It tries to infer the
|
* MediaItem.PlaybackProperties#uri uri} doesn't match one of the above. It tries to infer the
|
||||||
* required extractor by using the {@link
|
* required extractor by using the {@link
|
||||||
* com.google.android.exoplayer2.extractor.DefaultExtractorsFactory}. An {@link
|
* com.google.android.exoplayer2.extractor.DefaultExtractorsFactory} or the {@link
|
||||||
* UnrecognizedInputFormatException} is thrown if none of the available extractors can read
|
* ExtractorsFactory} provided in {@link #DefaultMediaSourceFactory(DataSource.Factory,
|
||||||
* the stream.
|
* ExtractorsFactory)}. An {@link UnrecognizedInputFormatException} is thrown if none of the
|
||||||
|
* available extractors can read the stream.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <h3>Ad support for media items with ad tag URIs</h3>
|
* <h3>Ad support for media items with ad tag URIs</h3>
|
||||||
@ -105,6 +107,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
@Nullable private AdViewProvider adViewProvider;
|
@Nullable private AdViewProvider adViewProvider;
|
||||||
@Nullable private DrmSessionManager drmSessionManager;
|
@Nullable private DrmSessionManager drmSessionManager;
|
||||||
@Nullable private List<StreamKey> streamKeys;
|
@Nullable private List<StreamKey> streamKeys;
|
||||||
|
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
@ -124,9 +127,22 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
* for requesting media data.
|
* for requesting media data.
|
||||||
*/
|
*/
|
||||||
public DefaultMediaSourceFactory(DataSource.Factory dataSourceFactory) {
|
public DefaultMediaSourceFactory(DataSource.Factory dataSourceFactory) {
|
||||||
|
this(dataSourceFactory, new DefaultExtractorsFactory());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance.
|
||||||
|
*
|
||||||
|
* @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
|
||||||
|
* its container.
|
||||||
|
*/
|
||||||
|
public DefaultMediaSourceFactory(
|
||||||
|
DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) {
|
||||||
this.dataSourceFactory = dataSourceFactory;
|
this.dataSourceFactory = dataSourceFactory;
|
||||||
mediaSourceDrmHelper = new MediaSourceDrmHelper();
|
mediaSourceDrmHelper = new MediaSourceDrmHelper();
|
||||||
mediaSourceFactories = loadDelegates(dataSourceFactory);
|
mediaSourceFactories = loadDelegates(dataSourceFactory, extractorsFactory);
|
||||||
supportedTypes = new int[mediaSourceFactories.size()];
|
supportedTypes = new int[mediaSourceFactories.size()];
|
||||||
for (int i = 0; i < mediaSourceFactories.size(); i++) {
|
for (int i = 0; i < mediaSourceFactories.size(); i++) {
|
||||||
supportedTypes[i] = mediaSourceFactories.keyAt(i);
|
supportedTypes[i] = mediaSourceFactories.keyAt(i);
|
||||||
@ -180,13 +196,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
@Override
|
@Override
|
||||||
public DefaultMediaSourceFactory setLoadErrorHandlingPolicy(
|
public DefaultMediaSourceFactory setLoadErrorHandlingPolicy(
|
||||||
@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
|
@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
|
||||||
LoadErrorHandlingPolicy newLoadErrorHandlingPolicy =
|
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
|
||||||
loadErrorHandlingPolicy != null
|
|
||||||
? loadErrorHandlingPolicy
|
|
||||||
: new DefaultLoadErrorHandlingPolicy();
|
|
||||||
for (int i = 0; i < mediaSourceFactories.size(); i++) {
|
|
||||||
mediaSourceFactories.valueAt(i).setLoadErrorHandlingPolicy(newLoadErrorHandlingPolicy);
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +234,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
!mediaItem.playbackProperties.streamKeys.isEmpty()
|
!mediaItem.playbackProperties.streamKeys.isEmpty()
|
||||||
? mediaItem.playbackProperties.streamKeys
|
? mediaItem.playbackProperties.streamKeys
|
||||||
: streamKeys);
|
: streamKeys);
|
||||||
|
mediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy);
|
||||||
|
|
||||||
MediaSource mediaSource = mediaSourceFactory.createMediaSource(mediaItem);
|
MediaSource mediaSource = mediaSourceFactory.createMediaSource(mediaItem);
|
||||||
|
|
||||||
@ -285,7 +296,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static SparseArray<MediaSourceFactory> loadDelegates(
|
private static SparseArray<MediaSourceFactory> loadDelegates(
|
||||||
DataSource.Factory dataSourceFactory) {
|
DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) {
|
||||||
SparseArray<MediaSourceFactory> factories = new SparseArray<>();
|
SparseArray<MediaSourceFactory> factories = new SparseArray<>();
|
||||||
// LINT.IfChange
|
// LINT.IfChange
|
||||||
try {
|
try {
|
||||||
@ -320,7 +331,8 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
|||||||
// Expected if the app was built without the hls module.
|
// Expected if the app was built without the hls module.
|
||||||
}
|
}
|
||||||
// LINT.ThenChange(../../../../../../../../proguard-rules.txt)
|
// LINT.ThenChange(../../../../../../../../proguard-rules.txt)
|
||||||
factories.put(C.TYPE_OTHER, new ProgressiveMediaSource.Factory(dataSourceFactory));
|
factories.put(
|
||||||
|
C.TYPE_OTHER, new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory));
|
||||||
return factories;
|
return factories;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
|
|||||||
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
||||||
import com.google.android.exoplayer2.offline.StreamKey;
|
import com.google.android.exoplayer2.offline.StreamKey;
|
||||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||||
|
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
|
||||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -59,7 +60,8 @@ public interface MediaSourceFactory {
|
|||||||
* Sets the {@link DrmSessionManager} to use for all media items regardless of their {@link
|
* Sets the {@link DrmSessionManager} to use for all media items regardless of their {@link
|
||||||
* MediaItem.DrmConfiguration}.
|
* MediaItem.DrmConfiguration}.
|
||||||
*
|
*
|
||||||
* @param drmSessionManager The {@link DrmSessionManager}.
|
* @param drmSessionManager The {@link DrmSessionManager}, or {@code null} to use the {@link
|
||||||
|
* DefaultDrmSessionManager}.
|
||||||
* @return This factory, for convenience.
|
* @return This factory, for convenience.
|
||||||
*/
|
*/
|
||||||
MediaSourceFactory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager);
|
MediaSourceFactory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager);
|
||||||
@ -85,7 +87,8 @@ public interface MediaSourceFactory {
|
|||||||
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)} or a {@link DrmSessionManager} has been
|
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)} or a {@link DrmSessionManager} has been
|
||||||
* set by {@link #setDrmSessionManager(DrmSessionManager)}, this user agent is ignored.
|
* set by {@link #setDrmSessionManager(DrmSessionManager)}, this user agent is ignored.
|
||||||
*
|
*
|
||||||
* @param userAgent The user agent to be used for DRM requests.
|
* @param userAgent The user agent to be used for DRM requests, or {@code null} to use the
|
||||||
|
* default.
|
||||||
* @return This factory, for convenience.
|
* @return This factory, for convenience.
|
||||||
*/
|
*/
|
||||||
MediaSourceFactory setDrmUserAgent(@Nullable String userAgent);
|
MediaSourceFactory setDrmUserAgent(@Nullable String userAgent);
|
||||||
@ -93,7 +96,8 @@ public interface MediaSourceFactory {
|
|||||||
/**
|
/**
|
||||||
* Sets an optional {@link LoadErrorHandlingPolicy}.
|
* Sets an optional {@link LoadErrorHandlingPolicy}.
|
||||||
*
|
*
|
||||||
* @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}.
|
* @param loadErrorHandlingPolicy A {@link LoadErrorHandlingPolicy}, or {@code null} to use the
|
||||||
|
* {@link DefaultLoadErrorHandlingPolicy}.
|
||||||
* @return This factory, for convenience.
|
* @return This factory, for convenience.
|
||||||
*/
|
*/
|
||||||
MediaSourceFactory setLoadErrorHandlingPolicy(
|
MediaSourceFactory setLoadErrorHandlingPolicy(
|
||||||
|
@ -22,6 +22,12 @@ import java.util.Map;
|
|||||||
/** Factory for arrays of {@link Extractor} instances. */
|
/** Factory for arrays of {@link Extractor} instances. */
|
||||||
public interface ExtractorsFactory {
|
public interface ExtractorsFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extractor factory that returns an empty list of extractors. Can be used whenever {@link
|
||||||
|
* Extractor Extractors} are not required.
|
||||||
|
*/
|
||||||
|
ExtractorsFactory EMPTY = () -> new Extractor[] {};
|
||||||
|
|
||||||
/** Returns an array of new {@link Extractor} instances. */
|
/** Returns an array of new {@link Extractor} instances. */
|
||||||
Extractor[] createExtractors();
|
Extractor[] createExtractors();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user