Provide a constructor that does not require a context

The only reason to require a context for creating an instance of
DefaultMediaSourceFactory is creating a user agent. DownloadHelper
has a bunch of static methods that need to instantiate a
DefaultMediaSourceFactory without a Context. By adding a setter for
the user agent we can remove that restriction and use a default user
agent.

PiperOrigin-RevId: 311291603
This commit is contained in:
bachinger 2020-05-13 10:21:46 +01:00 committed by Oliver Woodman
parent 478be50219
commit fefb2a03c2
3 changed files with 64 additions and 30 deletions

View File

@ -325,7 +325,7 @@ public class PlayerActivity extends AppCompatActivity
player = player =
new SimpleExoPlayer.Builder(/* context= */ this, renderersFactory) new SimpleExoPlayer.Builder(/* context= */ this, renderersFactory)
.setMediaSourceFactory( .setMediaSourceFactory(
new DefaultMediaSourceFactory( DefaultMediaSourceFactory.newInstance(
/* context= */ this, dataSourceFactory, new AdSupportProvider())) /* context= */ this, dataSourceFactory, new AdSupportProvider()))
.setTrackSelector(trackSelector) .setTrackSelector(trackSelector)
.build(); .build();

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.util.SparseArray; import android.util.SparseArray;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
@ -94,8 +95,8 @@ import java.util.Map;
* *
* <h3>Ad support for media items with ad tag uri</h3> * <h3>Ad support for media items with ad tag uri</h3>
* *
* <p>For a media item with an ad tag uri an {@link AdSupportProvider} needs to be passed to the * <p>For a media item with an ad tag uri, an {@link AdSupportProvider} needs to be passed to {@link
* constructor {@link #DefaultMediaSourceFactory(Context, DataSource.Factory, AdSupportProvider)}. * #newInstance(Context, DataSource.Factory, AdSupportProvider)}.
*/ */
public final class DefaultMediaSourceFactory implements MediaSourceFactory { public final class DefaultMediaSourceFactory implements MediaSourceFactory {
@ -128,6 +129,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
* DefaultDataSourceFactory)}. * DefaultDataSourceFactory)}.
* *
* @param context The {@link Context}. * @param context The {@link Context}.
* @return A new instance of {@link DefaultMediaSourceFactory}.
*/ */
public static DefaultMediaSourceFactory newInstance(Context context) { public static DefaultMediaSourceFactory newInstance(Context context) {
return newInstance( return newInstance(
@ -141,41 +143,60 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
* *
* @param context The {@link Context}. * @param context The {@link Context}.
* @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources. * @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources.
* @return A new instance of {@link DefaultMediaSourceFactory}.
*/ */
public static DefaultMediaSourceFactory newInstance( public static DefaultMediaSourceFactory newInstance(
Context context, DataSource.Factory dataSourceFactory) { Context context, DataSource.Factory dataSourceFactory) {
return new DefaultMediaSourceFactory(context, dataSourceFactory, /* adSupportProvider= */ null); return new DefaultMediaSourceFactory(dataSourceFactory, /* adSupportProvider= */ null)
.setDrmUserAgent(Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY));
} }
private static final String TAG = "DefaultMediaSourceFactory";
private final DataSource.Factory dataSourceFactory;
@Nullable private final AdSupportProvider adSupportProvider;
private final SparseArray<MediaSourceFactory> mediaSourceFactories;
@C.ContentType private final int[] supportedTypes;
private final String userAgent;
private DrmSessionManager drmSessionManager;
private HttpDataSource.Factory drmHttpDataSourceFactory;
@Nullable private List<StreamKey> streamKeys;
/** /**
* Creates a new instance with the given {@link Context} and {@link DataSource.Factory}. * Creates a new instance with the given {@link Context} and {@link DataSource.Factory}.
* *
* @param context The {@link Context}. * @param context The {@link Context}.
* @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources. * @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources.
* @param adSupportProvider A {@link AdSupportProvider} to be used to create ad media sources.
* @return A new instance of {@link DefaultMediaSourceFactory}.
*/
public static DefaultMediaSourceFactory newInstance(
Context context, DataSource.Factory dataSourceFactory, AdSupportProvider adSupportProvider) {
return new DefaultMediaSourceFactory(dataSourceFactory, adSupportProvider)
.setDrmUserAgent(Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY));
}
private static final String TAG = "DefaultMediaSourceFactory";
private static final String DEFAULT_USER_AGENT =
ExoPlayerLibraryInfo.VERSION_SLASHY
+ " (Linux;Android "
+ Build.VERSION.RELEASE
+ ") "
+ ExoPlayerLibraryInfo.VERSION_SLASHY;
private final DataSource.Factory dataSourceFactory;
@Nullable private final AdSupportProvider adSupportProvider;
private final SparseArray<MediaSourceFactory> mediaSourceFactories;
@C.ContentType private final int[] supportedTypes;
private DrmSessionManager drmSessionManager;
@Nullable private HttpDataSource.Factory drmHttpDataSourceFactory;
private String userAgent;
@Nullable private List<StreamKey> streamKeys;
/**
* Creates a new instance with the {@link DataSource.Factory} for downloading media and an {@link
* AdSupportProvider} to create {@link AdsMediaSource AdsMediaSources}.
*
* @param dataSourceFactory A {@link DataSource.Factory} to be used to create media sources.
* @param adSupportProvider An {@link AdSupportProvider} to get ads loaders and ad view providers * @param adSupportProvider An {@link AdSupportProvider} to get ads loaders and ad view providers
* to be used to create {@link AdsMediaSource AdsMediaSources}. * to be used to create {@link AdsMediaSource AdsMediaSources}.
*/ */
public DefaultMediaSourceFactory( public DefaultMediaSourceFactory(
Context context, DataSource.Factory dataSourceFactory, @Nullable AdSupportProvider adSupportProvider) {
DataSource.Factory dataSourceFactory,
@Nullable AdSupportProvider adSupportProvider) {
this.dataSourceFactory = dataSourceFactory; this.dataSourceFactory = dataSourceFactory;
this.adSupportProvider = adSupportProvider; this.adSupportProvider = adSupportProvider;
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager(); drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
userAgent = Util.getUserAgent(context, ExoPlayerLibraryInfo.VERSION_SLASHY); userAgent = DEFAULT_USER_AGENT;
drmHttpDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent);
mediaSourceFactories = loadDelegates(dataSourceFactory); mediaSourceFactories = loadDelegates(dataSourceFactory);
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++) {
@ -194,10 +215,21 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
*/ */
public DefaultMediaSourceFactory setDrmHttpDataSourceFactory( public DefaultMediaSourceFactory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) { @Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
this.drmHttpDataSourceFactory = this.drmHttpDataSourceFactory = drmHttpDataSourceFactory;
drmHttpDataSourceFactory != null return this;
? drmHttpDataSourceFactory }
: new DefaultHttpDataSourceFactory(userAgent);
/**
* Sets the optional user agent to be used for DRM requests.
*
* <p>In case a factory has been set by {@link
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)}, this user agent is ignored.
*
* @param userAgent The user agent to be used for DRM requests.
* @return This factory, for convenience.
*/
public DefaultMediaSourceFactory setDrmUserAgent(@Nullable String userAgent) {
this.userAgent = userAgent != null ? userAgent : DEFAULT_USER_AGENT;
return this; return this;
} }
@ -309,7 +341,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
new HttpMediaDrmCallback( new HttpMediaDrmCallback(
drmConfiguration.licenseUri.toString(), drmConfiguration.licenseUri.toString(),
drmConfiguration.forceDefaultLicenseUri, drmConfiguration.forceDefaultLicenseUri,
drmHttpDataSourceFactory); drmHttpDataSourceFactory != null
? drmHttpDataSourceFactory
: new DefaultHttpDataSourceFactory(userAgent));
for (Map.Entry<String, String> entry : drmConfiguration.requestHeaders.entrySet()) { for (Map.Entry<String, String> entry : drmConfiguration.requestHeaders.entrySet()) {
drmCallback.setKeyRequestProperty(entry.getKey(), entry.getValue()); drmCallback.setKeyRequestProperty(entry.getKey(), entry.getValue());
} }

View File

@ -193,9 +193,9 @@ public final class DefaultMediaSourceFactoryTest {
Uri adTagUri = Uri.parse(URI_MEDIA); Uri adTagUri = Uri.parse(URI_MEDIA);
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_MEDIA).setAdTagUri(adTagUri).build(); MediaItem mediaItem = new MediaItem.Builder().setUri(URI_MEDIA).setAdTagUri(adTagUri).build();
DefaultMediaSourceFactory defaultMediaSourceFactory = DefaultMediaSourceFactory defaultMediaSourceFactory =
new DefaultMediaSourceFactory( DefaultMediaSourceFactory.newInstance(
applicationContext, applicationContext,
new DefaultDataSourceFactory(applicationContext, "userAgent"), new DefaultDataSourceFactory(applicationContext, /* userAgent= */ "ua"),
createAdSupportProvider(mock(AdsLoader.class), mock(AdsLoader.AdViewProvider.class))); createAdSupportProvider(mock(AdsLoader.class), mock(AdsLoader.AdViewProvider.class)));
MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem); MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem);
@ -209,9 +209,9 @@ public final class DefaultMediaSourceFactoryTest {
MediaItem mediaItem = MediaItem mediaItem =
new MediaItem.Builder().setUri(URI_MEDIA).setAdTagUri(Uri.parse(URI_MEDIA)).build(); new MediaItem.Builder().setUri(URI_MEDIA).setAdTagUri(Uri.parse(URI_MEDIA)).build();
DefaultMediaSourceFactory defaultMediaSourceFactory = DefaultMediaSourceFactory defaultMediaSourceFactory =
new DefaultMediaSourceFactory( DefaultMediaSourceFactory.newInstance(
applicationContext, applicationContext,
new DefaultDataSourceFactory(applicationContext, "userAgent"), new DefaultDataSourceFactory(applicationContext, /* userAgent= */ "ua"),
createAdSupportProvider(/* adsLoader= */ null, mock(AdsLoader.AdViewProvider.class))); createAdSupportProvider(/* adsLoader= */ null, mock(AdsLoader.AdViewProvider.class)));
MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem); MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem);