Skip previously loaded HLS data after an error occurs.
Github issue: #183
This commit is contained in:
parent
1344b36da9
commit
87ca1b3465
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer.hls;
|
package com.google.android.exoplayer.hls;
|
||||||
|
|
||||||
import com.google.android.exoplayer.C;
|
|
||||||
import com.google.android.exoplayer.upstream.DataSource;
|
import com.google.android.exoplayer.upstream.DataSource;
|
||||||
import com.google.android.exoplayer.upstream.DataSpec;
|
import com.google.android.exoplayer.upstream.DataSpec;
|
||||||
|
|
||||||
@ -26,6 +25,8 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public final class TsChunk extends HlsChunk {
|
public final class TsChunk extends HlsChunk {
|
||||||
|
|
||||||
|
private static final byte[] SCRATCH_SPACE = new byte[4096];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The index of the variant in the master playlist.
|
* The index of the variant in the master playlist.
|
||||||
*/
|
*/
|
||||||
@ -51,7 +52,7 @@ public final class TsChunk extends HlsChunk {
|
|||||||
*/
|
*/
|
||||||
public final TsExtractor extractor;
|
public final TsExtractor extractor;
|
||||||
|
|
||||||
private volatile int loadPosition;
|
private int loadPosition;
|
||||||
private volatile boolean loadFinished;
|
private volatile boolean loadFinished;
|
||||||
private volatile boolean loadCanceled;
|
private volatile boolean loadCanceled;
|
||||||
|
|
||||||
@ -99,20 +100,28 @@ public final class TsChunk extends HlsChunk {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() throws IOException, InterruptedException {
|
public void load() throws IOException, InterruptedException {
|
||||||
DataSpec loadDataSpec;
|
|
||||||
if (loadPosition == 0) {
|
|
||||||
loadDataSpec = dataSpec;
|
|
||||||
} else {
|
|
||||||
long remainingLength = dataSpec.length != C.LENGTH_UNBOUNDED
|
|
||||||
? dataSpec.length - loadPosition : C.LENGTH_UNBOUNDED;
|
|
||||||
loadDataSpec = new DataSpec(dataSpec.uri, dataSpec.position + loadPosition,
|
|
||||||
remainingLength, dataSpec.key);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
dataSource.open(loadDataSpec);
|
dataSource.open(dataSpec);
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
|
int bytesSkipped = 0;
|
||||||
|
// If we previously fed part of this chunk to the extractor, skip it this time.
|
||||||
|
// TODO: Ideally we'd construct a dataSpec that only loads the remainder of the data here,
|
||||||
|
// rather than loading the whole chunk again and then skipping data we previously loaded. To
|
||||||
|
// do this is straightforward for non-encrypted content, but more complicated for content
|
||||||
|
// encrypted with AES, for which we'll need to modify the way that decryption is performed.
|
||||||
|
while (bytesRead != -1 && !loadCanceled && bytesSkipped < loadPosition) {
|
||||||
|
int skipLength = Math.min(loadPosition - bytesSkipped, SCRATCH_SPACE.length);
|
||||||
|
bytesRead = dataSource.read(SCRATCH_SPACE, 0, skipLength);
|
||||||
|
if (bytesRead != -1) {
|
||||||
|
bytesSkipped += bytesRead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Feed the remaining data into the extractor.
|
||||||
while (bytesRead != -1 && !loadCanceled) {
|
while (bytesRead != -1 && !loadCanceled) {
|
||||||
bytesRead = extractor.read(dataSource);
|
bytesRead = extractor.read(dataSource);
|
||||||
|
if (bytesRead != -1) {
|
||||||
|
loadPosition += bytesRead;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
loadFinished = !loadCanceled;
|
loadFinished = !loadCanceled;
|
||||||
} finally {
|
} finally {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user