Add SegmentDownloader.getAllRepresentationKeys method

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=183656655
This commit is contained in:
eguven 2018-01-29 06:22:03 -08:00 committed by Oliver Woodman
parent b82178ecb4
commit 1dde2adbf3
4 changed files with 61 additions and 64 deletions

View File

@ -104,10 +104,17 @@ public abstract class SegmentDownloader<M, K> implements Downloader {
* previous selection is cleared. If keys are null or empty, all representations are downloaded. * previous selection is cleared. If keys are null or empty, all representations are downloaded.
*/ */
public final void selectRepresentations(K[] keys) { public final void selectRepresentations(K[] keys) {
this.keys = keys != null ? keys.clone() : null; this.keys = (keys != null && keys.length > 0) ? keys.clone() : null;
resetCounters(); resetCounters();
} }
/**
* Returns keys for all representations.
*
* @see #selectRepresentations(Object[])
*/
public abstract K[] getAllRepresentationKeys() throws IOException;
/** /**
* Initializes the total segments, downloaded segments and downloaded bytes counters for the * Initializes the total segments, downloaded segments and downloaded bytes counters for the
* selected representations. * selected representations.
@ -221,7 +228,7 @@ public abstract class SegmentDownloader<M, K> implements Downloader {
if (manifest != null) { if (manifest != null) {
List<Segment> segments = null; List<Segment> segments = null;
try { try {
segments = getAllSegments(offlineDataSource, manifest, true); segments = getSegments(offlineDataSource, manifest, getAllRepresentationKeys(), true);
} catch (IOException e) { } catch (IOException e) {
// Ignore exceptions. We do our best with what's available offline. // Ignore exceptions. We do our best with what's available offline.
} }
@ -262,14 +269,6 @@ public abstract class SegmentDownloader<M, K> implements Downloader {
protected abstract List<Segment> getSegments(DataSource dataSource, M manifest, K[] keys, protected abstract List<Segment> getSegments(DataSource dataSource, M manifest, K[] keys,
boolean allowIncompleteIndex) throws InterruptedException, IOException; boolean allowIncompleteIndex) throws InterruptedException, IOException;
/**
* Returns a list of all segments.
*
* @see #getSegments(DataSource, M, Object[], boolean)
*/
protected abstract List<Segment> getAllSegments(DataSource dataSource, M manifest,
boolean allowPartialIndex) throws InterruptedException, IOException;
private void resetCounters() { private void resetCounters() {
totalSegments = C.LENGTH_UNSET; totalSegments = C.LENGTH_UNSET;
downloadedSegments = C.LENGTH_UNSET; downloadedSegments = C.LENGTH_UNSET;
@ -295,9 +294,10 @@ public abstract class SegmentDownloader<M, K> implements Downloader {
private synchronized List<Segment> initStatus(boolean offline) private synchronized List<Segment> initStatus(boolean offline)
throws IOException, InterruptedException { throws IOException, InterruptedException {
DataSource dataSource = getDataSource(offline); DataSource dataSource = getDataSource(offline);
List<Segment> segments = keys != null && keys.length > 0 if (keys == null) {
? getSegments(dataSource, manifest, keys, offline) keys = getAllRepresentationKeys();
: getAllSegments(dataSource, manifest, offline); }
List<Segment> segments = getSegments(dataSource, manifest, keys, offline);
CachingCounters cachingCounters = new CachingCounters(); CachingCounters cachingCounters = new CachingCounters();
totalSegments = segments.size(); totalSegments = segments.size();
downloadedSegments = 0; downloadedSegments = 0;

View File

@ -75,26 +75,24 @@ public final class DashDownloader extends SegmentDownloader<DashManifest, Repres
} }
@Override @Override
public DashManifest getManifest(DataSource dataSource, Uri uri) throws IOException { public RepresentationKey[] getAllRepresentationKeys() throws IOException {
return DashUtil.loadManifest(dataSource, uri); ArrayList<RepresentationKey> keys = new ArrayList<>();
} DashManifest manifest = getManifest();
@Override
protected List<Segment> getAllSegments(DataSource dataSource, DashManifest manifest,
boolean allowIndexLoadErrors) throws InterruptedException, IOException {
ArrayList<Segment> segments = new ArrayList<>();
for (int periodIndex = 0; periodIndex < manifest.getPeriodCount(); periodIndex++) { for (int periodIndex = 0; periodIndex < manifest.getPeriodCount(); periodIndex++) {
List<AdaptationSet> adaptationSets = manifest.getPeriod(periodIndex).adaptationSets; List<AdaptationSet> adaptationSets = manifest.getPeriod(periodIndex).adaptationSets;
for (int adaptationIndex = 0; adaptationIndex < adaptationSets.size(); adaptationIndex++) { for (int adaptationIndex = 0; adaptationIndex < adaptationSets.size(); adaptationIndex++) {
AdaptationSet adaptationSet = adaptationSets.get(adaptationIndex); int representationsCount = adaptationSets.get(adaptationIndex).representations.size();
RepresentationKey[] keys = new RepresentationKey[adaptationSet.representations.size()]; for (int i = 0; i < representationsCount; i++) {
for (int i = 0; i < keys.length; i++) { keys.add(new RepresentationKey(periodIndex, adaptationIndex, i));
keys[i] = new RepresentationKey(periodIndex, adaptationIndex, i);
} }
segments.addAll(getSegments(dataSource, manifest, keys, allowIndexLoadErrors));
} }
} }
return segments; return keys.toArray(new RepresentationKey[keys.size()]);
}
@Override
protected DashManifest getManifest(DataSource dataSource, Uri uri) throws IOException {
return DashUtil.loadManifest(dataSource, uri);
} }
@Override @Override

View File

@ -36,7 +36,7 @@ import java.util.List;
/** /**
* Helper class to download HLS streams. * Helper class to download HLS streams.
* *
* 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[])}. As key, string form of the rendition's url is used. The urls
* can be absolute or relative to the master playlist url. * can be absolute or relative to the master playlist url.
*/ */
@ -49,6 +49,16 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
super(manifestUri, constructorHelper); super(manifestUri, constructorHelper);
} }
@Override
public String[] getAllRepresentationKeys() throws IOException {
ArrayList<String> urls = new ArrayList<>();
HlsMasterPlaylist manifest = getManifest();
extractUrls(manifest.variants, urls);
extractUrls(manifest.audios, urls);
extractUrls(manifest.subtitles, urls);
return urls.toArray(new String[urls.size()]);
}
@Override @Override
protected HlsMasterPlaylist getManifest(DataSource dataSource, Uri uri) throws IOException { protected HlsMasterPlaylist getManifest(DataSource dataSource, Uri uri) throws IOException {
HlsPlaylist hlsPlaylist = loadManifest(dataSource, uri); HlsPlaylist hlsPlaylist = loadManifest(dataSource, uri);
@ -59,17 +69,6 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
} }
} }
@Override
protected List<Segment> getAllSegments(DataSource dataSource, HlsMasterPlaylist manifest,
boolean allowIndexLoadErrors) throws InterruptedException, IOException {
ArrayList<String> urls = new ArrayList<>();
extractUrls(manifest.variants, urls);
extractUrls(manifest.audios, urls);
extractUrls(manifest.subtitles, urls);
return getSegments(dataSource, manifest, urls.toArray(new String[urls.size()]),
allowIndexLoadErrors);
}
@Override @Override
protected List<Segment> getSegments(DataSource dataSource, HlsMasterPlaylist manifest, protected List<Segment> getSegments(DataSource dataSource, HlsMasterPlaylist manifest,
String[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException { String[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException {
@ -104,7 +103,7 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
return segments; return segments;
} }
private HlsPlaylist loadManifest(DataSource dataSource, Uri uri) throws IOException { private static HlsPlaylist loadManifest(DataSource dataSource, Uri uri) throws IOException {
DataSpec dataSpec = new DataSpec(uri, DataSpec dataSpec = new DataSpec(uri,
DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP); DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP);
ParsingLoadable<HlsPlaylist> loadable = new ParsingLoadable<>(dataSource, dataSpec, ParsingLoadable<HlsPlaylist> loadable = new ParsingLoadable<>(dataSource, dataSpec,
@ -113,9 +112,11 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
return loadable.getResult(); return loadable.getResult();
} }
private static void addSegment(ArrayList<Segment> segments, HlsMediaPlaylist mediaPlaylist, private static void addSegment(
HlsMediaPlaylist.Segment hlsSegment, HashSet<Uri> encryptionKeyUris) ArrayList<Segment> segments,
throws IOException, InterruptedException { HlsMediaPlaylist mediaPlaylist,
HlsMediaPlaylist.Segment hlsSegment,
HashSet<Uri> encryptionKeyUris) {
long startTimeUs = mediaPlaylist.startTimeUs + hlsSegment.relativeStartTimeUs; long startTimeUs = mediaPlaylist.startTimeUs + hlsSegment.relativeStartTimeUs;
if (hlsSegment.fullSegmentEncryptionKeyUri != null) { if (hlsSegment.fullSegmentEncryptionKeyUri != null) {
Uri keyUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, Uri keyUri = UriUtil.resolveToUri(mediaPlaylist.baseUri,

View File

@ -33,13 +33,12 @@ import java.util.List;
/** /**
* Helper class to download SmoothStreaming streams. * Helper class to download SmoothStreaming streams.
* *
* <p>Except {@link #getTotalSegments()}, {@link #getDownloadedSegments()} and * <p>Except {@link #getTotalSegments()}, {@link #getDownloadedSegments()} and {@link
* {@link #getDownloadedBytes()}, this class isn't thread safe. * #getDownloadedBytes()}, this class isn't thread safe.
* *
* <p>Example usage: * <p>Example usage:
* *
* <pre> * <pre>{@code
* {@code
* SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor()); * SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor());
* DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null); * DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
* DownloaderConstructorHelper constructorHelper = * DownloaderConstructorHelper constructorHelper =
@ -56,8 +55,8 @@ import java.util.List;
* }); * });
* // Access downloaded data using CacheDataSource * // Access downloaded data using CacheDataSource
* CacheDataSource cacheDataSource = * CacheDataSource cacheDataSource =
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);} * new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
* </pre> * }</pre>
*/ */
public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey> { public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey> {
@ -69,7 +68,20 @@ public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey>
} }
@Override @Override
public SsManifest getManifest(DataSource dataSource, Uri uri) throws IOException { public TrackKey[] getAllRepresentationKeys() throws IOException {
ArrayList<TrackKey> keys = new ArrayList<>();
SsManifest manifest = getManifest();
for (int i = 0; i < manifest.streamElements.length; i++) {
StreamElement streamElement = manifest.streamElements[i];
for (int j = 0; j < streamElement.formats.length; j++) {
keys.add(new TrackKey(i, j));
}
}
return keys.toArray(new TrackKey[keys.size()]);
}
@Override
protected SsManifest getManifest(DataSource dataSource, Uri uri) throws IOException {
DataSpec dataSpec = new DataSpec(uri, DataSpec dataSpec = new DataSpec(uri,
DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP); DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP);
ParsingLoadable<SsManifest> loadable = new ParsingLoadable<>(dataSource, dataSpec, ParsingLoadable<SsManifest> loadable = new ParsingLoadable<>(dataSource, dataSpec,
@ -78,20 +90,6 @@ public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey>
return loadable.getResult(); return loadable.getResult();
} }
@Override
protected List<Segment> getAllSegments(DataSource dataSource, SsManifest manifest,
boolean allowIndexLoadErrors) throws InterruptedException, IOException {
ArrayList<Segment> segments = new ArrayList<>();
for (int i = 0; i < manifest.streamElements.length; i++) {
StreamElement streamElement = manifest.streamElements[i];
for (int j = 0; j < streamElement.formats.length; j++) {
segments.addAll(getSegments(dataSource, manifest, new TrackKey[] {new TrackKey(i, j)},
allowIndexLoadErrors));
}
}
return segments;
}
@Override @Override
protected List<Segment> getSegments(DataSource dataSource, SsManifest manifest, protected List<Segment> getSegments(DataSource dataSource, SsManifest manifest,
TrackKey[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException { TrackKey[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException {