Add SegmentDownloader.getAllRepresentationKeys method
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=183656655
This commit is contained in:
parent
b82178ecb4
commit
1dde2adbf3
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user