Merge pull request #7867 from GeneticGenesis:pc/update-expected-http-statuses-for-failover

PiperOrigin-RevId: 338051017
This commit is contained in:
Oliver Woodman 2020-10-20 14:52:14 +01:00
parent d2fb9dda82
commit 452f68fb6c
3 changed files with 42 additions and 21 deletions

View File

@ -51,6 +51,9 @@
([#8005](https://github.com/google/ExoPlayer/issues/8005)). ([#8005](https://github.com/google/ExoPlayer/issues/8005)).
* Make FLV files seekable by using the key frame index * Make FLV files seekable by using the key frame index
([#7378](https://github.com/google/ExoPlayer/issues/7378)). ([#7378](https://github.com/google/ExoPlayer/issues/7378)).
* Adaptive playback (DASH / HLS / SmoothStreaming):
* Add 403, 500 and 503 to the list of HTTP status codes that can trigger
failover to another quality variant.
* HLS: * HLS:
* Fix crash affecting chunkful preparation of master playlists that start * Fix crash affecting chunkful preparation of master playlists that start
with an I-FRAME only variant with an I-FRAME only variant

View File

@ -72,9 +72,12 @@ public class DefaultLoadErrorHandlingPolicy implements LoadErrorHandlingPolicy {
IOException exception = loadErrorInfo.exception; IOException exception = loadErrorInfo.exception;
if (exception instanceof InvalidResponseCodeException) { if (exception instanceof InvalidResponseCodeException) {
int responseCode = ((InvalidResponseCodeException) exception).responseCode; int responseCode = ((InvalidResponseCodeException) exception).responseCode;
return responseCode == 404 // HTTP 404 Not Found. return responseCode == 403 // HTTP 403 Forbidden.
|| responseCode == 404 // HTTP 404 Not Found.
|| responseCode == 410 // HTTP 410 Gone. || responseCode == 410 // HTTP 410 Gone.
|| responseCode == 416 // HTTP 416 Range Not Satisfiable. || responseCode == 416 // HTTP 416 Range Not Satisfiable.
|| responseCode == 500 // HTTP 500 Internal Server Error.
|| responseCode == 503 // HTTP 503 Service Unavailable.
? DEFAULT_TRACK_BLACKLIST_MS ? DEFAULT_TRACK_BLACKLIST_MS
: C.TIME_UNSET; : C.TIME_UNSET;
} }

View File

@ -47,41 +47,46 @@ public final class DefaultLoadErrorHandlingPolicyTest {
private static final MediaLoadData PLACEHOLDER_MEDIA_LOAD_DATA = private static final MediaLoadData PLACEHOLDER_MEDIA_LOAD_DATA =
new MediaLoadData(/* dataType= */ C.DATA_TYPE_UNKNOWN); new MediaLoadData(/* dataType= */ C.DATA_TYPE_UNKNOWN);
@Test
public void getExclusionDurationMsFor_responseCode403() {
InvalidResponseCodeException exception = buildInvalidResponseCodeException(403, "Forbidden");
assertThat(getDefaultPolicyExclusionDurationMsFor(exception))
.isEqualTo(DefaultLoadErrorHandlingPolicy.DEFAULT_TRACK_BLACKLIST_MS);
}
@Test @Test
public void getExclusionDurationMsFor_responseCode404() { public void getExclusionDurationMsFor_responseCode404() {
InvalidResponseCodeException exception = InvalidResponseCodeException exception = buildInvalidResponseCodeException(404, "Not found");
new InvalidResponseCodeException(
404,
"Not Found",
Collections.emptyMap(),
new DataSpec(Uri.EMPTY),
/* responseBody= */ Util.EMPTY_BYTE_ARRAY);
assertThat(getDefaultPolicyExclusionDurationMsFor(exception)) assertThat(getDefaultPolicyExclusionDurationMsFor(exception))
.isEqualTo(DefaultLoadErrorHandlingPolicy.DEFAULT_TRACK_BLACKLIST_MS); .isEqualTo(DefaultLoadErrorHandlingPolicy.DEFAULT_TRACK_BLACKLIST_MS);
} }
@Test @Test
public void getExclusionDurationMsFor_responseCode410() { public void getExclusionDurationMsFor_responseCode410() {
InvalidResponseCodeException exception = buildInvalidResponseCodeException(410, "Gone");
assertThat(getDefaultPolicyExclusionDurationMsFor(exception))
.isEqualTo(DefaultLoadErrorHandlingPolicy.DEFAULT_TRACK_BLACKLIST_MS);
}
@Test
public void getExclusionDurationMsFor_responseCode500() {
InvalidResponseCodeException exception = InvalidResponseCodeException exception =
new InvalidResponseCodeException( buildInvalidResponseCodeException(500, "Internal server error");
410, assertThat(getDefaultPolicyExclusionDurationMsFor(exception))
"Gone", .isEqualTo(DefaultLoadErrorHandlingPolicy.DEFAULT_TRACK_BLACKLIST_MS);
Collections.emptyMap(), }
new DataSpec(Uri.EMPTY),
/* responseBody= */ Util.EMPTY_BYTE_ARRAY); @Test
public void getExclusionDurationMsFor_responseCode503() {
InvalidResponseCodeException exception =
buildInvalidResponseCodeException(503, "Service unavailable");
assertThat(getDefaultPolicyExclusionDurationMsFor(exception)) assertThat(getDefaultPolicyExclusionDurationMsFor(exception))
.isEqualTo(DefaultLoadErrorHandlingPolicy.DEFAULT_TRACK_BLACKLIST_MS); .isEqualTo(DefaultLoadErrorHandlingPolicy.DEFAULT_TRACK_BLACKLIST_MS);
} }
@Test @Test
public void getExclusionDurationMsFor_dontExcludeUnexpectedHttpCodes() { public void getExclusionDurationMsFor_dontExcludeUnexpectedHttpCodes() {
InvalidResponseCodeException exception = InvalidResponseCodeException exception = buildInvalidResponseCodeException(418, "I'm a teapot");
new InvalidResponseCodeException(
500,
"Internal Server Error",
Collections.emptyMap(),
new DataSpec(Uri.EMPTY),
/* responseBody= */ Util.EMPTY_BYTE_ARRAY);
assertThat(getDefaultPolicyExclusionDurationMsFor(exception)).isEqualTo(C.TIME_UNSET); assertThat(getDefaultPolicyExclusionDurationMsFor(exception)).isEqualTo(C.TIME_UNSET);
} }
@ -120,4 +125,14 @@ public final class DefaultLoadErrorHandlingPolicyTest {
PLACEHOLDER_LOAD_EVENT_INFO, PLACEHOLDER_MEDIA_LOAD_DATA, exception, errorCount); PLACEHOLDER_LOAD_EVENT_INFO, PLACEHOLDER_MEDIA_LOAD_DATA, exception, errorCount);
return new DefaultLoadErrorHandlingPolicy().getRetryDelayMsFor(loadErrorInfo); return new DefaultLoadErrorHandlingPolicy().getRetryDelayMsFor(loadErrorInfo);
} }
private static InvalidResponseCodeException buildInvalidResponseCodeException(
int statusCode, String message) {
return new InvalidResponseCodeException(
statusCode,
message,
Collections.emptyMap(),
new DataSpec(Uri.EMPTY),
/* responseBody= */ Util.EMPTY_BYTE_ARRAY);
}
} }