Commit bfe17aee by tonihei Committed by Oliver Woodman

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
parent 3110587f
......@@ -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();
......
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