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.
*/
public final void selectRepresentations(K[] keys) {
this.keys = keys != null ? keys.clone() : null;
this.keys = (keys != null && keys.length > 0) ? keys.clone() : null;
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
* selected representations.
@ -221,7 +228,7 @@ public abstract class SegmentDownloader<M, K> implements Downloader {
if (manifest != null) {
List<Segment> segments = null;
try {
segments = getAllSegments(offlineDataSource, manifest, true);
segments = getSegments(offlineDataSource, manifest, getAllRepresentationKeys(), true);
} catch (IOException e) {
// 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,
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() {
totalSegments = 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)
throws IOException, InterruptedException {
DataSource dataSource = getDataSource(offline);
List<Segment> segments = keys != null && keys.length > 0
? getSegments(dataSource, manifest, keys, offline)
: getAllSegments(dataSource, manifest, offline);
if (keys == null) {
keys = getAllRepresentationKeys();
}
List<Segment> segments = getSegments(dataSource, manifest, keys, offline);
CachingCounters cachingCounters = new CachingCounters();
totalSegments = segments.size();
downloadedSegments = 0;

View File

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

View File

@ -36,7 +36,7 @@ import java.util.List;
/**
* 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
* 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);
}
@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
protected HlsMasterPlaylist getManifest(DataSource dataSource, Uri uri) throws IOException {
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
protected List<Segment> getSegments(DataSource dataSource, HlsMasterPlaylist manifest,
String[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException {
@ -104,7 +103,7 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
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.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP);
ParsingLoadable<HlsPlaylist> loadable = new ParsingLoadable<>(dataSource, dataSpec,
@ -113,9 +112,11 @@ public final class HlsDownloader extends SegmentDownloader<HlsMasterPlaylist, St
return loadable.getResult();
}
private static void addSegment(ArrayList<Segment> segments, HlsMediaPlaylist mediaPlaylist,
HlsMediaPlaylist.Segment hlsSegment, HashSet<Uri> encryptionKeyUris)
throws IOException, InterruptedException {
private static void addSegment(
ArrayList<Segment> segments,
HlsMediaPlaylist mediaPlaylist,
HlsMediaPlaylist.Segment hlsSegment,
HashSet<Uri> encryptionKeyUris) {
long startTimeUs = mediaPlaylist.startTimeUs + hlsSegment.relativeStartTimeUs;
if (hlsSegment.fullSegmentEncryptionKeyUri != null) {
Uri keyUri = UriUtil.resolveToUri(mediaPlaylist.baseUri,

View File

@ -33,13 +33,12 @@ import java.util.List;
/**
* Helper class to download SmoothStreaming streams.
*
* <p>Except {@link #getTotalSegments()}, {@link #getDownloadedSegments()} and
* {@link #getDownloadedBytes()}, this class isn't thread safe.
* <p>Except {@link #getTotalSegments()}, {@link #getDownloadedSegments()} and {@link
* #getDownloadedBytes()}, this class isn't thread safe.
*
* <p>Example usage:
*
* <pre>
* {@code
* <pre>{@code
* SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor());
* DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
* DownloaderConstructorHelper constructorHelper =
@ -56,8 +55,8 @@ import java.util.List;
* });
* // Access downloaded data using CacheDataSource
* CacheDataSource cacheDataSource =
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);}
* </pre>
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
* }</pre>
*/
public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey> {
@ -69,7 +68,20 @@ public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey>
}
@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.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP);
ParsingLoadable<SsManifest> loadable = new ParsingLoadable<>(dataSource, dataSpec,
@ -78,20 +90,6 @@ public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey>
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
protected List<Segment> getSegments(DataSource dataSource, SsManifest manifest,
TrackKey[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException {