mirror of
https://github.com/samsonjs/media.git
synced 2026-04-01 10:35:48 +00:00
DataSpec: Deprecate most constructors
Keeping (Uri) and (Uri, position, length) to avoid needing Builder for the trivial case. PiperOrigin-RevId: 294530226
This commit is contained in:
parent
c7b6a2e045
commit
1cbe3f72e6
33 changed files with 237 additions and 206 deletions
|
|
@ -9,8 +9,9 @@
|
|||
* Add `Player.onPlayWhenReadyChanged` with reasons.
|
||||
* Add `Player.onPlaybackStateChanged` and deprecate
|
||||
`Player.onPlayerStateChanged`.
|
||||
* Deprecate and rename getPlaybackError to getPlayerError for consistency.
|
||||
* Deprecate and rename onLoadingChanged to onIsLoadingChanged for consistency.
|
||||
* Deprecate and rename `getPlaybackError` to `getPlayerError` for consistency.
|
||||
* Deprecate and rename `onLoadingChanged` to `onIsLoadingChanged` for
|
||||
consistency.
|
||||
* Make `MediaSourceEventListener.LoadEventInfo` and
|
||||
`MediaSourceEventListener.MediaLoadData` top-level classes.
|
||||
* Rename `MediaCodecRenderer.onOutputFormatChanged` to
|
||||
|
|
@ -19,7 +20,9 @@
|
|||
* Move player message-related constants from `C` to `Renderer`, to avoid
|
||||
having the constants class depend on player/renderer classes.
|
||||
* Split out `common` and `extractor` submodules.
|
||||
* Add `DataSpec.Builder` and `DataSpec.customData`.
|
||||
* Add `DataSpec.Builder` and deprecate most `DataSpec` constructors.
|
||||
* Add `DataSpec.customData` to allow applications to pass custom data through
|
||||
`DataSource` chains.
|
||||
* Text:
|
||||
* Parse `<ruby>` and `<rt>` tags in WebVTT subtitles (rendering is coming
|
||||
later).
|
||||
|
|
|
|||
|
|
@ -926,7 +926,7 @@ public class CronetDataSource extends BaseDataSource implements HttpDataSource {
|
|||
redirectUrlDataSpec =
|
||||
dataSpec
|
||||
.buildUpon()
|
||||
.setUri(Uri.parse(newLocationUrl))
|
||||
.setUri(newLocationUrl)
|
||||
.setHttpMethod(DataSpec.HTTP_METHOD_GET)
|
||||
.setHttpBody(null)
|
||||
.build();
|
||||
|
|
|
|||
|
|
@ -120,12 +120,15 @@ public final class CronetDataSourceTest {
|
|||
when(mockUrlRequestBuilder.build()).thenReturn(mockUrlRequest);
|
||||
mockStatusResponse();
|
||||
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, C.LENGTH_UNSET, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL));
|
||||
testPostDataSpec =
|
||||
new DataSpec(Uri.parse(TEST_URL), TEST_POST_BODY, 0, 0, C.LENGTH_UNSET, null, 0);
|
||||
new DataSpec.Builder()
|
||||
.setUri(TEST_URL)
|
||||
.setHttpMethod(DataSpec.HTTP_METHOD_POST)
|
||||
.setHttpBody(TEST_POST_BODY)
|
||||
.build();
|
||||
testHeadDataSpec =
|
||||
new DataSpec(
|
||||
Uri.parse(TEST_URL), DataSpec.HTTP_METHOD_HEAD, null, 0, 0, C.LENGTH_UNSET, null, 0);
|
||||
new DataSpec.Builder().setUri(TEST_URL).setHttpMethod(DataSpec.HTTP_METHOD_HEAD).build();
|
||||
testResponseHeader = new HashMap<>();
|
||||
testResponseHeader.put("Content-Type", TEST_CONTENT_TYPE);
|
||||
// This value can be anything since the DataSpec is unset.
|
||||
|
|
@ -197,7 +200,7 @@ public final class CronetDataSourceTest {
|
|||
|
||||
@Test
|
||||
public void testRequestSetsRangeHeader() throws HttpDataSourceException {
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||
mockResponseStartSuccess();
|
||||
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
|
@ -207,7 +210,6 @@ public final class CronetDataSourceTest {
|
|||
|
||||
@Test
|
||||
public void testRequestHeadersSet() throws HttpDataSourceException {
|
||||
|
||||
Map<String, String> headersSet = new HashMap<>();
|
||||
doAnswer(
|
||||
(invocation) -> {
|
||||
|
|
@ -227,17 +229,14 @@ public final class CronetDataSourceTest {
|
|||
dataSpecRequestProperties.put("defaultHeader3", "dataSpecOverridesAll");
|
||||
dataSpecRequestProperties.put("dataSourceHeader2", "dataSpecOverridesDataSource");
|
||||
dataSpecRequestProperties.put("dataSpecHeader1", "dataSpecValue1");
|
||||
|
||||
testDataSpec =
|
||||
new DataSpec(
|
||||
/* uri= */ Uri.parse(TEST_URL),
|
||||
/* httpMethod= */ DataSpec.HTTP_METHOD_GET,
|
||||
/* httpBody= */ null,
|
||||
/* absoluteStreamPosition= */ 1000,
|
||||
/* position= */ 1000,
|
||||
/* length= */ 5000,
|
||||
/* key= */ null,
|
||||
/* flags= */ 0,
|
||||
dataSpecRequestProperties);
|
||||
new DataSpec.Builder()
|
||||
.setUri(TEST_URL)
|
||||
.setPosition(1000)
|
||||
.setLength(5000)
|
||||
.setHttpRequestHeaders(dataSpecRequestProperties)
|
||||
.build();
|
||||
mockResponseStartSuccess();
|
||||
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
|
@ -263,7 +262,7 @@ public final class CronetDataSourceTest {
|
|||
@Test
|
||||
public void testRequestOpenGzippedCompressedReturnsDataSpecLength()
|
||||
throws HttpDataSourceException {
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, 5000);
|
||||
testResponseHeader.put("Content-Encoding", "gzip");
|
||||
testResponseHeader.put("Content-Length", Long.toString(50L));
|
||||
mockResponseStartSuccess();
|
||||
|
|
@ -292,14 +291,14 @@ public final class CronetDataSourceTest {
|
|||
@Test
|
||||
public void open_ifBodyIsSetWithoutContentTypeHeader_fails() {
|
||||
testDataSpec =
|
||||
new DataSpec(
|
||||
/* uri= */ Uri.parse(TEST_URL),
|
||||
/* postBody= */ new byte[1024],
|
||||
/* absoluteStreamPosition= */ 200,
|
||||
/* position= */ 200,
|
||||
/* length= */ 1024,
|
||||
/* key= */ "key",
|
||||
/* flags= */ 0);
|
||||
new DataSpec.Builder()
|
||||
.setUri(TEST_URL)
|
||||
.setHttpMethod(DataSpec.HTTP_METHOD_POST)
|
||||
.setHttpBody(new byte[1024])
|
||||
.setPosition(200)
|
||||
.setLength(1024)
|
||||
.setKey("key")
|
||||
.build();
|
||||
|
||||
try {
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
|
@ -481,7 +480,7 @@ public final class CronetDataSourceTest {
|
|||
mockResponseStartSuccess();
|
||||
mockReadSuccess(1000, 5000);
|
||||
testUrlResponseInfo = createUrlResponseInfo(206); // Server supports range requests.
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
||||
|
|
@ -498,7 +497,7 @@ public final class CronetDataSourceTest {
|
|||
mockResponseStartSuccess();
|
||||
mockReadSuccess(0, 7000);
|
||||
testUrlResponseInfo = createUrlResponseInfo(200); // Server does not support range requests.
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
||||
|
|
@ -571,7 +570,7 @@ public final class CronetDataSourceTest {
|
|||
|
||||
@Test
|
||||
public void testOverread() throws HttpDataSourceException {
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, 16, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, 16);
|
||||
testResponseHeader.put("Content-Length", Long.toString(16L));
|
||||
mockResponseStartSuccess();
|
||||
mockReadSuccess(0, 16);
|
||||
|
|
@ -724,7 +723,7 @@ public final class CronetDataSourceTest {
|
|||
mockResponseStartSuccess();
|
||||
mockReadSuccess(1000, 5000);
|
||||
testUrlResponseInfo = createUrlResponseInfo(206); // Server supports range requests.
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
||||
|
|
@ -743,7 +742,7 @@ public final class CronetDataSourceTest {
|
|||
mockResponseStartSuccess();
|
||||
mockReadSuccess(0, 7000);
|
||||
testUrlResponseInfo = createUrlResponseInfo(200); // Server does not support range requests.
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
||||
|
|
@ -792,7 +791,7 @@ public final class CronetDataSourceTest {
|
|||
|
||||
@Test
|
||||
public void testOverreadByteBuffer() throws HttpDataSourceException {
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, 16, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 0, 16);
|
||||
testResponseHeader.put("Content-Length", Long.toString(16L));
|
||||
mockResponseStartSuccess();
|
||||
mockReadSuccess(0, 16);
|
||||
|
|
@ -1084,7 +1083,7 @@ public final class CronetDataSourceTest {
|
|||
public void
|
||||
testRedirectParseAndAttachCookie_dataSourceHandlesSetCookie_andPreservesOriginalRequestHeadersIncludingByteRangeHeader()
|
||||
throws HttpDataSourceException {
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||
dataSourceUnderTest =
|
||||
new CronetDataSource(
|
||||
mockCronetEngine,
|
||||
|
|
@ -1271,7 +1270,7 @@ public final class CronetDataSourceTest {
|
|||
|
||||
@Test
|
||||
public void testAllowDirectExecutor() throws HttpDataSourceException {
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000, null);
|
||||
testDataSpec = new DataSpec(Uri.parse(TEST_URL), 1000, 5000);
|
||||
mockResponseStartSuccess();
|
||||
|
||||
dataSourceUnderTest.open(testDataSpec);
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ public final class FlacExtractorSeekTest {
|
|||
// Internal methods
|
||||
|
||||
private long readInputLength() throws IOException {
|
||||
DataSpec dataSpec = new DataSpec(FILE_URI, 0, C.LENGTH_UNSET, null);
|
||||
DataSpec dataSpec = new DataSpec(FILE_URI, /* position= */ 0, C.LENGTH_UNSET);
|
||||
long totalInputLength = dataSource.open(dataSpec);
|
||||
Util.closeQuietly(dataSource);
|
||||
return totalInputLength;
|
||||
|
|
@ -276,7 +276,7 @@ public final class FlacExtractorSeekTest {
|
|||
}
|
||||
|
||||
private ExtractorInput getExtractorInputFromPosition(long position) throws IOException {
|
||||
DataSpec dataSpec = new DataSpec(FILE_URI, position, totalInputLength, /* key= */ null);
|
||||
DataSpec dataSpec = new DataSpec(FILE_URI, position, totalInputLength);
|
||||
dataSource.open(dataSpec);
|
||||
return new DefaultExtractorInput(dataSource, position, totalInputLength);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.ext.okhttp;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||
|
|
@ -86,16 +85,12 @@ public class OkHttpDataSourceTest {
|
|||
dataSpecRequestProperties.put("5", dataSpecValue);
|
||||
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(
|
||||
/* uri= */ Uri.parse("http://www.google.com"),
|
||||
/* httpMethod= */ 1,
|
||||
/* httpBody= */ null,
|
||||
/* absoluteStreamPosition= */ 1000,
|
||||
/* position= */ 1000,
|
||||
/* length= */ 5000,
|
||||
/* key= */ null,
|
||||
/* flags= */ 0,
|
||||
dataSpecRequestProperties);
|
||||
new DataSpec.Builder()
|
||||
.setUri("http://www.google.com")
|
||||
.setPosition(1000)
|
||||
.setLength(5000)
|
||||
.setHttpRequestHeaders(dataSpecRequestProperties)
|
||||
.build();
|
||||
|
||||
Mockito.doAnswer(
|
||||
invocation -> {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,18 @@ public final class DataSpec {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets {@link DataSpec#uri}. Must be called before {@link #build()}.
|
||||
* Sets {@link DataSpec#uri}.
|
||||
*
|
||||
* @param uriString The {@link DataSpec#uri}.
|
||||
* @return The builder.
|
||||
*/
|
||||
public Builder setUri(String uriString) {
|
||||
this.uri = Uri.parse(uriString);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets {@link DataSpec#uri}.
|
||||
*
|
||||
* @param uri The {@link DataSpec#uri}.
|
||||
* @return The builder.
|
||||
|
|
@ -185,7 +196,7 @@ public final class DataSpec {
|
|||
* Builds a {@link DataSpec} with the builder's current values.
|
||||
*
|
||||
* @return The build {@link DataSpec}.
|
||||
* @throws IllegalStateException If {@link #setUri(Uri)} has not been called.
|
||||
* @throws IllegalStateException If {@link #setUri} has not been called.
|
||||
*/
|
||||
public DataSpec build() {
|
||||
Assertions.checkStateNotNull(uri, "The uri must be set.");
|
||||
|
|
@ -353,15 +364,39 @@ public final class DataSpec {
|
|||
* @param uri {@link #uri}.
|
||||
*/
|
||||
public DataSpec(Uri uri) {
|
||||
this(uri, /* flags= */ 0);
|
||||
this(uri, /* position= */ 0, /* length= */ C.LENGTH_UNSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @param uri {@link #uri}.
|
||||
* @param position {@link #position}.
|
||||
* @param length {@link #length}.
|
||||
*/
|
||||
public DataSpec(Uri uri, long position, long length) {
|
||||
this(
|
||||
uri,
|
||||
/* uriPositionOffset= */ 0,
|
||||
HTTP_METHOD_GET,
|
||||
/* httpBody= */ null,
|
||||
/* httpRequestHeaders= */ Collections.emptyMap(),
|
||||
position,
|
||||
length,
|
||||
/* key= */ null,
|
||||
/* flags= */ 0,
|
||||
/* customData= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param flags {@link #flags}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public DataSpec(Uri uri, @Flags int flags) {
|
||||
this(uri, /* position= */ 0, C.LENGTH_UNSET, /* key= */ null, flags);
|
||||
}
|
||||
|
|
@ -369,11 +404,14 @@ public final class DataSpec {
|
|||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param position {@link #position}.
|
||||
* @param length {@link #length}.
|
||||
* @param key {@link #key}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public DataSpec(Uri uri, long position, long length, @Nullable String key) {
|
||||
this(uri, position, position, length, key, /* flags= */ 0);
|
||||
}
|
||||
|
|
@ -381,12 +419,15 @@ public final class DataSpec {
|
|||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param position {@link #position}.
|
||||
* @param length {@link #length}.
|
||||
* @param key {@link #key}.
|
||||
* @param flags {@link #flags}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public DataSpec(Uri uri, long position, long length, @Nullable String key, @Flags int flags) {
|
||||
this(uri, position, position, length, key, flags);
|
||||
}
|
||||
|
|
@ -394,6 +435,7 @@ public final class DataSpec {
|
|||
/**
|
||||
* Constructs an instance.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param position {@link #position}, equal to {@link #position}.
|
||||
* @param length {@link #length}.
|
||||
|
|
@ -401,6 +443,8 @@ public final class DataSpec {
|
|||
* @param flags {@link #flags}.
|
||||
* @param httpRequestHeaders {@link #httpRequestHeaders}
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public DataSpec(
|
||||
Uri uri,
|
||||
long position,
|
||||
|
|
@ -423,6 +467,7 @@ public final class DataSpec {
|
|||
/**
|
||||
* Constructs an instance where {@link #uriPositionOffset} may be non-zero.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param absoluteStreamPosition The sum of {@link #uriPositionOffset} and {@link #position}.
|
||||
* @param position {@link #position}.
|
||||
|
|
@ -430,6 +475,8 @@ public final class DataSpec {
|
|||
* @param key {@link #key}.
|
||||
* @param flags {@link #flags}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public DataSpec(
|
||||
Uri uri,
|
||||
long absoluteStreamPosition,
|
||||
|
|
@ -446,6 +493,7 @@ public final class DataSpec {
|
|||
* set to {@link #HTTP_METHOD_POST}. If {@code postBody} is null then {@link #httpMethod} is set
|
||||
* to {@link #HTTP_METHOD_GET}.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param postBody {@link #httpBody} The body of the HTTP request, which is also used to infer the
|
||||
* {@link #httpMethod}.
|
||||
|
|
@ -455,6 +503,8 @@ public final class DataSpec {
|
|||
* @param key {@link #key}.
|
||||
* @param flags {@link #flags}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public DataSpec(
|
||||
Uri uri,
|
||||
@Nullable byte[] postBody,
|
||||
|
|
@ -477,6 +527,7 @@ public final class DataSpec {
|
|||
/**
|
||||
* Construct a instance where {@link #uriPositionOffset} may be non-zero.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param httpMethod {@link #httpMethod}.
|
||||
* @param httpBody {@link #httpBody}.
|
||||
|
|
@ -486,6 +537,8 @@ public final class DataSpec {
|
|||
* @param key {@link #key}.
|
||||
* @param flags {@link #flags}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Deprecated
|
||||
public DataSpec(
|
||||
Uri uri,
|
||||
@HttpMethod int httpMethod,
|
||||
|
|
@ -510,6 +563,7 @@ public final class DataSpec {
|
|||
/**
|
||||
* Construct a instance where {@link #uriPositionOffset} may be non-zero.
|
||||
*
|
||||
* @deprecated Use {@link Builder}.
|
||||
* @param uri {@link #uri}.
|
||||
* @param httpMethod {@link #httpMethod}.
|
||||
* @param httpBody {@link #httpBody}.
|
||||
|
|
@ -520,6 +574,7 @@ public final class DataSpec {
|
|||
* @param flags {@link #flags}.
|
||||
* @param httpRequestHeaders {@link #httpRequestHeaders}.
|
||||
*/
|
||||
@Deprecated
|
||||
public DataSpec(
|
||||
Uri uri,
|
||||
@HttpMethod int httpMethod,
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import static junit.framework.TestCase.fail;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import java.util.HashMap;
|
||||
|
|
@ -31,6 +32,7 @@ import org.junit.runner.RunWith;
|
|||
@RunWith(AndroidJUnit4.class)
|
||||
public class DataSpecTest {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void createDataSpec_withDefaultValues() {
|
||||
Uri uri = Uri.parse("www.google.com");
|
||||
|
|
@ -212,11 +214,12 @@ public class DataSpecTest {
|
|||
assertHttpRequestHeadersReadOnly(dataSpec);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test
|
||||
public void createDataSpec_setsHttpMethodAndPostBody() {
|
||||
Uri uri = Uri.parse("www.google.com");
|
||||
|
||||
byte[] postBody = new byte[] {0, 1, 2, 3};
|
||||
@Nullable byte[] postBody = new byte[] {0, 1, 2, 3};
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(
|
||||
uri,
|
||||
|
|
@ -259,7 +262,7 @@ public class DataSpecTest {
|
|||
@Test
|
||||
public void withUri_copiesHttpRequestHeaders() {
|
||||
Map<String, String> httpRequestHeaders = createHttpRequestHeaders(5);
|
||||
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestHeaders);
|
||||
DataSpec dataSpec = createDataSpecWithHttpRequestHeaders(httpRequestHeaders);
|
||||
|
||||
DataSpec dataSpecCopy = dataSpec.withUri(Uri.parse("www.new-uri.com"));
|
||||
|
||||
|
|
@ -269,7 +272,7 @@ public class DataSpecTest {
|
|||
@Test
|
||||
public void subrange_copiesHttpRequestHeaders() {
|
||||
Map<String, String> httpRequestHeaders = createHttpRequestHeaders(5);
|
||||
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestHeaders);
|
||||
DataSpec dataSpec = createDataSpecWithHttpRequestHeaders(httpRequestHeaders);
|
||||
|
||||
DataSpec dataSpecCopy = dataSpec.subrange(2);
|
||||
|
||||
|
|
@ -279,7 +282,7 @@ public class DataSpecTest {
|
|||
@Test
|
||||
public void subrange_withOffsetAndLength_copiesHttpRequestHeaders() {
|
||||
Map<String, String> httpRequestHeaders = createHttpRequestHeaders(5);
|
||||
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestHeaders);
|
||||
DataSpec dataSpec = createDataSpecWithHttpRequestHeaders(httpRequestHeaders);
|
||||
|
||||
DataSpec dataSpecCopy = dataSpec.subrange(2, 2);
|
||||
|
||||
|
|
@ -289,7 +292,7 @@ public class DataSpecTest {
|
|||
@Test
|
||||
public void withRequestHeaders_setsCorrectHeaders() {
|
||||
Map<String, String> httpRequestHeaders = createHttpRequestHeaders(5);
|
||||
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestHeaders);
|
||||
DataSpec dataSpec = createDataSpecWithHttpRequestHeaders(httpRequestHeaders);
|
||||
|
||||
Map<String, String> newRequestHeaders = createHttpRequestHeaders(5, 10);
|
||||
DataSpec dataSpecCopy = dataSpec.withRequestHeaders(newRequestHeaders);
|
||||
|
|
@ -300,7 +303,7 @@ public class DataSpecTest {
|
|||
@Test
|
||||
public void withAdditionalHeaders_setsCorrectHeaders() {
|
||||
Map<String, String> httpRequestHeaders = createHttpRequestHeaders(5);
|
||||
DataSpec dataSpec = createDataSpecWithHeaders(httpRequestHeaders);
|
||||
DataSpec dataSpec = createDataSpecWithHttpRequestHeaders(httpRequestHeaders);
|
||||
Map<String, String> additionalHeaders = createHttpRequestHeaders(5, 10);
|
||||
// additionalHeaders may overwrite a header key
|
||||
String existingKey = httpRequestHeaders.keySet().iterator().next();
|
||||
|
|
@ -328,17 +331,12 @@ public class DataSpecTest {
|
|||
return httpRequestParameters;
|
||||
}
|
||||
|
||||
private static DataSpec createDataSpecWithHeaders(Map<String, String> httpRequestHeaders) {
|
||||
return new DataSpec(
|
||||
Uri.parse("www.google.com"),
|
||||
/* httpMethod= */ 0,
|
||||
/* httpBody= */ new byte[] {0, 0, 0, 0},
|
||||
/* absoluteStreamPosition= */ 0,
|
||||
/* position= */ 0,
|
||||
/* length= */ 1,
|
||||
/* key= */ "key",
|
||||
/* flags= */ 0,
|
||||
httpRequestHeaders);
|
||||
private static DataSpec createDataSpecWithHttpRequestHeaders(
|
||||
Map<String, String> httpRequestHeaders) {
|
||||
return new DataSpec.Builder()
|
||||
.setUri("www.google.com")
|
||||
.setHttpRequestHeaders(httpRequestHeaders)
|
||||
.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public final class ContentDataSourceTest {
|
|||
ContentDataSource dataSource =
|
||||
new ContentDataSource(InstrumentationRegistry.getTargetContext());
|
||||
try {
|
||||
DataSpec dataSpec = new DataSpec(contentUri, offset, length, null);
|
||||
DataSpec dataSpec = new DataSpec(contentUri, offset, length);
|
||||
byte[] completeData =
|
||||
TestUtil.getByteArray(InstrumentationRegistry.getTargetContext(), DATA_PATH);
|
||||
byte[] expectedData = Arrays.copyOfRange(completeData, offset,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.drm;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
|
@ -150,15 +149,12 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
|||
int manualRedirectCount = 0;
|
||||
while (true) {
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(
|
||||
Uri.parse(url),
|
||||
DataSpec.HTTP_METHOD_POST,
|
||||
httpBody,
|
||||
/* absoluteStreamPosition= */ 0,
|
||||
/* position= */ 0,
|
||||
/* length= */ C.LENGTH_UNSET,
|
||||
/* key= */ null,
|
||||
DataSpec.FLAG_ALLOW_GZIP);
|
||||
new DataSpec.Builder()
|
||||
.setUri(url)
|
||||
.setHttpMethod(DataSpec.HTTP_METHOD_POST)
|
||||
.setHttpBody(httpBody)
|
||||
.setFlags(DataSpec.FLAG_ALLOW_GZIP)
|
||||
.build();
|
||||
DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec);
|
||||
try {
|
||||
return Util.toByteArray(inputStream);
|
||||
|
|
@ -168,7 +164,7 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
|||
boolean manuallyRedirect =
|
||||
(e.responseCode == 307 || e.responseCode == 308)
|
||||
&& manualRedirectCount++ < MAX_MANUAL_REDIRECTS;
|
||||
String redirectUrl = manuallyRedirect ? getRedirectUrl(e) : null;
|
||||
@Nullable String redirectUrl = manuallyRedirect ? getRedirectUrl(e) : null;
|
||||
if (redirectUrl == null) {
|
||||
throw e;
|
||||
}
|
||||
|
|
@ -182,12 +178,11 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
|
|||
private static @Nullable String getRedirectUrl(InvalidResponseCodeException exception) {
|
||||
Map<String, List<String>> headerFields = exception.headerFields;
|
||||
if (headerFields != null) {
|
||||
List<String> locationHeaders = headerFields.get("Location");
|
||||
@Nullable List<String> locationHeaders = headerFields.get("Location");
|
||||
if (locationHeaders != null && !locationHeaders.isEmpty()) {
|
||||
return locationHeaders.get(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,12 +56,11 @@ public final class ProgressiveDownloader implements Downloader {
|
|||
public ProgressiveDownloader(
|
||||
Uri uri, @Nullable String customCacheKey, DownloaderConstructorHelper constructorHelper) {
|
||||
this.dataSpec =
|
||||
new DataSpec(
|
||||
uri,
|
||||
/* absoluteStreamPosition= */ 0,
|
||||
C.LENGTH_UNSET,
|
||||
customCacheKey,
|
||||
/* flags= */ DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION);
|
||||
new DataSpec.Builder()
|
||||
.setUri(uri)
|
||||
.setKey(customCacheKey)
|
||||
.setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION)
|
||||
.build();
|
||||
this.cache = constructorHelper.getCache();
|
||||
this.dataSource = constructorHelper.createCacheDataSource();
|
||||
this.cacheKeyFactory = constructorHelper.getCacheKeyFactory();
|
||||
|
|
|
|||
|
|
@ -228,12 +228,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||
}
|
||||
|
||||
protected static DataSpec getCompressibleDataSpec(Uri uri) {
|
||||
return new DataSpec(
|
||||
uri,
|
||||
/* absoluteStreamPosition= */ 0,
|
||||
/* length= */ C.LENGTH_UNSET,
|
||||
/* key= */ null,
|
||||
/* flags= */ DataSpec.FLAG_ALLOW_GZIP);
|
||||
return new DataSpec.Builder().setUri(uri).setFlags(DataSpec.FLAG_ALLOW_GZIP).build();
|
||||
}
|
||||
|
||||
private static void mergeSegments(List<Segment> segments, CacheKeyFactory keyFactory) {
|
||||
|
|
|
|||
|
|
@ -1022,13 +1022,14 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
private DataSpec buildDataSpec(long position) {
|
||||
// Disable caching if the content length cannot be resolved, since this is indicative of a
|
||||
// progressive live stream.
|
||||
return new DataSpec(
|
||||
uri,
|
||||
position,
|
||||
C.LENGTH_UNSET,
|
||||
customCacheKey,
|
||||
DataSpec.FLAG_DONT_CACHE_IF_LENGTH_UNKNOWN | DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION,
|
||||
ICY_METADATA_HEADERS);
|
||||
return new DataSpec.Builder()
|
||||
.setUri(uri)
|
||||
.setPosition(position)
|
||||
.setKey(customCacheKey)
|
||||
.setFlags(
|
||||
DataSpec.FLAG_DONT_CACHE_IF_LENGTH_UNKNOWN | DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION)
|
||||
.setHttpRequestHeaders(ICY_METADATA_HEADERS)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void setLoadPosition(long position, long timeUs) {
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ public final class SingleSampleMediaSource extends BaseMediaSource {
|
|||
this.loadErrorHandlingPolicy = loadErrorHandlingPolicy;
|
||||
this.treatLoadErrorsAsEndOfStream = treatLoadErrorsAsEndOfStream;
|
||||
this.tag = tag;
|
||||
dataSpec = new DataSpec(uri, DataSpec.FLAG_ALLOW_GZIP);
|
||||
dataSpec = new DataSpec.Builder().setUri(uri).setFlags(DataSpec.FLAG_ALLOW_GZIP).build();
|
||||
timeline =
|
||||
new SinglePeriodTimeline(
|
||||
durationUs,
|
||||
|
|
|
|||
|
|
@ -109,7 +109,11 @@ 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);
|
||||
this(
|
||||
dataSource,
|
||||
new DataSpec.Builder().setUri(uri).setFlags(DataSpec.FLAG_ALLOW_GZIP).build(),
|
||||
type,
|
||||
parser);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package com.google.android.exoplayer2.upstream;
|
|||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import java.io.IOException;
|
||||
|
|
@ -112,7 +113,7 @@ public final class ByteArrayDataSourceTest {
|
|||
boolean opened = false;
|
||||
try {
|
||||
// Open the source.
|
||||
long length = dataSource.open(new DataSpec(null, dataOffset, dataLength, null));
|
||||
long length = dataSource.open(new DataSpec(Uri.EMPTY, dataOffset, dataLength));
|
||||
opened = true;
|
||||
assertThat(expectFailOnOpen).isFalse();
|
||||
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ public final class DataSchemeDataSourceTest {
|
|||
}
|
||||
|
||||
private static DataSpec buildDataSpec(String uriString, int position, int length) {
|
||||
return new DataSpec(Uri.parse(uriString), position, length, /* key= */ null);
|
||||
return new DataSpec(Uri.parse(uriString), position, length);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package com.google.android.exoplayer2.upstream;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
|
@ -89,16 +88,13 @@ public class DefaultHttpDataSourceTest {
|
|||
dataSpecRequestProperties.put("5", dataSpecParameter);
|
||||
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(
|
||||
/* uri= */ Uri.parse("http://www.google.com"),
|
||||
/* httpMethod= */ 1,
|
||||
/* httpBody= */ new byte[] {0, 0, 0, 0},
|
||||
/* absoluteStreamPosition= */ 0,
|
||||
/* position= */ 0,
|
||||
/* length= */ 1,
|
||||
/* key= */ "key",
|
||||
/* flags= */ 0,
|
||||
dataSpecRequestProperties);
|
||||
new DataSpec.Builder()
|
||||
.setUri("http://www.google.com")
|
||||
.setHttpBody(new byte[] {0, 0, 0, 0})
|
||||
.setLength(1)
|
||||
.setKey("key")
|
||||
.setHttpRequestHeaders(dataSpecRequestProperties)
|
||||
.build();
|
||||
|
||||
defaultHttpDataSource.open(dataSpec);
|
||||
|
||||
|
|
|
|||
|
|
@ -286,11 +286,7 @@ public final class CacheDataSourceTest {
|
|||
|
||||
// An unbounded request with offset for not cached content.
|
||||
dataSpec =
|
||||
new DataSpec(
|
||||
Uri.parse("https://www.test.com/other"),
|
||||
TEST_DATA.length - 2,
|
||||
C.LENGTH_UNSET,
|
||||
/* key= */ null);
|
||||
new DataSpec(Uri.parse("https://www.test.com/other"), TEST_DATA.length - 2, C.LENGTH_UNSET);
|
||||
assertThat(cacheDataSource.open(dataSpec)).isEqualTo(C.LENGTH_UNSET);
|
||||
}
|
||||
|
||||
|
|
@ -624,12 +620,13 @@ public final class CacheDataSourceTest {
|
|||
}
|
||||
|
||||
private DataSpec buildDataSpec(long position, long length, @Nullable String key) {
|
||||
return new DataSpec(
|
||||
testDataUri,
|
||||
position,
|
||||
length,
|
||||
key,
|
||||
DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION,
|
||||
httpRequestHeaders);
|
||||
return new DataSpec.Builder()
|
||||
.setUri(testDataUri)
|
||||
.setPosition(position)
|
||||
.setLength(length)
|
||||
.setKey(key)
|
||||
.setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION)
|
||||
.setHttpRequestHeaders(httpRequestHeaders)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,25 +48,24 @@ public final class CacheDataSourceTest2 {
|
|||
private static final int EXO_CACHE_MAX_FILESIZE = 128;
|
||||
|
||||
private static final Uri URI = Uri.parse("http://test.com/content");
|
||||
private static final String KEY = "key";
|
||||
private static final byte[] DATA = TestUtil.buildTestData(8 * EXO_CACHE_MAX_FILESIZE + 1);
|
||||
|
||||
// A DataSpec that covers the full file.
|
||||
private static final DataSpec FULL = new DataSpec(URI, 0, DATA.length, KEY);
|
||||
private static final DataSpec FULL = new DataSpec(URI, 0, DATA.length);
|
||||
|
||||
private static final int OFFSET_ON_BOUNDARY = EXO_CACHE_MAX_FILESIZE;
|
||||
// A DataSpec that starts at 0 and extends to a cache file boundary.
|
||||
private static final DataSpec END_ON_BOUNDARY = new DataSpec(URI, 0, OFFSET_ON_BOUNDARY, KEY);
|
||||
private static final DataSpec END_ON_BOUNDARY = new DataSpec(URI, 0, OFFSET_ON_BOUNDARY);
|
||||
// A DataSpec that starts on the same boundary and extends to the end of the file.
|
||||
private static final DataSpec START_ON_BOUNDARY = new DataSpec(URI, OFFSET_ON_BOUNDARY,
|
||||
DATA.length - OFFSET_ON_BOUNDARY, KEY);
|
||||
private static final DataSpec START_ON_BOUNDARY =
|
||||
new DataSpec(URI, OFFSET_ON_BOUNDARY, DATA.length - OFFSET_ON_BOUNDARY);
|
||||
|
||||
private static final int OFFSET_OFF_BOUNDARY = EXO_CACHE_MAX_FILESIZE * 2 + 1;
|
||||
// A DataSpec that starts at 0 and extends to just past a cache file boundary.
|
||||
private static final DataSpec END_OFF_BOUNDARY = new DataSpec(URI, 0, OFFSET_OFF_BOUNDARY, KEY);
|
||||
private static final DataSpec END_OFF_BOUNDARY = new DataSpec(URI, 0, OFFSET_OFF_BOUNDARY);
|
||||
// A DataSpec that starts on the same boundary and extends to the end of the file.
|
||||
private static final DataSpec START_OFF_BOUNDARY = new DataSpec(URI, OFFSET_OFF_BOUNDARY,
|
||||
DATA.length - OFFSET_OFF_BOUNDARY, KEY);
|
||||
private static final DataSpec START_OFF_BOUNDARY =
|
||||
new DataSpec(URI, OFFSET_OFF_BOUNDARY, DATA.length - OFFSET_OFF_BOUNDARY);
|
||||
|
||||
@Test
|
||||
public void testWithoutEncryption() throws IOException {
|
||||
|
|
|
|||
|
|
@ -126,12 +126,12 @@ public final class CacheUtilTest {
|
|||
// If DataSpec.key is present, returns it.
|
||||
assertThat(
|
||||
CacheUtil.DEFAULT_CACHE_KEY_FACTORY.buildCacheKey(
|
||||
new DataSpec(testUri, 0, LENGTH_UNSET, key)))
|
||||
new DataSpec.Builder().setUri(testUri).setKey(key).build()))
|
||||
.isEqualTo(key);
|
||||
// If not generates a new one using DataSpec.uri.
|
||||
assertThat(
|
||||
CacheUtil.DEFAULT_CACHE_KEY_FACTORY.buildCacheKey(
|
||||
new DataSpec(testUri, 0, LENGTH_UNSET, null)))
|
||||
new DataSpec(testUri, /* position= */ 0, /* length= */ LENGTH_UNSET)))
|
||||
.isEqualTo(testUri.toString());
|
||||
}
|
||||
|
||||
|
|
@ -186,11 +186,7 @@ public final class CacheUtilTest {
|
|||
mockCache.spansAndGaps = new int[] {100, 100, 200};
|
||||
Pair<Long, Long> contentLengthAndBytesCached =
|
||||
CacheUtil.getCached(
|
||||
new DataSpec(
|
||||
Uri.parse("test"),
|
||||
/* absoluteStreamPosition= */ 100,
|
||||
/* length= */ C.LENGTH_UNSET,
|
||||
/* key= */ null),
|
||||
new DataSpec(Uri.parse("test"), /* position= */ 100, /* length= */ C.LENGTH_UNSET),
|
||||
mockCache,
|
||||
/* cacheKeyFactory= */ null);
|
||||
|
||||
|
|
@ -222,7 +218,7 @@ public final class CacheUtilTest {
|
|||
FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
|
||||
|
||||
Uri testUri = Uri.parse("test_data");
|
||||
DataSpec dataSpec = new DataSpec(testUri, 10, 20, null);
|
||||
DataSpec dataSpec = new DataSpec(testUri, /* position= */ 10, /* length= */ 20);
|
||||
CachingCounters counters = new CachingCounters();
|
||||
CacheUtil.cache(
|
||||
dataSpec, cache, /* cacheKeyFactory= */ null, dataSource, counters, /* isCanceled= */ null);
|
||||
|
|
@ -266,7 +262,7 @@ public final class CacheUtilTest {
|
|||
FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
|
||||
|
||||
Uri testUri = Uri.parse("test_data");
|
||||
DataSpec dataSpec = new DataSpec(testUri, 10, 20, null);
|
||||
DataSpec dataSpec = new DataSpec(testUri, /* position= */ 10, /* length= */ 20);
|
||||
CachingCounters counters = new CachingCounters();
|
||||
CacheUtil.cache(
|
||||
dataSpec, cache, /* cacheKeyFactory= */ null, dataSource, counters, /* isCanceled= */ null);
|
||||
|
|
@ -292,7 +288,7 @@ public final class CacheUtilTest {
|
|||
FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
|
||||
|
||||
Uri testUri = Uri.parse("test_data");
|
||||
DataSpec dataSpec = new DataSpec(testUri, 0, 1000, null);
|
||||
DataSpec dataSpec = new DataSpec(testUri, /* position= */ 0, /* length= */ 1000);
|
||||
CachingCounters counters = new CachingCounters();
|
||||
CacheUtil.cache(
|
||||
dataSpec, cache, /* cacheKeyFactory= */ null, dataSource, counters, /* isCanceled= */ null);
|
||||
|
|
@ -307,7 +303,7 @@ public final class CacheUtilTest {
|
|||
FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
|
||||
|
||||
Uri testUri = Uri.parse("test_data");
|
||||
DataSpec dataSpec = new DataSpec(testUri, 0, 1000, null);
|
||||
DataSpec dataSpec = new DataSpec(testUri, /* position= */ 0, /* length= */ 1000);
|
||||
|
||||
try {
|
||||
CacheUtil.cache(
|
||||
|
|
@ -358,8 +354,11 @@ public final class CacheUtilTest {
|
|||
FakeDataSet fakeDataSet = new FakeDataSet().setRandomData("test_data", 100);
|
||||
FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
|
||||
|
||||
Uri uri = Uri.parse("test_data");
|
||||
DataSpec dataSpec = new DataSpec(uri, DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION);
|
||||
DataSpec dataSpec =
|
||||
new DataSpec.Builder()
|
||||
.setUri("test_data")
|
||||
.setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION)
|
||||
.build();
|
||||
CacheUtil.cache(
|
||||
dataSpec,
|
||||
cache,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,22 @@ import java.util.List;
|
|||
*/
|
||||
public final class DashUtil {
|
||||
|
||||
/**
|
||||
* Builds a {@link DataSpec} for a given {@link RangedUri} belonging to {@link Representation}.
|
||||
*
|
||||
* @param representation The {@link Representation} to which the request belongs.
|
||||
* @param requestUri The {@link RangedUri} of the data to request.
|
||||
* @return The {@link DataSpec}.
|
||||
*/
|
||||
public static DataSpec buildDataSpec(Representation representation, RangedUri requestUri) {
|
||||
return new DataSpec.Builder()
|
||||
.setUri(requestUri.resolveUri(representation.baseUrl))
|
||||
.setPosition(requestUri.start)
|
||||
.setLength(requestUri.length)
|
||||
.setKey(representation.getCacheKey())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a DASH manifest.
|
||||
*
|
||||
|
|
@ -53,8 +69,7 @@ public final class DashUtil {
|
|||
* @return An instance of {@link DashManifest}.
|
||||
* @throws IOException Thrown when there is an error while loading.
|
||||
*/
|
||||
public static DashManifest loadManifest(DataSource dataSource, Uri uri)
|
||||
throws IOException {
|
||||
public static DashManifest loadManifest(DataSource dataSource, Uri uri) throws IOException {
|
||||
return ParsingLoadable.load(dataSource, new DashManifestParser(), uri, C.DATA_TYPE_MANIFEST);
|
||||
}
|
||||
|
||||
|
|
@ -176,8 +191,7 @@ public final class DashUtil {
|
|||
private static void loadInitializationData(DataSource dataSource,
|
||||
Representation representation, ChunkExtractorWrapper extractorWrapper, RangedUri requestUri)
|
||||
throws IOException, InterruptedException {
|
||||
DataSpec dataSpec = new DataSpec(requestUri.resolveUri(representation.baseUrl),
|
||||
requestUri.start, requestUri.length, representation.getCacheKey());
|
||||
DataSpec dataSpec = DashUtil.buildDataSpec(representation, requestUri);
|
||||
InitializationChunk initializationChunk = new InitializationChunk(dataSource, dataSpec,
|
||||
representation.format, C.SELECTION_REASON_UNKNOWN, null /* trackSelectionData */,
|
||||
extractorWrapper);
|
||||
|
|
|
|||
|
|
@ -487,20 +487,19 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
Object trackSelectionData,
|
||||
RangedUri initializationUri,
|
||||
RangedUri indexUri) {
|
||||
Representation representation = representationHolder.representation;
|
||||
RangedUri requestUri;
|
||||
String baseUrl = representationHolder.representation.baseUrl;
|
||||
if (initializationUri != null) {
|
||||
// It's common for initialization and index data to be stored adjacently. Attempt to merge
|
||||
// the two requests together to request both at once.
|
||||
requestUri = initializationUri.attemptMerge(indexUri, baseUrl);
|
||||
requestUri = initializationUri.attemptMerge(indexUri, representation.baseUrl);
|
||||
if (requestUri == null) {
|
||||
requestUri = initializationUri;
|
||||
}
|
||||
} else {
|
||||
requestUri = indexUri;
|
||||
}
|
||||
DataSpec dataSpec = new DataSpec(requestUri.resolveUri(baseUrl), requestUri.start,
|
||||
requestUri.length, representationHolder.representation.getCacheKey());
|
||||
DataSpec dataSpec = DashUtil.buildDataSpec(representation, requestUri);
|
||||
return new InitializationChunk(dataSource, dataSpec, trackFormat,
|
||||
trackSelectionReason, trackSelectionData, representationHolder.extractorWrapper);
|
||||
}
|
||||
|
|
@ -521,15 +520,14 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
String baseUrl = representation.baseUrl;
|
||||
if (representationHolder.extractorWrapper == null) {
|
||||
long endTimeUs = representationHolder.getSegmentEndTimeUs(firstSegmentNum);
|
||||
DataSpec dataSpec = new DataSpec(segmentUri.resolveUri(baseUrl),
|
||||
segmentUri.start, segmentUri.length, representation.getCacheKey());
|
||||
DataSpec dataSpec = DashUtil.buildDataSpec(representation, segmentUri);
|
||||
return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason,
|
||||
trackSelectionData, startTimeUs, endTimeUs, firstSegmentNum, trackType, trackFormat);
|
||||
} else {
|
||||
int segmentCount = 1;
|
||||
for (int i = 1; i < maxSegmentCount; i++) {
|
||||
RangedUri nextSegmentUri = representationHolder.getSegmentUrl(firstSegmentNum + i);
|
||||
RangedUri mergedSegmentUri = segmentUri.attemptMerge(nextSegmentUri, baseUrl);
|
||||
@Nullable RangedUri mergedSegmentUri = segmentUri.attemptMerge(nextSegmentUri, baseUrl);
|
||||
if (mergedSegmentUri == null) {
|
||||
// Unable to merge segment fetches because the URIs do not merge.
|
||||
break;
|
||||
|
|
@ -543,8 +541,7 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
periodDurationUs != C.TIME_UNSET && periodDurationUs <= endTimeUs
|
||||
? periodDurationUs
|
||||
: C.TIME_UNSET;
|
||||
DataSpec dataSpec = new DataSpec(segmentUri.resolveUri(baseUrl),
|
||||
segmentUri.start, segmentUri.length, representation.getCacheKey());
|
||||
DataSpec dataSpec = DashUtil.buildDataSpec(representation, segmentUri);
|
||||
long sampleOffsetUs = -representation.presentationTimeOffsetUs;
|
||||
return new ContainerMediaChunk(
|
||||
dataSource,
|
||||
|
|
@ -588,11 +585,8 @@ public class DefaultDashChunkSource implements DashChunkSource {
|
|||
@Override
|
||||
public DataSpec getDataSpec() {
|
||||
checkInBounds();
|
||||
Representation representation = representationHolder.representation;
|
||||
RangedUri segmentUri = representationHolder.getSegmentUrl(getCurrentIndex());
|
||||
Uri resolvedUri = segmentUri.resolveUri(representation.baseUrl);
|
||||
String cacheKey = representation.getCacheKey();
|
||||
return new DataSpec(resolvedUri, segmentUri.start, segmentUri.length, cacheKey);
|
||||
return DashUtil.buildDataSpec(representationHolder.representation, segmentUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
|
|||
private static void addSegment(
|
||||
long startTimeUs, String baseUrl, RangedUri rangedUri, ArrayList<Segment> out) {
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(rangedUri.resolveUri(baseUrl), rangedUri.start, rangedUri.length, null);
|
||||
new DataSpec(rangedUri.resolveUri(baseUrl), rangedUri.start, rangedUri.length);
|
||||
out.add(new Segment(startTimeUs, dataSpec));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,8 +201,7 @@ public final class PsExtractorSeekTest {
|
|||
// Internal methods
|
||||
|
||||
private long readInputLength() throws IOException {
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(Uri.parse("asset:///" + PS_FILE_PATH), 0, C.LENGTH_UNSET, null);
|
||||
DataSpec dataSpec = new DataSpec(Uri.parse("asset:///" + PS_FILE_PATH));
|
||||
long totalInputLength = dataSource.open(dataSpec);
|
||||
Util.closeQuietly(dataSource);
|
||||
return totalInputLength;
|
||||
|
|
@ -343,8 +342,7 @@ public final class PsExtractorSeekTest {
|
|||
|
||||
private ExtractorInput getExtractorInputFromPosition(long position) throws IOException {
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(
|
||||
Uri.parse("asset:///" + PS_FILE_PATH), position, C.LENGTH_UNSET, /* key= */ null);
|
||||
new DataSpec(Uri.parse("asset:///" + PS_FILE_PATH), position, C.LENGTH_UNSET);
|
||||
dataSource.open(dataSpec);
|
||||
return new DefaultExtractorInput(dataSource, position, totalInputLength);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -512,7 +512,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
return null;
|
||||
}
|
||||
|
||||
byte[] encryptionKey = keyCache.remove(keyUri);
|
||||
@Nullable byte[] encryptionKey = keyCache.remove(keyUri);
|
||||
if (encryptionKey != null) {
|
||||
// The key was present in the key cache. We re-insert it to prevent it from being evicted by
|
||||
// the following key addition. Note that removal of the key is necessary to affect the
|
||||
|
|
@ -520,7 +520,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
keyCache.put(keyUri, encryptionKey);
|
||||
return null;
|
||||
}
|
||||
DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP);
|
||||
DataSpec dataSpec =
|
||||
new DataSpec.Builder().setUri(keyUri).setFlags(DataSpec.FLAG_ALLOW_GZIP).build();
|
||||
return new EncryptionKeyChunk(
|
||||
encryptionDataSource,
|
||||
dataSpec,
|
||||
|
|
@ -646,8 +647,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||
checkInBounds();
|
||||
Segment segment = playlist.segments.get((int) getCurrentIndex());
|
||||
Uri chunkUri = UriUtil.resolveToUri(playlist.baseUri, segment.url);
|
||||
return new DataSpec(
|
||||
chunkUri, segment.byterangeOffset, segment.byterangeLength, /* key= */ null);
|
||||
return new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -94,9 +94,9 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||
new DataSpec(
|
||||
UriUtil.resolveToUri(mediaPlaylist.baseUri, mediaSegment.url),
|
||||
mediaSegment.byterangeOffset,
|
||||
mediaSegment.byterangeLength,
|
||||
/* key= */ null);
|
||||
mediaSegment.byterangeLength);
|
||||
boolean mediaSegmentEncrypted = mediaSegmentKey != null;
|
||||
@Nullable
|
||||
byte[] mediaSegmentIv =
|
||||
mediaSegmentEncrypted
|
||||
? getEncryptionIvArray(Assertions.checkNotNull(mediaSegment.encryptionIV))
|
||||
|
|
@ -107,20 +107,17 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||
HlsMediaPlaylist.Segment initSegment = mediaSegment.initializationSegment;
|
||||
DataSpec initDataSpec = null;
|
||||
boolean initSegmentEncrypted = false;
|
||||
DataSource initDataSource = null;
|
||||
@Nullable DataSource initDataSource = null;
|
||||
if (initSegment != null) {
|
||||
initSegmentEncrypted = initSegmentKey != null;
|
||||
@Nullable
|
||||
byte[] initSegmentIv =
|
||||
initSegmentEncrypted
|
||||
? getEncryptionIvArray(Assertions.checkNotNull(initSegment.encryptionIV))
|
||||
: null;
|
||||
Uri initSegmentUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, initSegment.url);
|
||||
initDataSpec =
|
||||
new DataSpec(
|
||||
initSegmentUri,
|
||||
initSegment.byterangeOffset,
|
||||
initSegment.byterangeLength,
|
||||
/* key= */ null);
|
||||
new DataSpec(initSegmentUri, initSegment.byterangeOffset, initSegment.byterangeLength);
|
||||
initDataSource = buildDataSource(dataSource, initSegmentKey, initSegmentIv);
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +126,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
|
|||
int discontinuitySequenceNumber =
|
||||
mediaPlaylist.discontinuitySequence + mediaSegment.relativeDiscontinuitySequence;
|
||||
|
||||
Extractor previousExtractor = null;
|
||||
@Nullable Extractor previousExtractor = null;
|
||||
Id3Decoder id3Decoder;
|
||||
ParsableByteArray scratchId3Data;
|
||||
boolean shouldSpliceIn;
|
||||
|
|
|
|||
|
|
@ -141,8 +141,7 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
|
|||
}
|
||||
}
|
||||
Uri segmentUri = UriUtil.resolveToUri(baseUri, segment.url);
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(segmentUri, segment.byterangeOffset, segment.byterangeLength, /* key= */ null);
|
||||
DataSpec dataSpec = new DataSpec(segmentUri, segment.byterangeOffset, segment.byterangeLength);
|
||||
out.add(new Segment(startTimeUs, dataSpec));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,7 +241,6 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||
trackSelection.getSelectedFormat(),
|
||||
dataSource,
|
||||
uri,
|
||||
null,
|
||||
currentAbsoluteChunkIndex,
|
||||
chunkStartTimeUs,
|
||||
chunkEndTimeUs,
|
||||
|
|
@ -270,7 +269,6 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||
Format format,
|
||||
DataSource dataSource,
|
||||
Uri uri,
|
||||
String cacheKey,
|
||||
int chunkIndex,
|
||||
long chunkStartTimeUs,
|
||||
long chunkEndTimeUs,
|
||||
|
|
@ -278,7 +276,7 @@ public class DefaultSsChunkSource implements SsChunkSource {
|
|||
int trackSelectionReason,
|
||||
Object trackSelectionData,
|
||||
ChunkExtractorWrapper extractorWrapper) {
|
||||
DataSpec dataSpec = new DataSpec(uri, 0, C.LENGTH_UNSET, cacheKey);
|
||||
DataSpec dataSpec = new DataSpec(uri);
|
||||
// In SmoothStreaming each chunk contains sample timestamps relative to the start of the chunk.
|
||||
// To convert them the absolute timestamps, we need to set sampleOffsetUs to chunkStartTimeUs.
|
||||
long sampleOffsetUs = chunkStartTimeUs;
|
||||
|
|
|
|||
|
|
@ -94,8 +94,7 @@ public final class FakeAdaptiveDataSet extends FakeDataSet {
|
|||
String uri = dataSet.getUri(trackGroupIndex);
|
||||
int chunkIndex = (int) getCurrentIndex();
|
||||
Segment fakeDataChunk = Util.castNonNull(dataSet.getData(uri)).getSegments().get(chunkIndex);
|
||||
return new DataSpec(
|
||||
Uri.parse(uri), fakeDataChunk.byteOffset, fakeDataChunk.length, /* key= */ null);
|
||||
return new DataSpec(Uri.parse(uri), fakeDataChunk.byteOffset, fakeDataChunk.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@ public final class FakeChunkSource implements ChunkSource {
|
|||
String uri = dataSet.getUri(trackGroupIndex);
|
||||
Segment fakeDataChunk =
|
||||
Assertions.checkStateNotNull(dataSet.getData(uri)).getSegments().get(chunkIndex);
|
||||
DataSpec dataSpec = new DataSpec(Uri.parse(uri), fakeDataChunk.byteOffset,
|
||||
fakeDataChunk.length, null);
|
||||
DataSpec dataSpec =
|
||||
new DataSpec(Uri.parse(uri), fakeDataChunk.byteOffset, fakeDataChunk.length);
|
||||
int trackType = MimeTypes.getTrackType(selectedFormat.sampleMimeType);
|
||||
out.chunk = new SingleSampleMediaChunk(dataSource, dataSpec, selectedFormat,
|
||||
trackSelection.getSelectionReason(), trackSelection.getSelectionData(), startTimeUs,
|
||||
|
|
|
|||
|
|
@ -45,11 +45,7 @@ public final class FakeMediaChunkIterator extends BaseMediaChunkIterator {
|
|||
@Override
|
||||
public DataSpec getDataSpec() {
|
||||
checkInBounds();
|
||||
return new DataSpec(
|
||||
Uri.EMPTY,
|
||||
/* absoluteStreamPosition= */ 0,
|
||||
chunkLengths[(int) getCurrentIndex()],
|
||||
/* key= */ null);
|
||||
return new DataSpec(Uri.EMPTY, /* position= */ 0, chunkLengths[(int) getCurrentIndex()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ public class TestUtil {
|
|||
/** Returns an {@link ExtractorInput} to read from the given input at given position. */
|
||||
public static ExtractorInput getExtractorInputFromPosition(
|
||||
DataSource dataSource, long position, Uri uri) throws IOException {
|
||||
DataSpec dataSpec = new DataSpec(uri, position, C.LENGTH_UNSET, /* key= */ null);
|
||||
DataSpec dataSpec = new DataSpec(uri, position, C.LENGTH_UNSET);
|
||||
long length = dataSource.open(dataSpec);
|
||||
if (length != C.LENGTH_UNSET) {
|
||||
length += position;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public final class FakeDataSourceTest {
|
|||
@Test
|
||||
public void testReadPartialOpenEnded() throws IOException {
|
||||
FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
|
||||
assertThat(dataSource.open(new DataSpec(uri, 7, C.LENGTH_UNSET, null))).isEqualTo(8);
|
||||
assertThat(dataSource.open(new DataSpec(uri, 7, C.LENGTH_UNSET))).isEqualTo(8);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(3);
|
||||
assertBuffer(TEST_DATA_PART_1, 7, 3);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(5);
|
||||
|
|
@ -81,7 +81,7 @@ public final class FakeDataSourceTest {
|
|||
@Test
|
||||
public void testReadPartialBounded() throws IOException {
|
||||
FakeDataSource dataSource = new FakeDataSource(fakeDataSet);
|
||||
assertThat(dataSource.open(new DataSpec(uri, 9, 3, null))).isEqualTo(3);
|
||||
assertThat(dataSource.open(new DataSpec(uri, 9, 3))).isEqualTo(3);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(1);
|
||||
assertBuffer(TEST_DATA_PART_1, 9, 1);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(2);
|
||||
|
|
@ -89,7 +89,7 @@ public final class FakeDataSourceTest {
|
|||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(C.RESULT_END_OF_INPUT);
|
||||
dataSource.close();
|
||||
|
||||
assertThat(dataSource.open(new DataSpec(uri, 11, 4, null))).isEqualTo(4);
|
||||
assertThat(dataSource.open(new DataSpec(uri, 11, 4))).isEqualTo(4);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(4);
|
||||
assertBuffer(TEST_DATA_PART_2, 1, 4);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(C.RESULT_END_OF_INPUT);
|
||||
|
|
@ -143,7 +143,7 @@ public final class FakeDataSourceTest {
|
|||
assertThat(e).hasMessageThat().isEqualTo(errorMessage);
|
||||
}
|
||||
dataSource.close();
|
||||
assertThat(dataSource.open(new DataSpec(uri, 15, 15, null))).isEqualTo(15);
|
||||
assertThat(dataSource.open(new DataSpec(uri, 15, 15))).isEqualTo(15);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(15);
|
||||
assertBuffer(TEST_DATA);
|
||||
assertThat(dataSource.read(BUFFER, 0, BUFFER.length)).isEqualTo(C.RESULT_END_OF_INPUT);
|
||||
|
|
@ -220,7 +220,7 @@ public final class FakeDataSourceTest {
|
|||
.appendReadData(TestUtil.buildTestData(10))
|
||||
.endData());
|
||||
try {
|
||||
dataSource.open(new DataSpec(uri, 5, 10, null));
|
||||
dataSource.open(new DataSpec(uri, 5, 10));
|
||||
fail("IOException expected.");
|
||||
} catch (IOException e) {
|
||||
// Expected.
|
||||
|
|
|
|||
Loading…
Reference in a new issue