Commit 628234fd by bachinger Committed by Ian Baker

Read media items from intent

PiperOrigin-RevId: 307442976
parent 6a36574a
/*
* Copyright 2020 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.util.Assertions.checkNotNull;
import android.content.Intent;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.offline.DownloadRequest;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
/** Util to read from an intent. */
public class IntentUtil {
// 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";
// 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";
// 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 IS_LIVE_EXTRA = "is_live";
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_SESSION_FOR_CLEAR_TYPES_EXTRA = "drm_session_for_clear_types";
public static final String DRM_MULTI_SESSION_EXTRA = "drm_multi_session";
public static final String AD_TAG_URI_EXTRA = "ad_tag_uri";
public static final String SUBTITLE_URI_EXTRA = "subtitle_uri";
public static final String SUBTITLE_MIME_TYPE_EXTRA = "subtitle_mime_type";
public static final String SUBTITLE_LANGUAGE_EXTRA = "subtitle_language";
// For backwards compatibility only.
public static final String DRM_SCHEME_UUID_EXTRA = "drm_scheme_uuid";
public static final String PREFER_EXTENSION_DECODERS_EXTRA = "prefer_extension_decoders";
public static final String TUNNELING_EXTRA = "tunneling";
/** Creates a list of {@link MediaItem media items} from an {@link Intent}. */
public static List<MediaItem> createMediaItemsFromIntent(
Intent intent, DownloadTracker downloadTracker) {
List<MediaItem> mediaItems = new ArrayList<>();
if (ACTION_VIEW_LIST.equals(intent.getAction())) {
int index = 0;
while (intent.hasExtra(URI_EXTRA + "_" + index)) {
Uri uri = Uri.parse(intent.getStringExtra(URI_EXTRA + "_" + index));
mediaItems.add(
createMediaItemFromIntent(
uri,
intent,
/* extrasKeySuffix= */ "_" + index,
downloadTracker.getDownloadRequest(uri)));
index++;
}
} else {
Uri uri = intent.getData();
mediaItems.add(
createMediaItemFromIntent(
uri, intent, /* extrasKeySuffix= */ "", downloadTracker.getDownloadRequest(uri)));
}
return mediaItems;
}
private static MediaItem createMediaItemFromIntent(
Uri uri, Intent intent, String extrasKeySuffix, @Nullable DownloadRequest downloadRequest) {
String extension = intent.getStringExtra(EXTENSION_EXTRA + extrasKeySuffix);
MediaItem.Builder builder =
new MediaItem.Builder()
.setSourceUri(uri)
.setStreamKeys(downloadRequest != null ? downloadRequest.streamKeys : null)
.setCustomCacheKey(downloadRequest != null ? downloadRequest.customCacheKey : null)
.setMimeType(inferAdaptiveStreamMimeType(uri, extension))
.setAdTagUri(intent.getStringExtra(AD_TAG_URI_EXTRA + extrasKeySuffix))
.setSubtitles(createSubtitlesFromIntent(intent, extrasKeySuffix));
return populateDrmPropertiesFromIntent(builder, intent, extrasKeySuffix).build();
}
private static List<MediaItem.Subtitle> createSubtitlesFromIntent(
Intent intent, String extrasKeySuffix) {
if (!intent.hasExtra(SUBTITLE_URI_EXTRA + extrasKeySuffix)) {
return Collections.emptyList();
}
return Collections.singletonList(
new MediaItem.Subtitle(
Uri.parse(intent.getStringExtra(SUBTITLE_URI_EXTRA + extrasKeySuffix)),
checkNotNull(intent.getStringExtra(SUBTITLE_MIME_TYPE_EXTRA + extrasKeySuffix)),
intent.getStringExtra(SUBTITLE_LANGUAGE_EXTRA + extrasKeySuffix),
C.SELECTION_FLAG_DEFAULT));
}
private static MediaItem.Builder populateDrmPropertiesFromIntent(
MediaItem.Builder builder, 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 builder;
}
String drmSchemeExtra =
intent.hasExtra(schemeKey)
? intent.getStringExtra(schemeKey)
: intent.getStringExtra(schemeUuidKey);
String[] drmSessionForClearTypesExtra =
intent.getStringArrayExtra(DRM_SESSION_FOR_CLEAR_TYPES_EXTRA + extrasKeySuffix);
Map<String, String> headers = new HashMap<>();
String[] keyRequestPropertiesArray =
intent.getStringArrayExtra(DRM_KEY_REQUEST_PROPERTIES_EXTRA + extrasKeySuffix);
if (keyRequestPropertiesArray != null) {
for (int i = 0; i < keyRequestPropertiesArray.length; i += 2) {
headers.put(keyRequestPropertiesArray[i], keyRequestPropertiesArray[i + 1]);
}
}
builder
.setDrmUuid(Util.getDrmUuid(Util.castNonNull(drmSchemeExtra)))
.setDrmLicenseUri(intent.getStringExtra(DRM_LICENSE_URL_EXTRA + extrasKeySuffix))
.setDrmSessionForClearTypes(toTrackTypeList(drmSessionForClearTypesExtra))
.setDrmMultiSession(
intent.getBooleanExtra(DRM_MULTI_SESSION_EXTRA + extrasKeySuffix, false))
.setDrmLicenseRequestHeaders(headers);
return builder;
}
private static List<Integer> toTrackTypeList(@Nullable String[] trackTypeStringsArray) {
if (trackTypeStringsArray == null) {
return Collections.emptyList();
}
HashSet<Integer> trackTypes = new HashSet<>();
for (String trackTypeString : trackTypeStringsArray) {
switch (Util.toLowerInvariant(trackTypeString)) {
case "audio":
trackTypes.add(C.TRACK_TYPE_AUDIO);
break;
case "video":
trackTypes.add(C.TRACK_TYPE_VIDEO);
break;
default:
throw new IllegalArgumentException("Invalid track type: " + trackTypeString);
}
}
return new ArrayList<>(trackTypes);
}
@Nullable
private static String inferAdaptiveStreamMimeType(Uri uri, @Nullable String extension) {
@C.ContentType int contentType = Util.inferContentType(uri, extension);
switch (contentType) {
case C.TYPE_DASH:
return MimeTypes.APPLICATION_MPD;
case C.TYPE_HLS:
return MimeTypes.APPLICATION_M3U8;
case C.TYPE_SS:
return MimeTypes.APPLICATION_SS;
case C.TYPE_OTHER:
default:
return null;
}
}
}
......@@ -39,10 +39,8 @@ import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.demo.Sample.UriSample;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.offline.DownloadRequest;
import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.TrackGroupArray;
......@@ -66,7 +64,6 @@ import java.lang.reflect.Constructor;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
......@@ -74,45 +71,6 @@ import java.util.List;
public class PlayerActivity extends AppCompatActivity
implements OnClickListener, PlaybackPreparer, PlayerControlView.VisibilityListener {
// 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 IS_LIVE_EXTRA = "is_live";
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_SESSION_FOR_CLEAR_TYPES_EXTRA = "drm_session_for_clear_types";
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 TUNNELING_EXTRA = "tunneling";
public static final String AD_TAG_URI_EXTRA = "ad_tag_uri";
public static final String SUBTITLE_URI_EXTRA = "subtitle_uri";
public static final String SUBTITLE_MIME_TYPE_EXTRA = "subtitle_mime_type";
public static final String SUBTITLE_LANGUAGE_EXTRA = "subtitle_language";
// For backwards compatibility only.
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";
......@@ -154,7 +112,7 @@ public class PlayerActivity extends AppCompatActivity
@Override
public void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
String sphericalStereoMode = intent.getStringExtra(SPHERICAL_STEREO_MODE_EXTRA);
String sphericalStereoMode = intent.getStringExtra(IntentUtil.SPHERICAL_STEREO_MODE_EXTRA);
if (sphericalStereoMode != null) {
setTheme(R.style.PlayerTheme_Spherical);
}
......@@ -176,11 +134,11 @@ public class PlayerActivity extends AppCompatActivity
playerView.requestFocus();
if (sphericalStereoMode != null) {
int stereoMode;
if (SPHERICAL_STEREO_MODE_MONO.equals(sphericalStereoMode)) {
if (IntentUtil.SPHERICAL_STEREO_MODE_MONO.equals(sphericalStereoMode)) {
stereoMode = C.STEREO_MODE_MONO;
} else if (SPHERICAL_STEREO_MODE_TOP_BOTTOM.equals(sphericalStereoMode)) {
} else if (IntentUtil.SPHERICAL_STEREO_MODE_TOP_BOTTOM.equals(sphericalStereoMode)) {
stereoMode = C.STEREO_MODE_TOP_BOTTOM;
} else if (SPHERICAL_STEREO_MODE_LEFT_RIGHT.equals(sphericalStereoMode)) {
} else if (IntentUtil.SPHERICAL_STEREO_MODE_LEFT_RIGHT.equals(sphericalStereoMode)) {
stereoMode = C.STEREO_MODE_LEFT_RIGHT;
} else {
showToast(R.string.error_unrecognized_stereo_mode);
......@@ -198,7 +156,7 @@ public class PlayerActivity extends AppCompatActivity
} else {
DefaultTrackSelector.ParametersBuilder builder =
new DefaultTrackSelector.ParametersBuilder(/* context= */ this);
boolean tunneling = intent.getBooleanExtra(TUNNELING_EXTRA, false);
boolean tunneling = intent.getBooleanExtra(IntentUtil.TUNNELING_EXTRA, false);
if (Util.SDK_INT >= 21 && tunneling) {
builder.setTunnelingAudioSessionId(C.generateAudioSessionIdV21(/* context= */ this));
}
......@@ -337,15 +295,17 @@ public class PlayerActivity extends AppCompatActivity
private void initializePlayer() {
if (player == null) {
Intent intent = getIntent();
mediaItems = createMediaItems(intent);
if (mediaItems.isEmpty()) {
return;
}
TrackSelection.Factory trackSelectionFactory;
String abrAlgorithm = intent.getStringExtra(ABR_ALGORITHM_EXTRA);
if (abrAlgorithm == null || ABR_ALGORITHM_DEFAULT.equals(abrAlgorithm)) {
String abrAlgorithm = intent.getStringExtra(IntentUtil.ABR_ALGORITHM_EXTRA);
if (abrAlgorithm == null || IntentUtil.ABR_ALGORITHM_DEFAULT.equals(abrAlgorithm)) {
trackSelectionFactory = new AdaptiveTrackSelection.Factory();
} else if (ABR_ALGORITHM_RANDOM.equals(abrAlgorithm)) {
} else if (IntentUtil.ABR_ALGORITHM_RANDOM.equals(abrAlgorithm)) {
trackSelectionFactory = new RandomTrackSelection.Factory();
} else {
showToast(R.string.error_unrecognized_abr_algorithm);
......@@ -354,7 +314,7 @@ public class PlayerActivity extends AppCompatActivity
}
boolean preferExtensionDecoders =
intent.getBooleanExtra(PREFER_EXTENSION_DECODERS_EXTRA, false);
intent.getBooleanExtra(IntentUtil.PREFER_EXTENSION_DECODERS_EXTRA, false);
RenderersFactory renderersFactory =
((DemoApplication) getApplication()).buildRenderersFactory(preferExtensionDecoders);
......@@ -389,35 +349,19 @@ public class PlayerActivity extends AppCompatActivity
private List<MediaItem> createMediaItems(Intent intent) {
String action = intent.getAction();
boolean actionIsListView = ACTION_VIEW_LIST.equals(action);
if (!actionIsListView && !ACTION_VIEW.equals(action)) {
boolean actionIsListView = IntentUtil.ACTION_VIEW_LIST.equals(action);
if (!actionIsListView && !IntentUtil.ACTION_VIEW.equals(action)) {
showToast(getString(R.string.unexpected_intent_action, action));
finish();
return Collections.emptyList();
}
Sample intentAsSample = Sample.createFromIntent(intent);
UriSample[] samples =
intentAsSample instanceof Sample.PlaylistSample
? ((Sample.PlaylistSample) intentAsSample).children
: new UriSample[] {(UriSample) intentAsSample};
List<MediaItem> mediaItems = new ArrayList<>();
List<MediaItem> mediaItems =
IntentUtil.createMediaItemsFromIntent(
intent, ((DemoApplication) getApplication()).getDownloadTracker());
boolean hasAds = false;
for (UriSample sample : samples) {
MediaItem mediaItem = sample.toMediaItem();
DownloadRequest downloadRequest =
((DemoApplication) getApplication())
.getDownloadTracker()
.getDownloadRequest(Assertions.checkNotNull(mediaItem.playbackProperties).sourceUri);
if (downloadRequest != null) {
mediaItem =
mediaItem
.buildUpon()
.setStreamKeys(downloadRequest.streamKeys)
.setCustomCacheKey(downloadRequest.customCacheKey)
.build();
}
for (int i = 0; i < mediaItems.size(); i++) {
MediaItem mediaItem = mediaItems.get(i);
if (!Util.checkCleartextTrafficPermitted(mediaItem)) {
showToast(R.string.error_cleartext_not_permitted);
......@@ -442,7 +386,6 @@ public class PlayerActivity extends AppCompatActivity
}
}
hasAds |= mediaItem.playbackProperties.adTagUri != null;
mediaItems.add(mediaItem);
}
if (!hasAds) {
releaseAdsLoader();
......
......@@ -230,14 +230,14 @@ public class SampleChooserActivity extends AppCompatActivity
Sample sample = (Sample) view.getTag();
Intent intent = new Intent(this, PlayerActivity.class);
intent.putExtra(
PlayerActivity.PREFER_EXTENSION_DECODERS_EXTRA,
IntentUtil.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);
intent.putExtra(PlayerActivity.TUNNELING_EXTRA, isNonNullAndChecked(tunnelingMenuItem));
? IntentUtil.ABR_ALGORITHM_RANDOM
: IntentUtil.ABR_ALGORITHM_DEFAULT;
intent.putExtra(IntentUtil.ABR_ALGORITHM_EXTRA, abrAlgorithm);
intent.putExtra(IntentUtil.TUNNELING_EXTRA, isNonNullAndChecked(tunnelingMenuItem));
sample.addToIntent(intent);
startActivity(intent);
return true;
......
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