mirror of
https://github.com/samsonjs/media.git
synced 2026-04-11 12:15:47 +00:00
Support different drm schemes in playlists in the demo app
This CL changes PlayerActivity's VIEW_LIST action intent contract: Each media item configuration is provided by indexing the entries. For example, the URI of the first item is passed as "uri_0", the second one is "uri_1", etc. Optionally, the extra parameters, like the extensions, are passed as "extension_1", where the intent extras with matching indices, refer to the same media sample. The VIEW action's contract remains unchanged. PiperOrigin-RevId: 260518118
This commit is contained in:
parent
3051e5e9ad
commit
06f9481505
4 changed files with 360 additions and 252 deletions
|
|
@ -38,6 +38,7 @@ import com.google.android.exoplayer2.PlaybackPreparer;
|
|||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.RenderersFactory;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.demo.Sample.UriSample;
|
||||
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.DrmSessionManager;
|
||||
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
|
||||
|
|
@ -78,41 +79,48 @@ import java.lang.reflect.Constructor;
|
|||
import java.net.CookieHandler;
|
||||
import java.net.CookieManager;
|
||||
import java.net.CookiePolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
/** An activity that plays media using {@link SimpleExoPlayer}. */
|
||||
public class PlayerActivity extends AppCompatActivity
|
||||
implements OnClickListener, PlaybackPreparer, PlayerControlView.VisibilityListener {
|
||||
|
||||
public static final String DRM_SCHEME_EXTRA = "drm_scheme";
|
||||
public static final String DRM_LICENSE_URL_EXTRA = "drm_license_url";
|
||||
public static final String DRM_KEY_REQUEST_PROPERTIES_EXTRA = "drm_key_request_properties";
|
||||
public static final String DRM_MULTI_SESSION_EXTRA = "drm_multi_session";
|
||||
public static final String PREFER_EXTENSION_DECODERS_EXTRA = "prefer_extension_decoders";
|
||||
|
||||
public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW";
|
||||
public static final String EXTENSION_EXTRA = "extension";
|
||||
|
||||
public static final String ACTION_VIEW_LIST =
|
||||
"com.google.android.exoplayer.demo.action.VIEW_LIST";
|
||||
public static final String URI_LIST_EXTRA = "uri_list";
|
||||
public static final String EXTENSION_LIST_EXTRA = "extension_list";
|
||||
|
||||
public static final String AD_TAG_URI_EXTRA = "ad_tag_uri";
|
||||
|
||||
public static final String ABR_ALGORITHM_EXTRA = "abr_algorithm";
|
||||
public static final String ABR_ALGORITHM_DEFAULT = "default";
|
||||
public static final String ABR_ALGORITHM_RANDOM = "random";
|
||||
// Activity extras.
|
||||
|
||||
public static final String SPHERICAL_STEREO_MODE_EXTRA = "spherical_stereo_mode";
|
||||
public static final String SPHERICAL_STEREO_MODE_MONO = "mono";
|
||||
public static final String SPHERICAL_STEREO_MODE_TOP_BOTTOM = "top_bottom";
|
||||
public static final String SPHERICAL_STEREO_MODE_LEFT_RIGHT = "left_right";
|
||||
|
||||
// Actions.
|
||||
|
||||
public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW";
|
||||
public static final String ACTION_VIEW_LIST =
|
||||
"com.google.android.exoplayer.demo.action.VIEW_LIST";
|
||||
|
||||
// Player configuration extras.
|
||||
|
||||
public static final String ABR_ALGORITHM_EXTRA = "abr_algorithm";
|
||||
public static final String ABR_ALGORITHM_DEFAULT = "default";
|
||||
public static final String ABR_ALGORITHM_RANDOM = "random";
|
||||
|
||||
// Media item configuration extras.
|
||||
|
||||
public static final String URI_EXTRA = "uri";
|
||||
public static final String EXTENSION_EXTRA = "extension";
|
||||
|
||||
public static final String DRM_SCHEME_EXTRA = "drm_scheme";
|
||||
public static final String DRM_LICENSE_URL_EXTRA = "drm_license_url";
|
||||
public static final String DRM_KEY_REQUEST_PROPERTIES_EXTRA = "drm_key_request_properties";
|
||||
public static final String DRM_MULTI_SESSION_EXTRA = "drm_multi_session";
|
||||
public static final String PREFER_EXTENSION_DECODERS_EXTRA = "prefer_extension_decoders";
|
||||
public static final String AD_TAG_URI_EXTRA = "ad_tag_uri";
|
||||
// For backwards compatibility only.
|
||||
private static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
|
||||
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
|
||||
|
||||
// Saved instance state keys.
|
||||
|
||||
private static final String KEY_TRACK_SELECTOR_PARAMETERS = "track_selector_parameters";
|
||||
private static final String KEY_WINDOW = "window";
|
||||
private static final String KEY_POSITION = "position";
|
||||
|
|
@ -124,6 +132,8 @@ public class PlayerActivity extends AppCompatActivity
|
|||
DEFAULT_COOKIE_MANAGER.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
|
||||
}
|
||||
|
||||
private final ArrayList<FrameworkMediaDrm> mediaDrms;
|
||||
|
||||
private PlayerView playerView;
|
||||
private LinearLayout debugRootView;
|
||||
private Button selectTracksButton;
|
||||
|
|
@ -132,7 +142,6 @@ public class PlayerActivity extends AppCompatActivity
|
|||
|
||||
private DataSource.Factory dataSourceFactory;
|
||||
private SimpleExoPlayer player;
|
||||
private FrameworkMediaDrm mediaDrm;
|
||||
private MediaSource mediaSource;
|
||||
private DefaultTrackSelector trackSelector;
|
||||
private DefaultTrackSelector.Parameters trackSelectorParameters;
|
||||
|
|
@ -148,6 +157,10 @@ public class PlayerActivity extends AppCompatActivity
|
|||
private AdsLoader adsLoader;
|
||||
private Uri loadedAdTagUri;
|
||||
|
||||
public PlayerActivity() {
|
||||
mediaDrms = new ArrayList<>();
|
||||
}
|
||||
|
||||
// Activity lifecycle
|
||||
|
||||
@Override
|
||||
|
|
@ -329,69 +342,11 @@ public class PlayerActivity extends AppCompatActivity
|
|||
private void initializePlayer() {
|
||||
if (player == null) {
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
Uri[] uris;
|
||||
String[] extensions;
|
||||
if (ACTION_VIEW.equals(action)) {
|
||||
uris = new Uri[] {intent.getData()};
|
||||
extensions = new String[] {intent.getStringExtra(EXTENSION_EXTRA)};
|
||||
} else if (ACTION_VIEW_LIST.equals(action)) {
|
||||
String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
|
||||
uris = new Uri[uriStrings.length];
|
||||
for (int i = 0; i < uriStrings.length; i++) {
|
||||
uris[i] = Uri.parse(uriStrings[i]);
|
||||
}
|
||||
extensions = intent.getStringArrayExtra(EXTENSION_LIST_EXTRA);
|
||||
if (extensions == null) {
|
||||
extensions = new String[uriStrings.length];
|
||||
}
|
||||
} else {
|
||||
showToast(getString(R.string.unexpected_intent_action, action));
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
if (!Util.checkCleartextTrafficPermitted(uris)) {
|
||||
showToast(R.string.error_cleartext_not_permitted);
|
||||
return;
|
||||
}
|
||||
if (Util.maybeRequestReadExternalStoragePermission(/* activity= */ this, uris)) {
|
||||
// The player will be reinitialized if the permission is granted.
|
||||
return;
|
||||
}
|
||||
|
||||
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager = null;
|
||||
if (intent.hasExtra(DRM_SCHEME_EXTRA) || intent.hasExtra(DRM_SCHEME_UUID_EXTRA)) {
|
||||
String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL_EXTRA);
|
||||
String[] keyRequestPropertiesArray =
|
||||
intent.getStringArrayExtra(DRM_KEY_REQUEST_PROPERTIES_EXTRA);
|
||||
boolean multiSession = intent.getBooleanExtra(DRM_MULTI_SESSION_EXTRA, false);
|
||||
int errorStringId = R.string.error_drm_unknown;
|
||||
if (Util.SDK_INT < 18) {
|
||||
errorStringId = R.string.error_drm_not_supported;
|
||||
} else {
|
||||
try {
|
||||
String drmSchemeExtra = intent.hasExtra(DRM_SCHEME_EXTRA) ? DRM_SCHEME_EXTRA
|
||||
: DRM_SCHEME_UUID_EXTRA;
|
||||
UUID drmSchemeUuid = Util.getDrmUuid(intent.getStringExtra(drmSchemeExtra));
|
||||
if (drmSchemeUuid == null) {
|
||||
errorStringId = R.string.error_drm_unsupported_scheme;
|
||||
} else {
|
||||
drmSessionManager =
|
||||
buildDrmSessionManagerV18(
|
||||
drmSchemeUuid, drmLicenseUrl, keyRequestPropertiesArray, multiSession);
|
||||
}
|
||||
} catch (UnsupportedDrmException e) {
|
||||
errorStringId = e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
|
||||
? R.string.error_drm_unsupported_scheme : R.string.error_drm_unknown;
|
||||
}
|
||||
}
|
||||
if (drmSessionManager == null) {
|
||||
showToast(errorStringId);
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
|
||||
releaseMediaDrms();
|
||||
mediaSource = createTopLevelMediaSource(intent);
|
||||
if (mediaSource == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TrackSelection.Factory trackSelectionFactory;
|
||||
|
|
@ -424,28 +379,8 @@ public class PlayerActivity extends AppCompatActivity
|
|||
playerView.setPlaybackPreparer(this);
|
||||
debugViewHelper = new DebugTextViewHelper(player, debugTextView);
|
||||
debugViewHelper.start();
|
||||
|
||||
MediaSource[] mediaSources = new MediaSource[uris.length];
|
||||
for (int i = 0; i < uris.length; i++) {
|
||||
mediaSources[i] = buildMediaSource(uris[i], extensions[i], drmSessionManager);
|
||||
}
|
||||
mediaSource =
|
||||
mediaSources.length == 1 ? mediaSources[0] : new ConcatenatingMediaSource(mediaSources);
|
||||
String adTagUriString = intent.getStringExtra(AD_TAG_URI_EXTRA);
|
||||
if (adTagUriString != null) {
|
||||
Uri adTagUri = Uri.parse(adTagUriString);
|
||||
if (!adTagUri.equals(loadedAdTagUri)) {
|
||||
releaseAdsLoader();
|
||||
loadedAdTagUri = adTagUri;
|
||||
}
|
||||
MediaSource adsMediaSource = createAdsMediaSource(mediaSource, Uri.parse(adTagUriString));
|
||||
if (adsMediaSource != null) {
|
||||
mediaSource = adsMediaSource;
|
||||
} else {
|
||||
showToast(R.string.ima_not_loaded);
|
||||
}
|
||||
} else {
|
||||
releaseAdsLoader();
|
||||
if (adsLoader != null) {
|
||||
adsLoader.setPlayer(player);
|
||||
}
|
||||
}
|
||||
boolean haveStartPosition = startWindow != C.INDEX_UNSET;
|
||||
|
|
@ -456,23 +391,113 @@ public class PlayerActivity extends AppCompatActivity
|
|||
updateButtonVisibility();
|
||||
}
|
||||
|
||||
private MediaSource buildMediaSource(Uri uri) {
|
||||
return buildMediaSource(
|
||||
uri,
|
||||
/* overrideExtension= */ null,
|
||||
/* drmSessionManager= */ DrmSessionManager.getDummyDrmSessionManager());
|
||||
@Nullable
|
||||
private MediaSource createTopLevelMediaSource(Intent intent) {
|
||||
String action = intent.getAction();
|
||||
boolean actionIsListView = ACTION_VIEW_LIST.equals(action);
|
||||
if (!actionIsListView && !ACTION_VIEW.equals(action)) {
|
||||
showToast(getString(R.string.unexpected_intent_action, action));
|
||||
finish();
|
||||
return null;
|
||||
}
|
||||
|
||||
Sample intentAsSample = Sample.createFromIntent(intent);
|
||||
UriSample[] samples =
|
||||
intentAsSample instanceof Sample.PlaylistSample
|
||||
? ((Sample.PlaylistSample) intentAsSample).children
|
||||
: new UriSample[] {(UriSample) intentAsSample};
|
||||
|
||||
boolean seenAdsTagUri = false;
|
||||
for (UriSample sample : samples) {
|
||||
seenAdsTagUri |= sample.adTagUri != null;
|
||||
if (!Util.checkCleartextTrafficPermitted(sample.uri)) {
|
||||
showToast(R.string.error_cleartext_not_permitted);
|
||||
return null;
|
||||
}
|
||||
if (Util.maybeRequestReadExternalStoragePermission(/* activity= */ this, sample.uri)) {
|
||||
// The player will be reinitialized if the permission is granted.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
MediaSource[] mediaSources = new MediaSource[samples.length];
|
||||
for (int i = 0; i < samples.length; i++) {
|
||||
mediaSources[i] = createLeafMediaSource(samples[i]);
|
||||
}
|
||||
MediaSource mediaSource =
|
||||
mediaSources.length == 1 ? mediaSources[0] : new ConcatenatingMediaSource(mediaSources);
|
||||
|
||||
if (seenAdsTagUri) {
|
||||
Uri adTagUri = samples[0].adTagUri;
|
||||
if (actionIsListView) {
|
||||
showToast(R.string.unsupported_ads_in_concatenation);
|
||||
} else {
|
||||
if (!adTagUri.equals(loadedAdTagUri)) {
|
||||
releaseAdsLoader();
|
||||
loadedAdTagUri = adTagUri;
|
||||
}
|
||||
MediaSource adsMediaSource = createAdsMediaSource(mediaSource, adTagUri);
|
||||
if (adsMediaSource != null) {
|
||||
mediaSource = adsMediaSource;
|
||||
} else {
|
||||
showToast(R.string.ima_not_loaded);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
releaseAdsLoader();
|
||||
}
|
||||
|
||||
return mediaSource;
|
||||
}
|
||||
|
||||
private MediaSource buildMediaSource(
|
||||
Uri uri,
|
||||
@Nullable String overrideExtension,
|
||||
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
|
||||
private MediaSource createLeafMediaSource(UriSample parameters) {
|
||||
DrmSessionManager<FrameworkMediaCrypto> drmSessionManager = null;
|
||||
Sample.DrmInfo drmInfo = parameters.drmInfo;
|
||||
if (drmInfo != null) {
|
||||
int errorStringId = R.string.error_drm_unknown;
|
||||
if (Util.SDK_INT < 18) {
|
||||
errorStringId = R.string.error_drm_not_supported;
|
||||
} else {
|
||||
try {
|
||||
if (drmInfo.drmScheme == null) {
|
||||
errorStringId = R.string.error_drm_unsupported_scheme;
|
||||
} else {
|
||||
drmSessionManager =
|
||||
buildDrmSessionManagerV18(
|
||||
drmInfo.drmScheme,
|
||||
drmInfo.drmLicenseUrl,
|
||||
drmInfo.drmKeyRequestProperties,
|
||||
drmInfo.drmMultiSession);
|
||||
}
|
||||
} catch (UnsupportedDrmException e) {
|
||||
errorStringId =
|
||||
e.reason == UnsupportedDrmException.REASON_UNSUPPORTED_SCHEME
|
||||
? R.string.error_drm_unsupported_scheme
|
||||
: R.string.error_drm_unknown;
|
||||
}
|
||||
}
|
||||
if (drmSessionManager == null) {
|
||||
showToast(errorStringId);
|
||||
finish();
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
|
||||
}
|
||||
|
||||
DownloadRequest downloadRequest =
|
||||
((DemoApplication) getApplication()).getDownloadTracker().getDownloadRequest(uri);
|
||||
((DemoApplication) getApplication())
|
||||
.getDownloadTracker()
|
||||
.getDownloadRequest(parameters.uri);
|
||||
if (downloadRequest != null) {
|
||||
return DownloadHelper.createMediaSource(downloadRequest, dataSourceFactory);
|
||||
}
|
||||
@ContentType int type = Util.inferContentType(uri, overrideExtension);
|
||||
return createLeafMediaSource(parameters.uri, parameters.extension, drmSessionManager);
|
||||
}
|
||||
|
||||
private MediaSource createLeafMediaSource(
|
||||
Uri uri, String extension, DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
|
||||
@ContentType int type = Util.inferContentType(uri, extension);
|
||||
switch (type) {
|
||||
case C.TYPE_DASH:
|
||||
return new DashMediaSource.Factory(dataSourceFactory)
|
||||
|
|
@ -508,8 +533,9 @@ public class PlayerActivity extends AppCompatActivity
|
|||
keyRequestPropertiesArray[i + 1]);
|
||||
}
|
||||
}
|
||||
releaseMediaDrm();
|
||||
mediaDrm = FrameworkMediaDrm.newInstance(uuid);
|
||||
|
||||
FrameworkMediaDrm mediaDrm = FrameworkMediaDrm.newInstance(uuid);
|
||||
mediaDrms.add(mediaDrm);
|
||||
return new DefaultDrmSessionManager<>(uuid, mediaDrm, drmCallback, null, multiSession);
|
||||
}
|
||||
|
||||
|
|
@ -527,14 +553,14 @@ public class PlayerActivity extends AppCompatActivity
|
|||
if (adsLoader != null) {
|
||||
adsLoader.setPlayer(null);
|
||||
}
|
||||
releaseMediaDrm();
|
||||
releaseMediaDrms();
|
||||
}
|
||||
|
||||
private void releaseMediaDrm() {
|
||||
if (mediaDrm != null) {
|
||||
private void releaseMediaDrms() {
|
||||
for (FrameworkMediaDrm mediaDrm : mediaDrms) {
|
||||
mediaDrm.release();
|
||||
mediaDrm = null;
|
||||
}
|
||||
mediaDrms.clear();
|
||||
}
|
||||
|
||||
private void releaseAdsLoader() {
|
||||
|
|
@ -588,12 +614,12 @@ public class PlayerActivity extends AppCompatActivity
|
|||
// LINT.ThenChange(../../../../../../../../proguard-rules.txt)
|
||||
adsLoader = loaderConstructor.newInstance(this, adTagUri);
|
||||
}
|
||||
adsLoader.setPlayer(player);
|
||||
MediaSourceFactory adMediaSourceFactory =
|
||||
new MediaSourceFactory() {
|
||||
@Override
|
||||
public MediaSource createMediaSource(Uri uri) {
|
||||
return PlayerActivity.this.buildMediaSource(uri);
|
||||
return PlayerActivity.this.createLeafMediaSource(
|
||||
uri, /* extension=*/ null, DrmSessionManager.getDummyDrmSessionManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -718,5 +744,4 @@ public class PlayerActivity extends AppCompatActivity
|
|||
return Pair.create(0, errorString);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.demo;
|
||||
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.ACTION_VIEW_LIST;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.AD_TAG_URI_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.DRM_KEY_REQUEST_PROPERTIES_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.DRM_LICENSE_URL_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.DRM_MULTI_SESSION_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.DRM_SCHEME_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.DRM_SCHEME_UUID_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.EXTENSION_EXTRA;
|
||||
import static com.google.android.exoplayer2.demo.PlayerActivity.URI_EXTRA;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
/* package */ abstract class Sample {
|
||||
|
||||
public static final class UriSample extends Sample {
|
||||
|
||||
public static UriSample createFromIntent(Uri uri, Intent intent, String extrasKeySuffix) {
|
||||
String extension = intent.getStringExtra(EXTENSION_EXTRA + extrasKeySuffix);
|
||||
String adsTagUriString = intent.getStringExtra(AD_TAG_URI_EXTRA + extrasKeySuffix);
|
||||
Uri adTagUri = adsTagUriString != null ? Uri.parse(adsTagUriString) : null;
|
||||
return new UriSample(
|
||||
/* name= */ null,
|
||||
DrmInfo.createFromIntent(intent, extrasKeySuffix),
|
||||
uri,
|
||||
extension,
|
||||
adTagUri,
|
||||
/* sphericalStereoMode= */ null);
|
||||
}
|
||||
|
||||
public final Uri uri;
|
||||
public final String extension;
|
||||
public final DrmInfo drmInfo;
|
||||
public final Uri adTagUri;
|
||||
public final String sphericalStereoMode;
|
||||
|
||||
public UriSample(
|
||||
String name,
|
||||
DrmInfo drmInfo,
|
||||
Uri uri,
|
||||
String extension,
|
||||
Uri adTagUri,
|
||||
String sphericalStereoMode) {
|
||||
super(name);
|
||||
this.uri = uri;
|
||||
this.extension = extension;
|
||||
this.drmInfo = drmInfo;
|
||||
this.adTagUri = adTagUri;
|
||||
this.sphericalStereoMode = sphericalStereoMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToIntent(Intent intent) {
|
||||
intent.setAction(PlayerActivity.ACTION_VIEW).setData(uri);
|
||||
intent.putExtra(PlayerActivity.SPHERICAL_STEREO_MODE_EXTRA, sphericalStereoMode);
|
||||
addPlayerConfigToIntent(intent, /* extrasKeySuffix= */ "");
|
||||
}
|
||||
|
||||
public void addToPlaylistIntent(Intent intent, String extrasKeySuffix) {
|
||||
intent.putExtra(PlayerActivity.URI_EXTRA + extrasKeySuffix, uri.toString());
|
||||
addPlayerConfigToIntent(intent, extrasKeySuffix);
|
||||
}
|
||||
|
||||
private void addPlayerConfigToIntent(Intent intent, String extrasKeySuffix) {
|
||||
intent
|
||||
.putExtra(EXTENSION_EXTRA + extrasKeySuffix, extension)
|
||||
.putExtra(
|
||||
AD_TAG_URI_EXTRA + extrasKeySuffix, adTagUri != null ? adTagUri.toString() : null);
|
||||
if (drmInfo != null) {
|
||||
drmInfo.addToIntent(intent, extrasKeySuffix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class PlaylistSample extends Sample {
|
||||
|
||||
public final UriSample[] children;
|
||||
|
||||
public PlaylistSample(String name, UriSample... children) {
|
||||
super(name);
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToIntent(Intent intent) {
|
||||
intent.setAction(PlayerActivity.ACTION_VIEW_LIST);
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
children[i].addToPlaylistIntent(intent, /* extrasKeySuffix= */ "_" + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class DrmInfo {
|
||||
|
||||
public static DrmInfo createFromIntent(Intent intent, String extrasKeySuffix) {
|
||||
String schemeKey = DRM_SCHEME_EXTRA + extrasKeySuffix;
|
||||
String schemeUuidKey = DRM_SCHEME_UUID_EXTRA + extrasKeySuffix;
|
||||
if (!intent.hasExtra(schemeKey) && !intent.hasExtra(schemeUuidKey)) {
|
||||
return null;
|
||||
}
|
||||
String drmSchemeExtra =
|
||||
intent.hasExtra(schemeKey)
|
||||
? intent.getStringExtra(schemeKey)
|
||||
: intent.getStringExtra(schemeUuidKey);
|
||||
UUID drmScheme = Util.getDrmUuid(drmSchemeExtra);
|
||||
String drmLicenseUrl = intent.getStringExtra(DRM_LICENSE_URL_EXTRA + extrasKeySuffix);
|
||||
String[] keyRequestPropertiesArray =
|
||||
intent.getStringArrayExtra(DRM_KEY_REQUEST_PROPERTIES_EXTRA + extrasKeySuffix);
|
||||
boolean drmMultiSession =
|
||||
intent.getBooleanExtra(DRM_MULTI_SESSION_EXTRA + extrasKeySuffix, false);
|
||||
return new DrmInfo(drmScheme, drmLicenseUrl, keyRequestPropertiesArray, drmMultiSession);
|
||||
}
|
||||
|
||||
public final UUID drmScheme;
|
||||
public final String drmLicenseUrl;
|
||||
public final String[] drmKeyRequestProperties;
|
||||
public final boolean drmMultiSession;
|
||||
|
||||
public DrmInfo(
|
||||
UUID drmScheme,
|
||||
String drmLicenseUrl,
|
||||
String[] drmKeyRequestProperties,
|
||||
boolean drmMultiSession) {
|
||||
this.drmScheme = drmScheme;
|
||||
this.drmLicenseUrl = drmLicenseUrl;
|
||||
this.drmKeyRequestProperties = drmKeyRequestProperties;
|
||||
this.drmMultiSession = drmMultiSession;
|
||||
}
|
||||
|
||||
public void addToIntent(Intent intent, String extrasKeySuffix) {
|
||||
Assertions.checkNotNull(intent);
|
||||
intent.putExtra(DRM_SCHEME_EXTRA + extrasKeySuffix, drmScheme.toString());
|
||||
intent.putExtra(DRM_LICENSE_URL_EXTRA + extrasKeySuffix, drmLicenseUrl);
|
||||
intent.putExtra(DRM_KEY_REQUEST_PROPERTIES_EXTRA + extrasKeySuffix, drmKeyRequestProperties);
|
||||
intent.putExtra(DRM_MULTI_SESSION_EXTRA + extrasKeySuffix, drmMultiSession);
|
||||
}
|
||||
}
|
||||
|
||||
public static Sample createFromIntent(Intent intent) {
|
||||
if (ACTION_VIEW_LIST.equals(intent.getAction())) {
|
||||
ArrayList<String> intentUris = new ArrayList<>();
|
||||
int index = 0;
|
||||
while (intent.hasExtra(URI_EXTRA + "_" + index)) {
|
||||
intentUris.add(intent.getStringExtra(URI_EXTRA + "_" + index));
|
||||
index++;
|
||||
}
|
||||
UriSample[] children = new UriSample[intentUris.size()];
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
Uri uri = Uri.parse(intentUris.get(i));
|
||||
children[i] = UriSample.createFromIntent(uri, intent, /* extrasKeySuffix= */ "_" + i);
|
||||
}
|
||||
return new PlaylistSample(/* name= */ null, children);
|
||||
} else {
|
||||
return UriSample.createFromIntent(intent.getData(), intent, /* extrasKeySuffix= */ "");
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable public final String name;
|
||||
|
||||
public Sample(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public abstract void addToIntent(Intent intent);
|
||||
}
|
||||
|
|
@ -38,6 +38,9 @@ import android.widget.TextView;
|
|||
import android.widget.Toast;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.RenderersFactory;
|
||||
import com.google.android.exoplayer2.demo.Sample.DrmInfo;
|
||||
import com.google.android.exoplayer2.demo.Sample.PlaylistSample;
|
||||
import com.google.android.exoplayer2.demo.Sample.UriSample;
|
||||
import com.google.android.exoplayer2.offline.DownloadService;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSourceInputStream;
|
||||
|
|
@ -161,13 +164,17 @@ public class SampleChooserActivity extends AppCompatActivity
|
|||
public boolean onChildClick(
|
||||
ExpandableListView parent, View view, int groupPosition, int childPosition, long id) {
|
||||
Sample sample = (Sample) view.getTag();
|
||||
startActivity(
|
||||
sample.buildIntent(
|
||||
/* context= */ this,
|
||||
isNonNullAndChecked(preferExtensionDecodersMenuItem),
|
||||
isNonNullAndChecked(randomAbrMenuItem)
|
||||
? PlayerActivity.ABR_ALGORITHM_RANDOM
|
||||
: PlayerActivity.ABR_ALGORITHM_DEFAULT));
|
||||
Intent intent = new Intent(this, PlayerActivity.class);
|
||||
intent.putExtra(
|
||||
PlayerActivity.PREFER_EXTENSION_DECODERS_EXTRA,
|
||||
isNonNullAndChecked(preferExtensionDecodersMenuItem));
|
||||
String abrAlgorithm =
|
||||
isNonNullAndChecked(randomAbrMenuItem)
|
||||
? PlayerActivity.ABR_ALGORITHM_RANDOM
|
||||
: PlayerActivity.ABR_ALGORITHM_DEFAULT;
|
||||
intent.putExtra(PlayerActivity.ABR_ALGORITHM_EXTRA, abrAlgorithm);
|
||||
sample.addToIntent(intent);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -309,17 +316,12 @@ public class SampleChooserActivity extends AppCompatActivity
|
|||
extension = reader.nextString();
|
||||
break;
|
||||
case "drm_scheme":
|
||||
Assertions.checkState(!insidePlaylist, "Invalid attribute on nested item: drm_scheme");
|
||||
drmScheme = reader.nextString();
|
||||
break;
|
||||
case "drm_license_url":
|
||||
Assertions.checkState(!insidePlaylist,
|
||||
"Invalid attribute on nested item: drm_license_url");
|
||||
drmLicenseUrl = reader.nextString();
|
||||
break;
|
||||
case "drm_key_request_properties":
|
||||
Assertions.checkState(!insidePlaylist,
|
||||
"Invalid attribute on nested item: drm_key_request_properties");
|
||||
ArrayList<String> drmKeyRequestPropertiesList = new ArrayList<>();
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
|
|
@ -357,17 +359,21 @@ public class SampleChooserActivity extends AppCompatActivity
|
|||
DrmInfo drmInfo =
|
||||
drmScheme == null
|
||||
? null
|
||||
: new DrmInfo(drmScheme, drmLicenseUrl, drmKeyRequestProperties, drmMultiSession);
|
||||
: new DrmInfo(
|
||||
Util.getDrmUuid(drmScheme),
|
||||
drmLicenseUrl,
|
||||
drmKeyRequestProperties,
|
||||
drmMultiSession);
|
||||
if (playlistSamples != null) {
|
||||
UriSample[] playlistSamplesArray = playlistSamples.toArray(new UriSample[0]);
|
||||
return new PlaylistSample(sampleName, drmInfo, playlistSamplesArray);
|
||||
return new PlaylistSample(sampleName, playlistSamplesArray);
|
||||
} else {
|
||||
return new UriSample(
|
||||
sampleName,
|
||||
drmInfo,
|
||||
uri,
|
||||
extension,
|
||||
adTagUri,
|
||||
adTagUri != null ? Uri.parse(adTagUri) : null,
|
||||
sphericalStereoMode);
|
||||
}
|
||||
}
|
||||
|
|
@ -497,116 +503,4 @@ public class SampleChooserActivity extends AppCompatActivity
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class DrmInfo {
|
||||
public final String drmScheme;
|
||||
public final String drmLicenseUrl;
|
||||
public final String[] drmKeyRequestProperties;
|
||||
public final boolean drmMultiSession;
|
||||
|
||||
public DrmInfo(
|
||||
String drmScheme,
|
||||
String drmLicenseUrl,
|
||||
String[] drmKeyRequestProperties,
|
||||
boolean drmMultiSession) {
|
||||
this.drmScheme = drmScheme;
|
||||
this.drmLicenseUrl = drmLicenseUrl;
|
||||
this.drmKeyRequestProperties = drmKeyRequestProperties;
|
||||
this.drmMultiSession = drmMultiSession;
|
||||
}
|
||||
|
||||
public void updateIntent(Intent intent) {
|
||||
Assertions.checkNotNull(intent);
|
||||
intent.putExtra(PlayerActivity.DRM_SCHEME_EXTRA, drmScheme);
|
||||
intent.putExtra(PlayerActivity.DRM_LICENSE_URL_EXTRA, drmLicenseUrl);
|
||||
intent.putExtra(PlayerActivity.DRM_KEY_REQUEST_PROPERTIES_EXTRA, drmKeyRequestProperties);
|
||||
intent.putExtra(PlayerActivity.DRM_MULTI_SESSION_EXTRA, drmMultiSession);
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class Sample {
|
||||
public final String name;
|
||||
public final DrmInfo drmInfo;
|
||||
|
||||
public Sample(String name, DrmInfo drmInfo) {
|
||||
this.name = name;
|
||||
this.drmInfo = drmInfo;
|
||||
}
|
||||
|
||||
public Intent buildIntent(
|
||||
Context context, boolean preferExtensionDecoders, String abrAlgorithm) {
|
||||
Intent intent = new Intent(context, PlayerActivity.class);
|
||||
intent.putExtra(PlayerActivity.PREFER_EXTENSION_DECODERS_EXTRA, preferExtensionDecoders);
|
||||
intent.putExtra(PlayerActivity.ABR_ALGORITHM_EXTRA, abrAlgorithm);
|
||||
if (drmInfo != null) {
|
||||
drmInfo.updateIntent(intent);
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class UriSample extends Sample {
|
||||
|
||||
public final Uri uri;
|
||||
public final String extension;
|
||||
public final String adTagUri;
|
||||
public final String sphericalStereoMode;
|
||||
|
||||
public UriSample(
|
||||
String name,
|
||||
DrmInfo drmInfo,
|
||||
Uri uri,
|
||||
String extension,
|
||||
String adTagUri,
|
||||
String sphericalStereoMode) {
|
||||
super(name, drmInfo);
|
||||
this.uri = uri;
|
||||
this.extension = extension;
|
||||
this.adTagUri = adTagUri;
|
||||
this.sphericalStereoMode = sphericalStereoMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent buildIntent(
|
||||
Context context, boolean preferExtensionDecoders, String abrAlgorithm) {
|
||||
return super.buildIntent(context, preferExtensionDecoders, abrAlgorithm)
|
||||
.setData(uri)
|
||||
.putExtra(PlayerActivity.EXTENSION_EXTRA, extension)
|
||||
.putExtra(PlayerActivity.AD_TAG_URI_EXTRA, adTagUri)
|
||||
.putExtra(PlayerActivity.SPHERICAL_STEREO_MODE_EXTRA, sphericalStereoMode)
|
||||
.setAction(PlayerActivity.ACTION_VIEW);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class PlaylistSample extends Sample {
|
||||
|
||||
public final UriSample[] children;
|
||||
|
||||
public PlaylistSample(
|
||||
String name,
|
||||
DrmInfo drmInfo,
|
||||
UriSample... children) {
|
||||
super(name, drmInfo);
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent buildIntent(
|
||||
Context context, boolean preferExtensionDecoders, String abrAlgorithm) {
|
||||
String[] uris = new String[children.length];
|
||||
String[] extensions = new String[children.length];
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
uris[i] = children[i].uri.toString();
|
||||
extensions[i] = children[i].extension;
|
||||
}
|
||||
return super.buildIntent(context, preferExtensionDecoders, abrAlgorithm)
|
||||
.putExtra(PlayerActivity.URI_LIST_EXTRA, uris)
|
||||
.putExtra(PlayerActivity.EXTENSION_LIST_EXTRA, extensions)
|
||||
.setAction(PlayerActivity.ACTION_VIEW_LIST);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@
|
|||
|
||||
<string name="ima_not_loaded">Playing sample without ads, as the IMA extension was not loaded</string>
|
||||
|
||||
<string name="unsupported_ads_in_concatenation">Playing sample without ads, as ads are not supported in concatenations</string>
|
||||
|
||||
<string name="download_start_error">Failed to start download</string>
|
||||
|
||||
<string name="download_playlist_unsupported">This demo app does not support downloading playlists</string>
|
||||
|
|
|
|||
Loading…
Reference in a new issue