mirror of
https://github.com/androidx/media.git
synced 2025-05-07 07:30:22 +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.device.DeviceInfo;
|
||||
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.MetadataOutput;
|
||||
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.upstream.BandwidthMeter;
|
||||
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.Clock;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
@ -115,9 +118,11 @@ public class SimpleExoPlayer extends BasePlayer
|
||||
/**
|
||||
* Creates a builder.
|
||||
*
|
||||
* <p>Use {@link #Builder(Context, RenderersFactory)} instead, if you intend to provide a custom
|
||||
* {@link RenderersFactory}. This is to ensure that ProGuard or R8 can remove ExoPlayer's {@link
|
||||
* DefaultRenderersFactory} from the APK.
|
||||
* <p>Use {@link #Builder(Context, RenderersFactory)} or {@link #Builder(Context,
|
||||
* RenderersFactory, ExtractorsFactory)} instead, if you intend to provide a custom {@link
|
||||
* 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:
|
||||
*
|
||||
@ -146,7 +151,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||
* @param context A {@link 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.
|
||||
*/
|
||||
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(
|
||||
context,
|
||||
renderersFactory,
|
||||
new DefaultTrackSelector(context),
|
||||
new DefaultMediaSourceFactory(context),
|
||||
new DefaultMediaSourceFactory(
|
||||
new DefaultDataSourceFactory(
|
||||
context, Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY)),
|
||||
extractorsFactory),
|
||||
new DefaultLoadControl(),
|
||||
DefaultBandwidthMeter.getSingletonInstance(context),
|
||||
new AnalyticsCollector(Clock.DEFAULT));
|
||||
@ -546,7 +570,7 @@ public class SimpleExoPlayer extends BasePlayer
|
||||
Clock clock,
|
||||
Looper applicationLooper) {
|
||||
this(
|
||||
new Builder(context, renderersFactory)
|
||||
new Builder(context, renderersFactory, new DefaultExtractorsFactory())
|
||||
.setTrackSelector(trackSelector)
|
||||
.setMediaSourceFactory(mediaSourceFactory)
|
||||
.setLoadControl(loadControl)
|
||||
|
@ -34,6 +34,7 @@ import com.google.android.exoplayer2.RenderersFactory;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
|
||||
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.MediaPeriod;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
@ -889,7 +890,7 @@ public final class DownloadHelper {
|
||||
MediaItem mediaItem,
|
||||
DataSource.Factory dataSourceFactory,
|
||||
@Nullable DrmSessionManager drmSessionManager) {
|
||||
return new DefaultMediaSourceFactory(dataSourceFactory)
|
||||
return new DefaultMediaSourceFactory(dataSourceFactory, ExtractorsFactory.EMPTY)
|
||||
.setDrmSessionManager(drmSessionManager)
|
||||
.createMediaSource(mediaItem);
|
||||
}
|
||||
|
@ -23,13 +23,14 @@ import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
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.source.ads.AdsLoader;
|
||||
import com.google.android.exoplayer2.source.ads.AdsLoader.AdViewProvider;
|
||||
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
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.LoadErrorHandlingPolicy;
|
||||
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
|
||||
* MediaItem.PlaybackProperties#uri uri} doesn't match one of the above. It tries to infer the
|
||||
* required extractor by using the {@link
|
||||
* com.google.android.exoplayer2.extractor.DefaultExtractorsFactory}. An {@link
|
||||
* UnrecognizedInputFormatException} is thrown if none of the available extractors can read
|
||||
* the stream.
|
||||
* com.google.android.exoplayer2.extractor.DefaultExtractorsFactory} or the {@link
|
||||
* ExtractorsFactory} provided in {@link #DefaultMediaSourceFactory(DataSource.Factory,
|
||||
* ExtractorsFactory)}. An {@link UnrecognizedInputFormatException} is thrown if none of the
|
||||
* available extractors can read the stream.
|
||||
* </ul>
|
||||
*
|
||||
* <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 DrmSessionManager drmSessionManager;
|
||||
@Nullable private List<StreamKey> streamKeys;
|
||||
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
@ -124,9 +127,22 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
||||
* for requesting media data.
|
||||
*/
|
||||
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;
|
||||
mediaSourceDrmHelper = new MediaSourceDrmHelper();
|
||||
mediaSourceFactories = loadDelegates(dataSourceFactory);
|
||||
mediaSourceFactories = loadDelegates(dataSourceFactory, extractorsFactory);
|
||||
supportedTypes = new int[mediaSourceFactories.size()];
|
||||
for (int i = 0; i < mediaSourceFactories.size(); i++) {
|
||||
supportedTypes[i] = mediaSourceFactories.keyAt(i);
|
||||
@ -180,13 +196,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
||||
@Override
|
||||
public DefaultMediaSourceFactory setLoadErrorHandlingPolicy(
|
||||
@Nullable LoadErrorHandlingPolicy loadErrorHandlingPolicy) {
|
||||
LoadErrorHandlingPolicy newLoadErrorHandlingPolicy =
|
||||
loadErrorHandlingPolicy != null
|
||||
? loadErrorHandlingPolicy
|
||||
: new DefaultLoadErrorHandlingPolicy();
|
||||
for (int i = 0; i < mediaSourceFactories.size(); i++) {
|
||||
mediaSourceFactories.valueAt(i).setLoadErrorHandlingPolicy(newLoadErrorHandlingPolicy);
|
||||
}
|
||||
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -224,6 +234,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
||||
!mediaItem.playbackProperties.streamKeys.isEmpty()
|
||||
? mediaItem.playbackProperties.streamKeys
|
||||
: streamKeys);
|
||||
mediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy);
|
||||
|
||||
MediaSource mediaSource = mediaSourceFactory.createMediaSource(mediaItem);
|
||||
|
||||
@ -285,7 +296,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
||||
}
|
||||
|
||||
private static SparseArray<MediaSourceFactory> loadDelegates(
|
||||
DataSource.Factory dataSourceFactory) {
|
||||
DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) {
|
||||
SparseArray<MediaSourceFactory> factories = new SparseArray<>();
|
||||
// LINT.IfChange
|
||||
try {
|
||||
@ -320,7 +331,8 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
|
||||
// Expected if the app was built without the hls module.
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
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.LoadErrorHandlingPolicy;
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
MediaSourceFactory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager);
|
||||
@ -85,7 +87,8 @@ public interface MediaSourceFactory {
|
||||
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)} or a {@link DrmSessionManager} has been
|
||||
* 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.
|
||||
*/
|
||||
MediaSourceFactory setDrmUserAgent(@Nullable String userAgent);
|
||||
@ -93,7 +96,8 @@ public interface MediaSourceFactory {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
MediaSourceFactory setLoadErrorHandlingPolicy(
|
||||
|
@ -22,6 +22,12 @@ import java.util.Map;
|
||||
/** Factory for arrays of {@link Extractor} instances. */
|
||||
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. */
|
||||
Extractor[] createExtractors();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user