Commit 39adcabf by Oliver Woodman

Blacklist variants if media or encryption loads fail, in addition

to if the playlist load fails.

NB - I'm aware the casting is a bit messy, but I don't want a common
interface because I'm hopeful that TsChunk will go away at some point.

Issue: #537
parent ecf7d1be
...@@ -303,7 +303,7 @@ public class HlsChunkSource { ...@@ -303,7 +303,7 @@ public class HlsChunkSource {
Uri keyUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.encryptionKeyUri); Uri keyUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.encryptionKeyUri);
if (!keyUri.equals(encryptionKeyUri)) { if (!keyUri.equals(encryptionKeyUri)) {
// Encryption is specified and the key has changed. // Encryption is specified and the key has changed.
Chunk toReturn = newEncryptionKeyChunk(keyUri, segment.encryptionIV); Chunk toReturn = newEncryptionKeyChunk(keyUri, segment.encryptionIV, variantIndex);
return toReturn; return toReturn;
} }
if (!Util.areEqual(segment.encryptionIV, encryptionIvString)) { if (!Util.areEqual(segment.encryptionIV, encryptionIvString)) {
...@@ -381,23 +381,35 @@ public class HlsChunkSource { ...@@ -381,23 +381,35 @@ public class HlsChunkSource {
* @return True if the error was handled by the source. False otherwise. * @return True if the error was handled by the source. False otherwise.
*/ */
public boolean onChunkLoadError(Chunk chunk, IOException e) { public boolean onChunkLoadError(Chunk chunk, IOException e) {
if (chunk.bytesLoaded() == 0 && (chunk instanceof MediaPlaylistChunk) if (chunk.bytesLoaded() == 0
&& (chunk instanceof TsChunk || chunk instanceof MediaPlaylistChunk
|| chunk instanceof EncryptionKeyChunk)
&& (e instanceof InvalidResponseCodeException)) { && (e instanceof InvalidResponseCodeException)) {
InvalidResponseCodeException responseCodeException = (InvalidResponseCodeException) e; InvalidResponseCodeException responseCodeException = (InvalidResponseCodeException) e;
int responseCode = responseCodeException.responseCode; int responseCode = responseCodeException.responseCode;
if (responseCode == 404 || responseCode == 410) { if (responseCode == 404 || responseCode == 410) {
MediaPlaylistChunk playlistChunk = (MediaPlaylistChunk) chunk; int variantIndex;
mediaPlaylistBlacklistTimesMs[playlistChunk.variantIndex] = SystemClock.elapsedRealtime(); if (chunk instanceof TsChunk) {
TsChunk tsChunk = (TsChunk) chunk;
variantIndex = getVariantIndex(tsChunk.format);
} else if (chunk instanceof MediaPlaylistChunk) {
MediaPlaylistChunk playlistChunk = (MediaPlaylistChunk) chunk;
variantIndex = playlistChunk.variantIndex;
} else {
EncryptionKeyChunk encryptionChunk = (EncryptionKeyChunk) chunk;
variantIndex = encryptionChunk.variantIndex;
}
mediaPlaylistBlacklistTimesMs[variantIndex] = SystemClock.elapsedRealtime();
if (!allPlaylistsBlacklisted()) { if (!allPlaylistsBlacklisted()) {
// We've handled the 404/410 by blacklisting the playlist. // We've handled the 404/410 by blacklisting the playlist.
Log.w(TAG, "Blacklisted playlist (" + responseCode + "): " Log.w(TAG, "Blacklisted playlist (" + responseCode + "): "
+ playlistChunk.dataSpec.uri); + chunk.dataSpec.uri);
return true; return true;
} else { } else {
// This was the last non-blacklisted playlist. Don't blacklist it. // This was the last non-blacklisted playlist. Don't blacklist it.
Log.w(TAG, "Final playlist not blacklisted (" + responseCode + "): " Log.w(TAG, "Final playlist not blacklisted (" + responseCode + "): "
+ playlistChunk.dataSpec.uri); + chunk.dataSpec.uri);
mediaPlaylistBlacklistTimesMs[playlistChunk.variantIndex] = 0; mediaPlaylistBlacklistTimesMs[variantIndex] = 0;
return false; return false;
} }
} }
...@@ -476,9 +488,9 @@ public class HlsChunkSource { ...@@ -476,9 +488,9 @@ public class HlsChunkSource {
mediaPlaylistUri.toString()); mediaPlaylistUri.toString());
} }
private EncryptionKeyChunk newEncryptionKeyChunk(Uri keyUri, String iv) { private EncryptionKeyChunk newEncryptionKeyChunk(Uri keyUri, String iv, int variantIndex) {
DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNBOUNDED, null, DataSpec.FLAG_ALLOW_GZIP); DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNBOUNDED, null, DataSpec.FLAG_ALLOW_GZIP);
return new EncryptionKeyChunk(dataSource, dataSpec, scratchSpace, iv); return new EncryptionKeyChunk(dataSource, dataSpec, scratchSpace, iv, variantIndex);
} }
/* package */ void setEncryptionData(Uri keyUri, String iv, byte[] secretKey) { /* package */ void setEncryptionData(Uri keyUri, String iv, byte[] secretKey) {
...@@ -635,13 +647,15 @@ public class HlsChunkSource { ...@@ -635,13 +647,15 @@ public class HlsChunkSource {
private static class EncryptionKeyChunk extends DataChunk { private static class EncryptionKeyChunk extends DataChunk {
public final String iv; public final String iv;
public final int variantIndex;
private byte[] result; private byte[] result;
public EncryptionKeyChunk(DataSource dataSource, DataSpec dataSpec, byte[] scratchSpace, public EncryptionKeyChunk(DataSource dataSource, DataSpec dataSpec, byte[] scratchSpace,
String iv) { String iv, int variantIndex) {
super(dataSource, dataSpec, Chunk.TYPE_DRM, Chunk.TRIGGER_UNSPECIFIED, null, scratchSpace); super(dataSource, dataSpec, Chunk.TYPE_DRM, Chunk.TRIGGER_UNSPECIFIED, null, scratchSpace);
this.iv = iv; this.iv = iv;
this.variantIndex = variantIndex;
} }
@Override @Override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment