Add ability to play filtered manifests in PlayerActivity
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=189796293
This commit is contained in:
parent
dfa31f02e3
commit
764d18f68f
@ -21,9 +21,9 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -58,9 +58,14 @@ import com.google.android.exoplayer2.source.ads.AdsLoader;
|
||||
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
|
||||
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
||||
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.FilteringDashManifestParser;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
|
||||
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.FilteringHlsPlaylistParser;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.FilteringSsManifestParser;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.TrackKey;
|
||||
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
|
||||
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
|
||||
@ -73,11 +78,13 @@ import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||
import com.google.android.exoplayer2.util.EventLogger;
|
||||
import com.google.android.exoplayer2.util.ParcelableArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.net.CookieHandler;
|
||||
import java.net.CookieManager;
|
||||
import java.net.CookiePolicy;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/** An activity that plays media using {@link SimpleExoPlayer}. */
|
||||
@ -92,11 +99,14 @@ public class PlayerActivity extends Activity
|
||||
|
||||
public static final String ACTION_VIEW = "com.google.android.exoplayer.demo.action.VIEW";
|
||||
public static final String EXTENSION_EXTRA = "extension";
|
||||
public static final String MANIFEST_FILTER_EXTRA = "manifest_filter";
|
||||
|
||||
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 MANIFEST_FILTER_LIST_EXTRA = "manifest_filter_list";
|
||||
|
||||
public static final String AD_TAG_URI_EXTRA = "ad_tag_uri";
|
||||
|
||||
// For backwards compatibility.
|
||||
@ -318,9 +328,11 @@ public class PlayerActivity extends Activity
|
||||
String action = intent.getAction();
|
||||
Uri[] uris;
|
||||
String[] extensions;
|
||||
Parcelable[] manifestFilters;
|
||||
if (ACTION_VIEW.equals(action)) {
|
||||
uris = new Uri[] {intent.getData()};
|
||||
extensions = new String[] {intent.getStringExtra(EXTENSION_EXTRA)};
|
||||
manifestFilters = new Parcelable[] {intent.getParcelableExtra(MANIFEST_FILTER_EXTRA)};
|
||||
} else if (ACTION_VIEW_LIST.equals(action)) {
|
||||
String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
|
||||
uris = new Uri[uriStrings.length];
|
||||
@ -331,6 +343,7 @@ public class PlayerActivity extends Activity
|
||||
if (extensions == null) {
|
||||
extensions = new String[uriStrings.length];
|
||||
}
|
||||
manifestFilters = intent.getParcelableArrayExtra(MANIFEST_FILTER_LIST_EXTRA);
|
||||
} else {
|
||||
showToast(getString(R.string.unexpected_intent_action, action));
|
||||
return;
|
||||
@ -341,7 +354,9 @@ public class PlayerActivity extends Activity
|
||||
}
|
||||
MediaSource[] mediaSources = new MediaSource[uris.length];
|
||||
for (int i = 0; i < uris.length; i++) {
|
||||
mediaSources[i] = buildMediaSource(uris[i], extensions[i]);
|
||||
ParcelableArray<?> manifestFilter = (ParcelableArray<?>) manifestFilters[i];
|
||||
List<?> filter = manifestFilter != null ? manifestFilter.asList() : null;
|
||||
mediaSources[i] = buildMediaSource(uris[i], extensions[i], filter);
|
||||
}
|
||||
mediaSource =
|
||||
mediaSources.length == 1 ? mediaSources[0] : new ConcatenatingMediaSource(mediaSources);
|
||||
@ -372,22 +387,32 @@ public class PlayerActivity extends Activity
|
||||
updateButtonVisibilities();
|
||||
}
|
||||
|
||||
private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
|
||||
@ContentType int type = TextUtils.isEmpty(overrideExtension) ? Util.inferContentType(uri)
|
||||
: Util.inferContentType("." + overrideExtension);
|
||||
private MediaSource buildMediaSource(Uri uri) {
|
||||
return buildMediaSource(uri, null, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private MediaSource buildMediaSource(
|
||||
Uri uri, @Nullable String overrideExtension, @Nullable List<?> manifestFilter) {
|
||||
@ContentType int type = Util.inferContentType(uri, overrideExtension);
|
||||
switch (type) {
|
||||
case C.TYPE_DASH:
|
||||
return new DashMediaSource.Factory(
|
||||
new DefaultDashChunkSource.Factory(mediaDataSourceFactory),
|
||||
buildDataSourceFactory(false))
|
||||
.setManifestParser(
|
||||
new FilteringDashManifestParser((List<RepresentationKey>) manifestFilter))
|
||||
.createMediaSource(uri);
|
||||
case C.TYPE_SS:
|
||||
return new SsMediaSource.Factory(
|
||||
new DefaultSsChunkSource.Factory(mediaDataSourceFactory),
|
||||
buildDataSourceFactory(false))
|
||||
.setManifestParser(new FilteringSsManifestParser((List<TrackKey>) manifestFilter))
|
||||
.createMediaSource(uri);
|
||||
case C.TYPE_HLS:
|
||||
return new HlsMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
|
||||
return new HlsMediaSource.Factory(mediaDataSourceFactory)
|
||||
.setPlaylistParser(new FilteringHlsPlaylistParser((List<String>) manifestFilter))
|
||||
.createMediaSource(uri);
|
||||
case C.TYPE_OTHER:
|
||||
return new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
|
||||
default: {
|
||||
@ -483,7 +508,7 @@ public class PlayerActivity extends Activity
|
||||
new AdsMediaSource.MediaSourceFactory() {
|
||||
@Override
|
||||
public MediaSource createMediaSource(Uri uri) {
|
||||
return PlayerActivity.this.buildMediaSource(uri, /* overrideExtension= */ null);
|
||||
return PlayerActivity.this.buildMediaSource(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.util;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** A {@link android.os.Parcelable} wrapper around an array. */
|
||||
public final class ParcelableArray<V extends Parcelable> implements Parcelable {
|
||||
|
||||
@SuppressWarnings("rawtypes") // V cannot be obtained from static context
|
||||
public static final Creator<ParcelableArray> CREATOR =
|
||||
new Creator<ParcelableArray>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ParcelableArray createFromParcel(Parcel in) {
|
||||
ClassLoader classLoader = ParcelableArray.class.getClassLoader();
|
||||
Parcelable[] elements = in.readParcelableArray(classLoader);
|
||||
return new ParcelableArray(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableArray[] newArray(int size) {
|
||||
return new ParcelableArray[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final V[] elements;
|
||||
|
||||
public ParcelableArray(V[] elements) {
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
/** Returns an unmodifiable list containing all elements. */
|
||||
public List<V> asList() {
|
||||
return Collections.unmodifiableList(Arrays.asList(elements));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeParcelableArray(elements, flags);
|
||||
}
|
||||
}
|
@ -1093,6 +1093,20 @@ public final class Util {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a best guess to infer the type from a {@link Uri}.
|
||||
*
|
||||
* @param uri The {@link Uri}.
|
||||
* @param overrideExtension If not null, used to infer the type.
|
||||
* @return The content type.
|
||||
*/
|
||||
@C.ContentType
|
||||
public static int inferContentType(Uri uri, String overrideExtension) {
|
||||
return TextUtils.isEmpty(overrideExtension)
|
||||
? inferContentType(uri)
|
||||
: inferContentType("." + overrideExtension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a best guess to infer the type from a {@link Uri}.
|
||||
*
|
||||
|
@ -16,10 +16,11 @@
|
||||
package com.google.android.exoplayer2.source.dash.manifest;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable.Parser;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A parser of media presentation description files which includes only the representations
|
||||
@ -28,16 +29,20 @@ import java.util.ArrayList;
|
||||
public final class FilteringDashManifestParser implements Parser<DashManifest> {
|
||||
|
||||
private final DashManifestParser dashManifestParser;
|
||||
private final ArrayList<RepresentationKey> filter;
|
||||
private final List<RepresentationKey> filter;
|
||||
|
||||
/** @param filter The representation keys that should be retained in the parsed manifests. */
|
||||
public FilteringDashManifestParser(ArrayList<RepresentationKey> filter) {
|
||||
/**
|
||||
* @param filter The representation keys that should be retained in the parsed manifests. If null,
|
||||
* all representation are retained.
|
||||
*/
|
||||
public FilteringDashManifestParser(@Nullable List<RepresentationKey> filter) {
|
||||
this.dashManifestParser = new DashManifestParser();
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DashManifest parse(Uri uri, InputStream inputStream) throws IOException {
|
||||
return dashManifestParser.parse(uri, inputStream).copy(filter);
|
||||
DashManifest manifest = dashManifestParser.parse(uri, inputStream);
|
||||
return filter != null ? manifest.copy(filter) : manifest;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.source.hls.playlist;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable.Parser;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -27,8 +28,11 @@ public final class FilteringHlsPlaylistParser implements Parser<HlsPlaylist> {
|
||||
private final HlsPlaylistParser hlsPlaylistParser;
|
||||
private final List<String> filter;
|
||||
|
||||
/** @param filter The urls to renditions that should be retained in the parsed playlists. */
|
||||
public FilteringHlsPlaylistParser(List<String> filter) {
|
||||
/**
|
||||
* @param filter The urls to renditions that should be retained in the parsed playlists. If null,
|
||||
* all renditions are retained.
|
||||
*/
|
||||
public FilteringHlsPlaylistParser(@Nullable List<String> filter) {
|
||||
this.hlsPlaylistParser = new HlsPlaylistParser();
|
||||
this.filter = filter;
|
||||
}
|
||||
@ -37,7 +41,8 @@ public final class FilteringHlsPlaylistParser implements Parser<HlsPlaylist> {
|
||||
public HlsPlaylist parse(Uri uri, InputStream inputStream) throws IOException {
|
||||
HlsPlaylist hlsPlaylist = hlsPlaylistParser.parse(uri, inputStream);
|
||||
if (hlsPlaylist instanceof HlsMasterPlaylist) {
|
||||
return ((HlsMasterPlaylist) hlsPlaylist).copy(filter);
|
||||
HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) hlsPlaylist;
|
||||
return filter != null ? masterPlaylist.copy(filter) : masterPlaylist;
|
||||
} else {
|
||||
return hlsPlaylist;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
package com.google.android.exoplayer2.source.smoothstreaming.manifest;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable.Parser;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -29,14 +30,18 @@ public final class FilteringSsManifestParser implements Parser<SsManifest> {
|
||||
private final SsManifestParser ssManifestParser;
|
||||
private final List<TrackKey> filter;
|
||||
|
||||
/** @param filter The track keys that should be retained in the parsed manifests. */
|
||||
public FilteringSsManifestParser(List<TrackKey> filter) {
|
||||
/**
|
||||
* @param filter The track keys that should be retained in the parsed manifests. If null, all
|
||||
* tracks are retained.
|
||||
*/
|
||||
public FilteringSsManifestParser(@Nullable List<TrackKey> filter) {
|
||||
this.ssManifestParser = new SsManifestParser();
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SsManifest parse(Uri uri, InputStream inputStream) throws IOException {
|
||||
return ssManifestParser.parse(uri, inputStream).copy(filter);
|
||||
SsManifest manifest = ssManifestParser.parse(uri, inputStream);
|
||||
return filter != null ? manifest.copy(filter) : manifest;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user