SegmentDownloader loadManifest cleanup.

- HlsDownloader.loadManifest (previously called getHlsPlaylist)
  suppressed errors for the offline case, where-as the DashUtil
  equivalent method did not. This change makes them consistent
  and moves both other to use ParsingLoadable.
- Enable GZIP for manifest loads in both cases.
- Use Uri rather than String to represent Uris. Previously the
  strings were parsed into Uris quite deep in the code, which
  isn't ideal if the parsing fails; you'd probably prefer the
  error to occur early at the top level.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=165181398
This commit is contained in:
olly 2017-08-14 08:31:59 -07:00 committed by Oliver Woodman
parent fb83872365
commit cf6534ea5b
5 changed files with 77 additions and 36 deletions

View File

@ -72,8 +72,19 @@ public final class ParsingLoadable<T> implements Loadable {
* @param parser Parses the object from the response.
*/
public ParsingLoadable(DataSource dataSource, Uri uri, int type, Parser<? extends T> parser) {
this(dataSource, new DataSpec(uri, DataSpec.FLAG_ALLOW_GZIP), type, parser);
}
/**
* @param dataSource A {@link DataSource} to use when loading the data.
* @param dataSpec The {@link DataSpec} from which the object should be loaded.
* @param type See {@link #type}.
* @param parser Parses the object from the response.
*/
public ParsingLoadable(DataSource dataSource, DataSpec dataSpec, int type,
Parser<? extends T> parser) {
this.dataSource = dataSource;
this.dataSpec = new DataSpec(uri, DataSpec.FLAG_ALLOW_GZIP);
this.dataSpec = dataSpec;
this.type = type;
this.parser = parser;
}
@ -108,7 +119,7 @@ public final class ParsingLoadable<T> implements Loadable {
}
@Override
public final void load() throws IOException, InterruptedException {
public final void load() throws IOException {
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
try {
inputStream.open();

View File

@ -31,9 +31,9 @@ import com.google.android.exoplayer2.source.dash.manifest.Period;
import com.google.android.exoplayer2.source.dash.manifest.RangedUri;
import com.google.android.exoplayer2.source.dash.manifest.Representation;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSourceInputStream;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.MimeTypes;
import java.io.IOException;
import java.util.List;
@ -47,21 +47,18 @@ public final class DashUtil {
* Loads a DASH manifest.
*
* @param dataSource The {@link HttpDataSource} from which the manifest should be read.
* @param manifestUri The URI of the manifest to be read.
* @param uri The {@link Uri} of the manifest to be read.
* @return An instance of {@link DashManifest}.
* @throws IOException Thrown when there is an error while loading.
*/
public static DashManifest loadManifest(DataSource dataSource, String manifestUri)
public static DashManifest loadManifest(DataSource dataSource, Uri uri)
throws IOException {
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource,
new DataSpec(Uri.parse(manifestUri), DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH));
try {
inputStream.open();
DashManifestParser parser = new DashManifestParser();
return parser.parse(dataSource.getUri(), inputStream);
} finally {
inputStream.close();
}
DataSpec dataSpec = new DataSpec(uri,
DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH | DataSpec.FLAG_ALLOW_GZIP);
ParsingLoadable<DashManifest> loadable = new ParsingLoadable<>(dataSource, dataSpec,
C.DATA_TYPE_MANIFEST, new DashManifestParser());
loadable.load();
return loadable.getResult();
}
/**

View File

@ -16,6 +16,7 @@
package com.google.android.exoplayer2.playbacktests.gts;
import android.media.MediaDrm.MediaDrmStateException;
import android.net.Uri;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Pair;
import com.google.android.exoplayer2.drm.DrmInitData;
@ -170,7 +171,7 @@ public final class DashWidevineOfflineTest extends ActivityInstrumentationTestCa
private void downloadLicense() throws InterruptedException, DrmSessionException, IOException {
DataSource dataSource = httpDataSourceFactory.createDataSource();
DashManifest dashManifest = DashUtil.loadManifest(dataSource,
DashTestData.WIDEVINE_H264_MANIFEST);
Uri.parse(DashTestData.WIDEVINE_H264_MANIFEST));
DrmInitData drmInitData = DashUtil.loadDrmInitData(dataSource, dashManifest.getPeriod(0));
offlineLicenseKeySetId = offlineLicenseHelper.downloadLicense(drmInitData);
Assert.assertNotNull(offlineLicenseKeySetId);

View File

@ -39,11 +39,11 @@ public final class CacheAsserts {
/** Asserts that the cache content is equal to the data in the {@code fakeDataSet}. */
public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet) throws IOException {
ArrayList<FakeData> allData = fakeDataSet.getAllData();
String[] uriStrings = new String[allData.size()];
Uri[] uris = new Uri[allData.size()];
for (int i = 0; i < allData.size(); i++) {
uriStrings[i] = allData.get(i).uri;
uris[i] = allData.get(i).uri;
}
assertCachedData(cache, fakeDataSet, uriStrings);
assertCachedData(cache, fakeDataSet, uris);
}
/**
@ -51,30 +51,41 @@ public final class CacheAsserts {
*/
public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet, String... uriStrings)
throws IOException {
Uri[] uris = new Uri[uriStrings.length];
for (int i = 0; i < uriStrings.length; i++) {
uris[i] = Uri.parse(uriStrings[i]);
}
assertCachedData(cache, fakeDataSet, uris);
}
/**
* Asserts that the cache content is equal to the given subset of data in the {@code fakeDataSet}.
*/
public static void assertCachedData(Cache cache, FakeDataSet fakeDataSet, Uri... uris)
throws IOException {
int totalLength = 0;
for (String uriString : uriStrings) {
byte[] data = fakeDataSet.getData(uriString).getData();
assertDataCached(cache, uriString, data);
for (Uri uri : uris) {
byte[] data = fakeDataSet.getData(uri).getData();
assertDataCached(cache, uri, data);
totalLength += data.length;
}
assertEquals(totalLength, cache.getCacheSpace());
}
/** Asserts that the cache contains the given subset of data in the {@code fakeDataSet}. */
public static void assertDataCached(Cache cache, FakeDataSet fakeDataSet, String... uriStrings)
public static void assertDataCached(Cache cache, FakeDataSet fakeDataSet, Uri... uris)
throws IOException {
for (String uriString : uriStrings) {
assertDataCached(cache, uriString, fakeDataSet.getData(uriString).getData());
for (Uri uri : uris) {
assertDataCached(cache, uri, fakeDataSet.getData(uri).getData());
}
}
/** Asserts that the cache contains the given data for {@code uriString}. */
public static void assertDataCached(Cache cache, String uriString, byte[] expected)
throws IOException {
public static void assertDataCached(Cache cache, Uri uri, byte[] expected) throws IOException {
CacheDataSource dataSource = new CacheDataSource(cache, DummyDataSource.INSTANCE, 0);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource,
new DataSpec(Uri.parse(uriString), DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH));
new DataSpec(uri, DataSpec.FLAG_ALLOW_CACHING_UNKNOWN_LENGTH));
try {
inputStream.open();
byte[] buffer = new byte[1024];
@ -87,7 +98,7 @@ public final class CacheAsserts {
} finally {
inputStream.close();
}
MoreAsserts.assertEquals("Cached data doesn't match expected for '" + uriString + "',",
MoreAsserts.assertEquals("Cached data doesn't match expected for '" + uri + "',",
expected, outputStream.toByteArray());
}

View File

@ -15,6 +15,7 @@
*/
package com.google.android.exoplayer2.testutil;
import android.net.Uri;
import android.support.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.upstream.DataSpec;
@ -28,11 +29,11 @@ import java.util.List;
/**
* Collection of {@link FakeData} to be served by a {@link FakeDataSource}.
*
* <p>Multiple fake data can be defined by {@link FakeDataSet#setData(String, byte[])} and {@link
* FakeDataSet#newData(String)} methods. It's also possible to define a default data by {@link
* <p>Multiple fake data can be defined by {@link FakeDataSet#setData(Uri, byte[])} and {@link
* FakeDataSet#newData(Uri)} methods. It's also possible to define a default data by {@link
* FakeDataSet#newDefaultData()}.
*
* <p>{@link FakeDataSet#newData(String)} and {@link FakeDataSet#newDefaultData()} return a {@link
* <p>{@link FakeDataSet#newData(Uri)} and {@link FakeDataSet#newDefaultData()} return a {@link
* FakeData} instance which can be used to define specific results during
* {@link FakeDataSource#read(byte[], int, int)} calls.
*
@ -104,8 +105,8 @@ public class FakeDataSet {
this(null, 0, null, action, previousSegment);
}
private Segment(byte[] data, int length, IOException exception, Runnable action,
Segment previousSegment) {
private Segment(@Nullable byte[] data, int length, @Nullable IOException exception,
@Nullable Runnable action, Segment previousSegment) {
this.exception = exception;
this.action = action;
this.data = data;
@ -125,12 +126,12 @@ public class FakeDataSet {
}
/** Uri of the data or null if this is the default FakeData. */
public final String uri;
public final Uri uri;
private final ArrayList<Segment> segments;
private final FakeDataSet dataSet;
private boolean simulateUnknownLength;
private FakeData(FakeDataSet dataSet, String uri) {
private FakeData(FakeDataSet dataSet, Uri uri) {
this.uri = uri;
this.segments = new ArrayList<>();
this.dataSet = dataSet;
@ -219,7 +220,7 @@ public class FakeDataSet {
}
private final HashMap<String, FakeData> dataMap;
private final HashMap<Uri, FakeData> dataMap;
private FakeData defaultData;
public FakeDataSet() {
@ -234,16 +235,31 @@ public class FakeDataSet {
/** Sets random data with the given {@code length} for the given {@code uri}. */
public FakeDataSet setRandomData(String uri, int length) {
return setRandomData(Uri.parse(uri), length);
}
/** Sets random data with the given {@code length} for the given {@code uri}. */
public FakeDataSet setRandomData(Uri uri, int length) {
return setData(uri, TestUtil.buildTestData(length));
}
/** Sets the given {@code data} for the given {@code uri}. */
public FakeDataSet setData(String uri, byte[] data) {
return setData(Uri.parse(uri), data);
}
/** Sets the given {@code data} for the given {@code uri}. */
public FakeDataSet setData(Uri uri, byte[] data) {
return newData(uri).appendReadData(data).endData();
}
/** Returns a new {@link FakeData} with the given {@code uri}. */
public FakeData newData(String uri) {
return newData(Uri.parse(uri));
}
/** Returns a new {@link FakeData} with the given {@code uri}. */
public FakeData newData(Uri uri) {
FakeData data = new FakeData(this, uri);
dataMap.put(uri, data);
return data;
@ -251,6 +267,11 @@ public class FakeDataSet {
/** Returns the data for the given {@code uri}, or {@code defaultData} if no data is set. */
public FakeData getData(String uri) {
return getData(Uri.parse(uri));
}
/** Returns the data for the given {@code uri}, or {@code defaultData} if no data is set. */
public FakeData getData(Uri uri) {
FakeData data = dataMap.get(uri);
return data != null ? data : defaultData;
}