Use parcelable keys for HLS downloads to remove special casing
This removes the need for separate String/Parcelable filter paths in the demo app. Hopefully this is a temporary measure as we work toward using track groups + consistent keys for all media types. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=194065499
This commit is contained in:
parent
874dc202f8
commit
1f3adacac3
@ -41,6 +41,7 @@ import com.google.android.exoplayer2.source.dash.offline.DashDownloadAction;
|
|||||||
import com.google.android.exoplayer2.source.dash.offline.DashDownloader;
|
import com.google.android.exoplayer2.source.dash.offline.DashDownloader;
|
||||||
import com.google.android.exoplayer2.source.hls.offline.HlsDownloadAction;
|
import com.google.android.exoplayer2.source.hls.offline.HlsDownloadAction;
|
||||||
import com.google.android.exoplayer2.source.hls.offline.HlsDownloader;
|
import com.google.android.exoplayer2.source.hls.offline.HlsDownloader;
|
||||||
|
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
|
||||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.TrackKey;
|
import com.google.android.exoplayer2.source.smoothstreaming.manifest.TrackKey;
|
||||||
import com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloadAction;
|
import com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloadAction;
|
||||||
import com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader;
|
import com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader;
|
||||||
@ -63,7 +64,6 @@ public class DownloadActivity extends Activity {
|
|||||||
private AsyncTask manifestDownloaderTask;
|
private AsyncTask manifestDownloaderTask;
|
||||||
|
|
||||||
private DownloadUtilMethods downloadUtilMethods;
|
private DownloadUtilMethods downloadUtilMethods;
|
||||||
|
|
||||||
private ListView representationList;
|
private ListView representationList;
|
||||||
private ArrayAdapter<RepresentationItem> arrayAdapter;
|
private ArrayAdapter<RepresentationItem> arrayAdapter;
|
||||||
|
|
||||||
@ -162,15 +162,11 @@ public class DownloadActivity extends Activity {
|
|||||||
ArrayList<Object> selectedRepresentationKeys = getSelectedRepresentationKeys();
|
ArrayList<Object> selectedRepresentationKeys = getSelectedRepresentationKeys();
|
||||||
if (selectedRepresentationKeys.isEmpty()) {
|
if (selectedRepresentationKeys.isEmpty()) {
|
||||||
playerIntent.removeExtra(PlayerActivity.MANIFEST_FILTER_EXTRA);
|
playerIntent.removeExtra(PlayerActivity.MANIFEST_FILTER_EXTRA);
|
||||||
} else if (selectedRepresentationKeys.get(0) instanceof Parcelable) {
|
} else {
|
||||||
Parcelable[] parcelables = new Parcelable[selectedRepresentationKeys.size()];
|
Parcelable[] parcelables = new Parcelable[selectedRepresentationKeys.size()];
|
||||||
selectedRepresentationKeys.toArray(parcelables);
|
selectedRepresentationKeys.toArray(parcelables);
|
||||||
playerIntent.putExtra(
|
playerIntent.putExtra(
|
||||||
PlayerActivity.MANIFEST_FILTER_EXTRA, new ParcelableArray<>(parcelables));
|
PlayerActivity.MANIFEST_FILTER_EXTRA, new ParcelableArray<>(parcelables));
|
||||||
} else {
|
|
||||||
String[] strings = new String[selectedRepresentationKeys.size()];
|
|
||||||
selectedRepresentationKeys.toArray(strings);
|
|
||||||
playerIntent.putExtra(PlayerActivity.MANIFEST_FILTER_EXTRA, strings);
|
|
||||||
}
|
}
|
||||||
startActivity(playerIntent);
|
startActivity(playerIntent);
|
||||||
}
|
}
|
||||||
@ -198,11 +194,11 @@ public class DownloadActivity extends Activity {
|
|||||||
|
|
||||||
private static final class RepresentationItem {
|
private static final class RepresentationItem {
|
||||||
|
|
||||||
public final Object key;
|
public final Parcelable key;
|
||||||
public final String title;
|
public final String title;
|
||||||
public final int percentDownloaded;
|
public final int percentDownloaded;
|
||||||
|
|
||||||
public RepresentationItem(Object key, String title, float percentDownloaded) {
|
public RepresentationItem(Parcelable key, String title, float percentDownloaded) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.percentDownloaded = (int) percentDownloaded;
|
this.percentDownloaded = (int) percentDownloaded;
|
||||||
@ -317,14 +313,14 @@ public class DownloadActivity extends Activity {
|
|||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
HlsDownloader downloader = new HlsDownloader(manifestUri, constructorHelper);
|
HlsDownloader downloader = new HlsDownloader(manifestUri, constructorHelper);
|
||||||
ArrayList<RepresentationItem> items = new ArrayList<>();
|
ArrayList<RepresentationItem> items = new ArrayList<>();
|
||||||
for (String key : downloader.getAllRepresentationKeys()) {
|
for (RenditionKey key : downloader.getAllRepresentationKeys()) {
|
||||||
downloader.selectRepresentations(new String[] {key});
|
downloader.selectRepresentations(new RenditionKey[] {key});
|
||||||
try {
|
try {
|
||||||
downloader.init();
|
downloader.init();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
items.add(new RepresentationItem(key, key, downloader.getDownloadPercentage()));
|
items.add(new RepresentationItem(key, key.url, downloader.getDownloadPercentage()));
|
||||||
}
|
}
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
@ -332,7 +328,7 @@ public class DownloadActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public DownloadAction getDownloadAction(
|
public DownloadAction getDownloadAction(
|
||||||
String sampleName, ArrayList<Object> representationKeys) {
|
String sampleName, ArrayList<Object> representationKeys) {
|
||||||
String[] keys = representationKeys.toArray(new String[representationKeys.size()]);
|
RenditionKey[] keys = representationKeys.toArray(new RenditionKey[representationKeys.size()]);
|
||||||
return new HlsDownloadAction(manifestUri, false, sampleName, keys);
|
return new HlsDownloadAction(manifestUri, false, sampleName, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.os.Parcelable;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -60,6 +61,7 @@ import com.google.android.exoplayer2.source.dash.manifest.FilteringDashManifestP
|
|||||||
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
|
import com.google.android.exoplayer2.source.dash.manifest.RepresentationKey;
|
||||||
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
|
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.FilteringHlsPlaylistParser;
|
import com.google.android.exoplayer2.source.hls.playlist.FilteringHlsPlaylistParser;
|
||||||
|
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
|
||||||
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
|
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
|
||||||
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
|
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.FilteringSsManifestParser;
|
||||||
@ -83,7 +85,6 @@ import java.lang.reflect.Constructor;
|
|||||||
import java.net.CookieHandler;
|
import java.net.CookieHandler;
|
||||||
import java.net.CookieManager;
|
import java.net.CookieManager;
|
||||||
import java.net.CookiePolicy;
|
import java.net.CookiePolicy;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -300,15 +301,11 @@ public class PlayerActivity extends Activity
|
|||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
Uri[] uris;
|
Uri[] uris;
|
||||||
String[] extensions;
|
String[] extensions;
|
||||||
Object[] manifestFilters;
|
Parcelable[] manifestFilters;
|
||||||
if (ACTION_VIEW.equals(action)) {
|
if (ACTION_VIEW.equals(action)) {
|
||||||
uris = new Uri[] {intent.getData()};
|
uris = new Uri[] {intent.getData()};
|
||||||
extensions = new String[] {intent.getStringExtra(EXTENSION_EXTRA)};
|
extensions = new String[] {intent.getStringExtra(EXTENSION_EXTRA)};
|
||||||
Object filter = intent.getParcelableExtra(MANIFEST_FILTER_EXTRA);
|
manifestFilters = new Parcelable[] {intent.getParcelableExtra(MANIFEST_FILTER_EXTRA)};
|
||||||
if (filter == null) {
|
|
||||||
filter = intent.getStringArrayExtra(MANIFEST_FILTER_EXTRA);
|
|
||||||
}
|
|
||||||
manifestFilters = new Object[] {filter};
|
|
||||||
} else if (ACTION_VIEW_LIST.equals(action)) {
|
} else if (ACTION_VIEW_LIST.equals(action)) {
|
||||||
String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
|
String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
|
||||||
uris = new Uri[uriStrings.length];
|
uris = new Uri[uriStrings.length];
|
||||||
@ -321,7 +318,7 @@ public class PlayerActivity extends Activity
|
|||||||
}
|
}
|
||||||
manifestFilters = intent.getParcelableArrayExtra(MANIFEST_FILTER_LIST_EXTRA);
|
manifestFilters = intent.getParcelableArrayExtra(MANIFEST_FILTER_LIST_EXTRA);
|
||||||
if (manifestFilters == null) {
|
if (manifestFilters == null) {
|
||||||
manifestFilters = new Object[uriStrings.length];
|
manifestFilters = new Parcelable[uriStrings.length];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showToast(getString(R.string.unexpected_intent_action, action));
|
showToast(getString(R.string.unexpected_intent_action, action));
|
||||||
@ -414,15 +411,8 @@ public class PlayerActivity extends Activity
|
|||||||
|
|
||||||
MediaSource[] mediaSources = new MediaSource[uris.length];
|
MediaSource[] mediaSources = new MediaSource[uris.length];
|
||||||
for (int i = 0; i < uris.length; i++) {
|
for (int i = 0; i < uris.length; i++) {
|
||||||
List<?> filter;
|
ParcelableArray<?> manifestFilter = (ParcelableArray<?>) manifestFilters[i];
|
||||||
Object manifestFilter = manifestFilters[i];
|
List<?> filter = manifestFilter != null ? manifestFilter.asList() : null;
|
||||||
if (manifestFilter instanceof ParcelableArray<?>) {
|
|
||||||
filter = ((ParcelableArray<?>) manifestFilter).asList();
|
|
||||||
} else if (manifestFilter instanceof String[]) {
|
|
||||||
filter = Arrays.asList((String[]) manifestFilter);
|
|
||||||
} else {
|
|
||||||
filter = null;
|
|
||||||
}
|
|
||||||
mediaSources[i] = buildMediaSource(uris[i], extensions[i], filter);
|
mediaSources[i] = buildMediaSource(uris[i], extensions[i], filter);
|
||||||
}
|
}
|
||||||
mediaSource =
|
mediaSource =
|
||||||
@ -479,7 +469,7 @@ public class PlayerActivity extends Activity
|
|||||||
.createMediaSource(uri);
|
.createMediaSource(uri);
|
||||||
case C.TYPE_HLS:
|
case C.TYPE_HLS:
|
||||||
return new HlsMediaSource.Factory(mediaDataSourceFactory)
|
return new HlsMediaSource.Factory(mediaDataSourceFactory)
|
||||||
.setPlaylistParser(new FilteringHlsPlaylistParser((List<String>) manifestFilter))
|
.setPlaylistParser(new FilteringHlsPlaylistParser((List<RenditionKey>) manifestFilter))
|
||||||
.createMediaSource(uri);
|
.createMediaSource(uri);
|
||||||
case C.TYPE_OTHER:
|
case C.TYPE_OTHER:
|
||||||
return new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
|
return new ExtractorMediaSource.Factory(mediaDataSourceFactory).createMediaSource(uri);
|
||||||
|
@ -20,15 +20,16 @@ import android.support.annotation.Nullable;
|
|||||||
import com.google.android.exoplayer2.offline.DownloadAction;
|
import com.google.android.exoplayer2.offline.DownloadAction;
|
||||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||||
import com.google.android.exoplayer2.offline.SegmentDownloadAction;
|
import com.google.android.exoplayer2.offline.SegmentDownloadAction;
|
||||||
|
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/** An action to download or remove downloaded HLS streams. */
|
/** An action to download or remove downloaded HLS streams. */
|
||||||
public final class HlsDownloadAction extends SegmentDownloadAction<String> {
|
public final class HlsDownloadAction extends SegmentDownloadAction<RenditionKey> {
|
||||||
|
|
||||||
public static final Deserializer DESERIALIZER =
|
public static final Deserializer DESERIALIZER =
|
||||||
new SegmentDownloadActionDeserializer<String>() {
|
new SegmentDownloadActionDeserializer<RenditionKey>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getType() {
|
public String getType() {
|
||||||
@ -36,18 +37,18 @@ public final class HlsDownloadAction extends SegmentDownloadAction<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String readKey(DataInputStream input) throws IOException {
|
protected RenditionKey readKey(DataInputStream input) throws IOException {
|
||||||
return input.readUTF();
|
return new RenditionKey(input.readUTF());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String[] createKeyArray(int keyCount) {
|
protected RenditionKey[] createKeyArray(int keyCount) {
|
||||||
return new String[keyCount];
|
return new RenditionKey[keyCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DownloadAction createDownloadAction(
|
protected DownloadAction createDownloadAction(
|
||||||
Uri manifestUri, boolean removeAction, String data, String[] keys) {
|
Uri manifestUri, boolean removeAction, String data, RenditionKey[] keys) {
|
||||||
return new HlsDownloadAction(manifestUri, removeAction, data, keys);
|
return new HlsDownloadAction(manifestUri, removeAction, data, keys);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -56,7 +57,7 @@ public final class HlsDownloadAction extends SegmentDownloadAction<String> {
|
|||||||
|
|
||||||
/** @see SegmentDownloadAction#SegmentDownloadAction(Uri, boolean, String, Object[]) */
|
/** @see SegmentDownloadAction#SegmentDownloadAction(Uri, boolean, String, Object[]) */
|
||||||
public HlsDownloadAction(
|
public HlsDownloadAction(
|
||||||
Uri manifestUri, boolean removeAction, @Nullable String data, String... keys) {
|
Uri manifestUri, boolean removeAction, @Nullable String data, RenditionKey... keys) {
|
||||||
super(manifestUri, removeAction, data, keys);
|
super(manifestUri, removeAction, data, keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +76,8 @@ public final class HlsDownloadAction extends SegmentDownloadAction<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeKey(DataOutputStream output, String key) throws IOException {
|
protected void writeKey(DataOutputStream output, RenditionKey key) throws IOException {
|
||||||
output.writeUTF(key);
|
output.writeUTF(key.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUr
|
|||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
|
||||||
|
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||||
@ -37,10 +38,9 @@ import java.util.List;
|
|||||||
* Helper class to download HLS streams.
|
* Helper class to download HLS streams.
|
||||||
*
|
*
|
||||||
* <p>A subset of renditions can be downloaded by selecting them using {@link
|
* <p>A subset of renditions can be downloaded by selecting them using {@link
|
||||||
* #selectRepresentations(Object[])}. As key, string form of the rendition's url is used. The urls
|
* #selectRepresentations(Object[])}.
|
||||||
* can be absolute or relative to the master playlist url.
|
|
||||||
*/
|
*/
|
||||||
public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, String> {
|
public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, RenditionKey> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper)
|
* @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper)
|
||||||
@ -50,13 +50,13 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getAllRepresentationKeys() throws IOException {
|
public RenditionKey[] getAllRepresentationKeys() throws IOException {
|
||||||
ArrayList<String> urls = new ArrayList<>();
|
ArrayList<RenditionKey> renditionKeys = new ArrayList<>();
|
||||||
HlsMasterPlaylist manifest = getManifest();
|
HlsMasterPlaylist manifest = getManifest();
|
||||||
extractUrls(manifest.variants, urls);
|
extractUrls(manifest.variants, renditionKeys);
|
||||||
extractUrls(manifest.audios, urls);
|
extractUrls(manifest.audios, renditionKeys);
|
||||||
extractUrls(manifest.subtitles, urls);
|
extractUrls(manifest.subtitles, renditionKeys);
|
||||||
return urls.toArray(new String[urls.size()]);
|
return renditionKeys.toArray(new RenditionKey[renditionKeys.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -70,13 +70,17 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<Segment> getSegments(DataSource dataSource, HlsMasterPlaylist manifest,
|
protected List<Segment> getSegments(
|
||||||
String[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException {
|
DataSource dataSource,
|
||||||
|
HlsMasterPlaylist manifest,
|
||||||
|
RenditionKey[] keys,
|
||||||
|
boolean allowIndexLoadErrors)
|
||||||
|
throws InterruptedException, IOException {
|
||||||
HashSet<Uri> encryptionKeyUris = new HashSet<>();
|
HashSet<Uri> encryptionKeyUris = new HashSet<>();
|
||||||
ArrayList<Segment> segments = new ArrayList<>();
|
ArrayList<Segment> segments = new ArrayList<>();
|
||||||
for (String playlistUrl : keys) {
|
for (RenditionKey renditionKey : keys) {
|
||||||
HlsMediaPlaylist mediaPlaylist = null;
|
HlsMediaPlaylist mediaPlaylist = null;
|
||||||
Uri uri = UriUtil.resolveToUri(manifest.baseUri, playlistUrl);
|
Uri uri = UriUtil.resolveToUri(manifest.baseUri, renditionKey.url);
|
||||||
try {
|
try {
|
||||||
mediaPlaylist = (HlsMediaPlaylist) loadManifest(dataSource, uri);
|
mediaPlaylist = (HlsMediaPlaylist) loadManifest(dataSource, uri);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -128,9 +132,9 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
|
|||||||
new DataSpec(resolvedUri, hlsSegment.byterangeOffset, hlsSegment.byterangeLength, null)));
|
new DataSpec(resolvedUri, hlsSegment.byterangeOffset, hlsSegment.byterangeLength, null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void extractUrls(List<HlsUrl> hlsUrls, ArrayList<String> urls) {
|
private static void extractUrls(List<HlsUrl> hlsUrls, ArrayList<RenditionKey> renditionKeys) {
|
||||||
for (int i = 0; i < hlsUrls.size(); i++) {
|
for (int i = 0; i < hlsUrls.size(); i++) {
|
||||||
urls.add(hlsUrls.get(i).url);
|
renditionKeys.add(new RenditionKey(hlsUrls.get(i).url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,13 +26,13 @@ import java.util.List;
|
|||||||
public final class FilteringHlsPlaylistParser implements Parser<HlsPlaylist> {
|
public final class FilteringHlsPlaylistParser implements Parser<HlsPlaylist> {
|
||||||
|
|
||||||
private final HlsPlaylistParser hlsPlaylistParser;
|
private final HlsPlaylistParser hlsPlaylistParser;
|
||||||
private final List<String> filter;
|
private final List<RenditionKey> filter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param filter The urls to renditions that should be retained in the parsed playlists. If null,
|
* @param filter The urls to renditions that should be retained in the parsed playlists. If null,
|
||||||
* all renditions are retained.
|
* all renditions are retained.
|
||||||
*/
|
*/
|
||||||
public FilteringHlsPlaylistParser(@Nullable List<String> filter) {
|
public FilteringHlsPlaylistParser(@Nullable List<RenditionKey> filter) {
|
||||||
this.hlsPlaylistParser = new HlsPlaylistParser();
|
this.hlsPlaylistParser = new HlsPlaylistParser();
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
}
|
}
|
||||||
|
@ -111,16 +111,21 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of this playlist which includes only the renditions identified by the given
|
* Returns a copy of this playlist which includes only the renditions identified by the given
|
||||||
* urls.
|
* keys.
|
||||||
*
|
*
|
||||||
* @param renditionUrls List of rendition urls.
|
* @param renditionKeys List of rendition keys.
|
||||||
* @return A copy of this playlist which includes only the renditions identified by the given
|
* @return A copy of this playlist which includes only the renditions identified by the given
|
||||||
* urls.
|
* urls.
|
||||||
*/
|
*/
|
||||||
public HlsMasterPlaylist copy(List<String> renditionUrls) {
|
public HlsMasterPlaylist copy(List<RenditionKey> renditionKeys) {
|
||||||
return new HlsMasterPlaylist(baseUri, tags, copyRenditionsList(variants, renditionUrls),
|
return new HlsMasterPlaylist(
|
||||||
copyRenditionsList(audios, renditionUrls), copyRenditionsList(subtitles, renditionUrls),
|
baseUri,
|
||||||
muxedAudioFormat, muxedCaptionFormats);
|
tags,
|
||||||
|
copyRenditionsList(variants, renditionKeys),
|
||||||
|
copyRenditionsList(audios, renditionKeys),
|
||||||
|
copyRenditionsList(subtitles, renditionKeys),
|
||||||
|
muxedAudioFormat,
|
||||||
|
muxedCaptionFormats);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,12 +141,17 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||||||
emptyList, null, null);
|
emptyList, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<HlsUrl> copyRenditionsList(List<HlsUrl> renditions, List<String> urls) {
|
private static List<HlsUrl> copyRenditionsList(
|
||||||
List<HlsUrl> copiedRenditions = new ArrayList<>(urls.size());
|
List<HlsUrl> renditions, List<RenditionKey> renditionKeys) {
|
||||||
|
List<HlsUrl> copiedRenditions = new ArrayList<>(renditionKeys.size());
|
||||||
for (int i = 0; i < renditions.size(); i++) {
|
for (int i = 0; i < renditions.size(); i++) {
|
||||||
HlsUrl rendition = renditions.get(i);
|
HlsUrl rendition = renditions.get(i);
|
||||||
if (urls.contains(rendition.url)) {
|
for (int j = 0; j < renditionKeys.size(); j++) {
|
||||||
copiedRenditions.add(rendition);
|
RenditionKey renditionKey = renditionKeys.get(j);
|
||||||
|
if (renditionKey.url.equals(rendition.url)) {
|
||||||
|
copiedRenditions.add(rendition);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return copiedRenditions;
|
return copiedRenditions;
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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.source.hls.playlist;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
/** Uniquely identifies a rendition in an {@link HlsMasterPlaylist}. */
|
||||||
|
public final class RenditionKey implements Parcelable {
|
||||||
|
|
||||||
|
public final String url;
|
||||||
|
|
||||||
|
public RenditionKey(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parcelable implementation.
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel dest, int flags) {
|
||||||
|
dest.writeString(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<RenditionKey> CREATOR =
|
||||||
|
new Creator<RenditionKey>() {
|
||||||
|
@Override
|
||||||
|
public RenditionKey createFromParcel(Parcel in) {
|
||||||
|
return new RenditionKey(in.readString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RenditionKey[] newArray(int size) {
|
||||||
|
return new RenditionKey[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -35,6 +35,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
|
||||||
|
import com.google.android.exoplayer2.source.hls.playlist.RenditionKey;
|
||||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||||
import com.google.android.exoplayer2.testutil.FakeDataSource.Factory;
|
import com.google.android.exoplayer2.testutil.FakeDataSource.Factory;
|
||||||
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||||
@ -91,8 +92,8 @@ public class HlsDownloaderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSelectRepresentationsClearsPreviousSelection() throws Exception {
|
public void testSelectRepresentationsClearsPreviousSelection() throws Exception {
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI));
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_2_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_2_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
|
|
||||||
assertCachedData(
|
assertCachedData(
|
||||||
@ -107,7 +108,7 @@ public class HlsDownloaderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCounterMethods() throws Exception {
|
public void testCounterMethods() throws Exception {
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
|
|
||||||
assertThat(hlsDownloader.getTotalSegments()).isEqualTo(4);
|
assertThat(hlsDownloader.getTotalSegments()).isEqualTo(4);
|
||||||
@ -118,11 +119,11 @@ public class HlsDownloaderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInitStatus() throws Exception {
|
public void testInitStatus() throws Exception {
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
|
|
||||||
HlsDownloader newHlsDownloader = getHlsDownloader(MASTER_PLAYLIST_URI);
|
HlsDownloader newHlsDownloader = getHlsDownloader(MASTER_PLAYLIST_URI);
|
||||||
newHlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI});
|
newHlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI));
|
||||||
newHlsDownloader.init();
|
newHlsDownloader.init();
|
||||||
|
|
||||||
assertThat(newHlsDownloader.getTotalSegments()).isEqualTo(4);
|
assertThat(newHlsDownloader.getTotalSegments()).isEqualTo(4);
|
||||||
@ -133,7 +134,7 @@ public class HlsDownloaderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDownloadRepresentation() throws Exception {
|
public void testDownloadRepresentation() throws Exception {
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
|
|
||||||
assertCachedData(
|
assertCachedData(
|
||||||
@ -148,7 +149,7 @@ public class HlsDownloaderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDownloadMultipleRepresentations() throws Exception {
|
public void testDownloadMultipleRepresentations() throws Exception {
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI, MEDIA_PLAYLIST_2_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI, MEDIA_PLAYLIST_2_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
|
|
||||||
assertCachedData(cache, fakeDataSet);
|
assertCachedData(cache, fakeDataSet);
|
||||||
@ -174,9 +175,9 @@ public class HlsDownloaderTest {
|
|||||||
hlsDownloader.remove();
|
hlsDownloader.remove();
|
||||||
|
|
||||||
// select something random
|
// select something random
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI));
|
||||||
// clear selection
|
// clear selection
|
||||||
hlsDownloader.selectRepresentations(new String[0]);
|
hlsDownloader.selectRepresentations(getKeys());
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
assertCachedData(cache, fakeDataSet);
|
assertCachedData(cache, fakeDataSet);
|
||||||
hlsDownloader.remove();
|
hlsDownloader.remove();
|
||||||
@ -184,7 +185,7 @@ public class HlsDownloaderTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRemoveAll() throws Exception {
|
public void testRemoveAll() throws Exception {
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI, MEDIA_PLAYLIST_2_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI, MEDIA_PLAYLIST_2_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
hlsDownloader.remove();
|
hlsDownloader.remove();
|
||||||
|
|
||||||
@ -194,7 +195,7 @@ public class HlsDownloaderTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testDownloadMediaPlaylist() throws Exception {
|
public void testDownloadMediaPlaylist() throws Exception {
|
||||||
hlsDownloader = getHlsDownloader(MEDIA_PLAYLIST_1_URI);
|
hlsDownloader = getHlsDownloader(MEDIA_PLAYLIST_1_URI);
|
||||||
hlsDownloader.selectRepresentations(new String[] {MEDIA_PLAYLIST_1_URI});
|
hlsDownloader.selectRepresentations(getKeys(MEDIA_PLAYLIST_1_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
|
|
||||||
assertCachedData(
|
assertCachedData(
|
||||||
@ -217,7 +218,7 @@ public class HlsDownloaderTest {
|
|||||||
.setRandomData("fileSequence1.ts", 11)
|
.setRandomData("fileSequence1.ts", 11)
|
||||||
.setRandomData("fileSequence2.ts", 12);
|
.setRandomData("fileSequence2.ts", 12);
|
||||||
hlsDownloader = getHlsDownloader(ENC_MEDIA_PLAYLIST_URI);
|
hlsDownloader = getHlsDownloader(ENC_MEDIA_PLAYLIST_URI);
|
||||||
hlsDownloader.selectRepresentations(new String[] {ENC_MEDIA_PLAYLIST_URI});
|
hlsDownloader.selectRepresentations(getKeys(ENC_MEDIA_PLAYLIST_URI));
|
||||||
hlsDownloader.download(null);
|
hlsDownloader.download(null);
|
||||||
|
|
||||||
assertCachedData(cache, fakeDataSet);
|
assertCachedData(cache, fakeDataSet);
|
||||||
@ -228,4 +229,12 @@ public class HlsDownloaderTest {
|
|||||||
return new HlsDownloader(
|
return new HlsDownloader(
|
||||||
Uri.parse(mediaPlaylistUri), new DownloaderConstructorHelper(cache, factory));
|
Uri.parse(mediaPlaylistUri), new DownloaderConstructorHelper(cache, factory));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static RenditionKey[] getKeys(String... urls) {
|
||||||
|
RenditionKey[] renditionKeys = new RenditionKey[urls.length];
|
||||||
|
for (int i = 0; i < urls.length; i++) {
|
||||||
|
renditionKeys[i] = new RenditionKey(urls[i]);
|
||||||
|
}
|
||||||
|
return renditionKeys;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user