mirror of
https://github.com/androidx/media.git
synced 2025-05-16 20:19:57 +08:00
Add EXT-X-BYTERANGE support #139
This commit is contained in:
parent
360d452dad
commit
3abcefa00c
@ -138,6 +138,9 @@ package com.google.android.exoplayer.demo;
|
||||
new Sample("Apple master playlist", "uid:hls:applemaster",
|
||||
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/"
|
||||
+ "bipbop_4x3_variant.m3u8", DemoUtil.TYPE_HLS_MASTER, false, true),
|
||||
new Sample("Apple master playlist advanced", "uid:hls:applemasteradvanced",
|
||||
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_16x9/"
|
||||
+ "bipbop_16x9_variant.m3u8", DemoUtil.TYPE_HLS_MASTER, false, true),
|
||||
new Sample("Apple single media playlist", "uid:hls:applesinglemedia",
|
||||
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/"
|
||||
+ "prog_index.m3u8", DemoUtil.TYPE_HLS_MEDIA, false, true),
|
||||
|
@ -239,7 +239,8 @@ public class HlsChunkSource {
|
||||
} else {
|
||||
dataSource = upstreamDataSource;
|
||||
}
|
||||
DataSpec dataSpec = new DataSpec(chunkUri, 0, C.LENGTH_UNBOUNDED, null);
|
||||
DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength,
|
||||
null);
|
||||
|
||||
// Configure the extractor that will read the chunk.
|
||||
TsExtractor extractor;
|
||||
|
@ -35,9 +35,12 @@ public final class HlsMediaPlaylist {
|
||||
public final String encryptionMethod;
|
||||
public final String encryptionKeyUri;
|
||||
public final String encryptionIV;
|
||||
public final int byterangeOffset;
|
||||
public final int byterangeLength;
|
||||
|
||||
public Segment(String uri, double durationSecs, boolean discontinuity, long startTimeUs,
|
||||
String encryptionMethod, String encryptionKeyUri, String encryptionIV) {
|
||||
String encryptionMethod, String encryptionKeyUri, String encryptionIV,
|
||||
int byterangeOffset, int byterangeLength) {
|
||||
this.url = uri;
|
||||
this.durationSecs = durationSecs;
|
||||
this.discontinuity = discontinuity;
|
||||
@ -45,6 +48,8 @@ public final class HlsMediaPlaylist {
|
||||
this.encryptionMethod = encryptionMethod;
|
||||
this.encryptionKeyUri = encryptionKeyUri;
|
||||
this.encryptionIV = encryptionIV;
|
||||
this.byterangeOffset = byterangeOffset;
|
||||
this.byterangeLength = byterangeLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.google.android.exoplayer.hls;
|
||||
|
||||
import com.google.android.exoplayer.C;
|
||||
import com.google.android.exoplayer.hls.HlsMediaPlaylist.Segment;
|
||||
import com.google.android.exoplayer.util.ManifestParser;
|
||||
|
||||
@ -41,6 +42,7 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
|
||||
private static final String VERSION_TAG = "#EXT-X-VERSION";
|
||||
private static final String ENDLIST_TAG = "#EXT-X-ENDLIST";
|
||||
private static final String KEY_TAG = "#EXT-X-KEY";
|
||||
private static final String BYTERANGE_TAG = "#EXT-X-BYTERANGE";
|
||||
|
||||
private static final String METHOD_ATTR = "METHOD";
|
||||
private static final String URI_ATTR = "URI";
|
||||
@ -54,6 +56,8 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
|
||||
Pattern.compile(TARGET_DURATION_TAG + ":(\\d+)\\b");
|
||||
private static final Pattern VERSION_REGEX =
|
||||
Pattern.compile(VERSION_TAG + ":(\\d+)\\b");
|
||||
private static final Pattern BYTERANGE_REGEX =
|
||||
Pattern.compile(BYTERANGE_TAG + ":(\\d+(?:@\\d+)?)\\b");
|
||||
|
||||
private static final Pattern METHOD_ATTR_REGEX =
|
||||
Pattern.compile(METHOD_ATTR + "=([^,.*]+)");
|
||||
@ -85,6 +89,8 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
|
||||
String segmentEncryptionMethod = null;
|
||||
String segmentEncryptionKeyUri = null;
|
||||
String segmentEncryptionIV = null;
|
||||
int segmentByterangeOffset = 0;
|
||||
int segmentByterangeLength = C.LENGTH_UNBOUNDED;
|
||||
|
||||
int segmentMediaSequence = 0;
|
||||
|
||||
@ -119,16 +125,30 @@ public final class HlsMediaPlaylistParser implements ManifestParser<HlsMediaPlay
|
||||
segmentEncryptionIV = Integer.toHexString(segmentMediaSequence);
|
||||
}
|
||||
}
|
||||
} else if (line.startsWith(BYTERANGE_TAG)) {
|
||||
String byteRange = HlsParserUtil.parseStringAttr(line, BYTERANGE_REGEX, BYTERANGE_TAG);
|
||||
String[] splitByteRange = byteRange.split("@");
|
||||
segmentByterangeLength = Integer.parseInt(splitByteRange[0]);
|
||||
if (splitByteRange.length > 1) {
|
||||
segmentByterangeOffset = Integer.parseInt(splitByteRange[1]);
|
||||
}
|
||||
} else if (line.equals(DISCONTINUITY_TAG)) {
|
||||
segmentDiscontinuity = true;
|
||||
} else if (!line.startsWith("#")) {
|
||||
segmentMediaSequence++;
|
||||
if (segmentByterangeLength == C.LENGTH_UNBOUNDED) {
|
||||
segmentByterangeOffset = 0;
|
||||
}
|
||||
segments.add(new Segment(line, segmentDurationSecs, segmentDiscontinuity,
|
||||
segmentStartTimeUs, segmentEncryptionMethod, segmentEncryptionKeyUri,
|
||||
segmentEncryptionIV));
|
||||
segmentEncryptionIV, segmentByterangeOffset, segmentByterangeLength));
|
||||
segmentStartTimeUs += (long) (segmentDurationSecs * 1000000);
|
||||
segmentDiscontinuity = false;
|
||||
segmentDurationSecs = 0.0;
|
||||
if (segmentByterangeLength != C.LENGTH_UNBOUNDED) {
|
||||
segmentByterangeOffset += segmentByterangeLength;
|
||||
}
|
||||
segmentByterangeLength = C.LENGTH_UNBOUNDED;
|
||||
} else if (line.equals(ENDLIST_TAG)) {
|
||||
live = false;
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user