Commit cb46e875 by Daniel

Added parsing of optional human-readable title #EXTINF:<duration>,[<title>]

parent f432b521
...@@ -44,17 +44,17 @@ public class HlsMediaPlaylistParserTest extends TestCase { ...@@ -44,17 +44,17 @@ public class HlsMediaPlaylistParserTest extends TestCase {
+ "#EXT-X-DISCONTINUITY-SEQUENCE:4\n" + "#EXT-X-DISCONTINUITY-SEQUENCE:4\n"
+ "#EXT-X-ALLOW-CACHE:YES\n" + "#EXT-X-ALLOW-CACHE:YES\n"
+ "\n" + "\n"
+ "#EXTINF:7.975,\n" + "#EXTINF:7.975,This is a human-readable title string.\n"
+ "#EXT-X-BYTERANGE:51370@0\n" + "#EXT-X-BYTERANGE:51370@0\n"
+ "https://priv.example.com/fileSequence2679.ts\n" + "https://priv.example.com/fileSequence2679.ts\n"
+ "\n" + "\n"
+ "#EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.php?r=2680\",IV=0x1566B\n" + "#EXT-X-KEY:METHOD=AES-128,URI=\"https://priv.example.com/key.php?r=2680\",IV=0x1566B\n"
+ "#EXTINF:7.975,\n" + "#EXTINF:7.975,Title with a url https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.2.1\n"
+ "#EXT-X-BYTERANGE:51501@2147483648\n" + "#EXT-X-BYTERANGE:51501@2147483648\n"
+ "https://priv.example.com/fileSequence2680.ts\n" + "https://priv.example.com/fileSequence2680.ts\n"
+ "\n" + "\n"
+ "#EXT-X-KEY:METHOD=NONE\n" + "#EXT-X-KEY:METHOD=NONE\n"
+ "#EXTINF:7.941,\n" + "#EXTINF:7.941,Title with a uuid 123e4567-e89b-12d3-a456-426655440000\n"
+ "#EXT-X-BYTERANGE:51501\n" // @2147535149 + "#EXT-X-BYTERANGE:51501\n" // @2147535149
+ "https://priv.example.com/fileSequence2681.ts\n" + "https://priv.example.com/fileSequence2681.ts\n"
+ "\n" + "\n"
...@@ -88,6 +88,7 @@ public class HlsMediaPlaylistParserTest extends TestCase { ...@@ -88,6 +88,7 @@ public class HlsMediaPlaylistParserTest extends TestCase {
assertThat(mediaPlaylist.discontinuitySequence + segment.relativeDiscontinuitySequence) assertThat(mediaPlaylist.discontinuitySequence + segment.relativeDiscontinuitySequence)
.isEqualTo(4); .isEqualTo(4);
assertThat(segment.durationUs).isEqualTo(7975000); assertThat(segment.durationUs).isEqualTo(7975000);
assertThat(segment.title).isEqualTo("This is a human-readable title string.");
assertThat(segment.fullSegmentEncryptionKeyUri).isNull(); assertThat(segment.fullSegmentEncryptionKeyUri).isNull();
assertThat(segment.encryptionIV).isNull(); assertThat(segment.encryptionIV).isNull();
assertThat(segment.byterangeLength).isEqualTo(51370); assertThat(segment.byterangeLength).isEqualTo(51370);
...@@ -97,6 +98,7 @@ public class HlsMediaPlaylistParserTest extends TestCase { ...@@ -97,6 +98,7 @@ public class HlsMediaPlaylistParserTest extends TestCase {
segment = segments.get(1); segment = segments.get(1);
assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0); assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0);
assertThat(segment.durationUs).isEqualTo(7975000); assertThat(segment.durationUs).isEqualTo(7975000);
assertThat(segment.title).isEqualTo("Title with a url https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.2.1");
assertThat(segment.fullSegmentEncryptionKeyUri) assertThat(segment.fullSegmentEncryptionKeyUri)
.isEqualTo("https://priv.example.com/key.php?r=2680"); .isEqualTo("https://priv.example.com/key.php?r=2680");
assertThat(segment.encryptionIV).isEqualTo("0x1566B"); assertThat(segment.encryptionIV).isEqualTo("0x1566B");
...@@ -107,6 +109,7 @@ public class HlsMediaPlaylistParserTest extends TestCase { ...@@ -107,6 +109,7 @@ public class HlsMediaPlaylistParserTest extends TestCase {
segment = segments.get(2); segment = segments.get(2);
assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0); assertThat(segment.relativeDiscontinuitySequence).isEqualTo(0);
assertThat(segment.durationUs).isEqualTo(7941000); assertThat(segment.durationUs).isEqualTo(7941000);
assertThat(segment.title).isEqualTo("Title with a uuid 123e4567-e89b-12d3-a456-426655440000");
assertThat(segment.fullSegmentEncryptionKeyUri).isNull(); assertThat(segment.fullSegmentEncryptionKeyUri).isNull();
assertThat(segment.encryptionIV).isEqualTo(null); assertThat(segment.encryptionIV).isEqualTo(null);
assertThat(segment.byterangeLength).isEqualTo(51501); assertThat(segment.byterangeLength).isEqualTo(51501);
...@@ -116,6 +119,7 @@ public class HlsMediaPlaylistParserTest extends TestCase { ...@@ -116,6 +119,7 @@ public class HlsMediaPlaylistParserTest extends TestCase {
segment = segments.get(3); segment = segments.get(3);
assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1); assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1);
assertThat(segment.durationUs).isEqualTo(7975000); assertThat(segment.durationUs).isEqualTo(7975000);
assertThat(segment.title).isNull();
assertThat(segment.fullSegmentEncryptionKeyUri) assertThat(segment.fullSegmentEncryptionKeyUri)
.isEqualTo("https://priv.example.com/key.php?r=2682"); .isEqualTo("https://priv.example.com/key.php?r=2682");
// 0xA7A == 2682. // 0xA7A == 2682.
...@@ -128,6 +132,7 @@ public class HlsMediaPlaylistParserTest extends TestCase { ...@@ -128,6 +132,7 @@ public class HlsMediaPlaylistParserTest extends TestCase {
segment = segments.get(4); segment = segments.get(4);
assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1); assertThat(segment.relativeDiscontinuitySequence).isEqualTo(1);
assertThat(segment.durationUs).isEqualTo(7975000); assertThat(segment.durationUs).isEqualTo(7975000);
assertThat(segment.title).isNull();
assertThat(segment.fullSegmentEncryptionKeyUri) assertThat(segment.fullSegmentEncryptionKeyUri)
.isEqualTo("https://priv.example.com/key.php?r=2682"); .isEqualTo("https://priv.example.com/key.php?r=2682");
// 0xA7B == 2683. // 0xA7B == 2683.
......
...@@ -42,6 +42,10 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -42,6 +42,10 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
*/ */
public final long durationUs; public final long durationUs;
/** /**
* The human-readable title of the segment as defined by #EXTINF.
*/
public final String title;
/**
* The number of #EXT-X-DISCONTINUITY tags in the playlist before the segment. * The number of #EXT-X-DISCONTINUITY tags in the playlist before the segment.
*/ */
public final int relativeDiscontinuitySequence; public final int relativeDiscontinuitySequence;
...@@ -70,12 +74,13 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -70,12 +74,13 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
public final long byterangeLength; public final long byterangeLength;
public Segment(String uri, long byterangeOffset, long byterangeLength) { public Segment(String uri, long byterangeOffset, long byterangeLength) {
this(uri, 0, -1, C.TIME_UNSET, null, null, byterangeOffset, byterangeLength); this(uri, 0, null, -1, C.TIME_UNSET, null, null, byterangeOffset, byterangeLength);
} }
/** /**
* @param url See {@link #url}. * @param url See {@link #url}.
* @param durationUs See {@link #durationUs}. * @param durationUs See {@link #durationUs}.
* @param title See {@link #title}.
* @param relativeDiscontinuitySequence See {@link #relativeDiscontinuitySequence}. * @param relativeDiscontinuitySequence See {@link #relativeDiscontinuitySequence}.
* @param relativeStartTimeUs See {@link #relativeStartTimeUs}. * @param relativeStartTimeUs See {@link #relativeStartTimeUs}.
* @param fullSegmentEncryptionKeyUri See {@link #fullSegmentEncryptionKeyUri}. * @param fullSegmentEncryptionKeyUri See {@link #fullSegmentEncryptionKeyUri}.
...@@ -83,11 +88,12 @@ public final class HlsMediaPlaylist extends HlsPlaylist { ...@@ -83,11 +88,12 @@ public final class HlsMediaPlaylist extends HlsPlaylist {
* @param byterangeOffset See {@link #byterangeOffset}. * @param byterangeOffset See {@link #byterangeOffset}.
* @param byterangeLength See {@link #byterangeLength}. * @param byterangeLength See {@link #byterangeLength}.
*/ */
public Segment(String url, long durationUs, int relativeDiscontinuitySequence, public Segment(String url, long durationUs, String title, int relativeDiscontinuitySequence,
long relativeStartTimeUs, String fullSegmentEncryptionKeyUri, long relativeStartTimeUs, String fullSegmentEncryptionKeyUri,
String encryptionIV, long byterangeOffset, long byterangeLength) { String encryptionIV, long byterangeOffset, long byterangeLength) {
this.url = url; this.url = url;
this.durationUs = durationUs; this.durationUs = durationUs;
this.title = title;
this.relativeDiscontinuitySequence = relativeDiscontinuitySequence; this.relativeDiscontinuitySequence = relativeDiscontinuitySequence;
this.relativeStartTimeUs = relativeStartTimeUs; this.relativeStartTimeUs = relativeStartTimeUs;
this.fullSegmentEncryptionKeyUri = fullSegmentEncryptionKeyUri; this.fullSegmentEncryptionKeyUri = fullSegmentEncryptionKeyUri;
......
...@@ -104,7 +104,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -104,7 +104,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
private static final Pattern REGEX_MEDIA_SEQUENCE = Pattern.compile(TAG_MEDIA_SEQUENCE private static final Pattern REGEX_MEDIA_SEQUENCE = Pattern.compile(TAG_MEDIA_SEQUENCE
+ ":(\\d+)\\b"); + ":(\\d+)\\b");
private static final Pattern REGEX_MEDIA_DURATION = Pattern.compile(TAG_MEDIA_DURATION private static final Pattern REGEX_MEDIA_DURATION = Pattern.compile(TAG_MEDIA_DURATION
+ ":([\\d\\.]+)\\b"); + ":([\\d\\.]+)\\b");
private static final Pattern REGEX_MEDIA_TITLE = Pattern.compile(TAG_MEDIA_DURATION
+ ":[\\d\\.]+\\b,(.+)?");
private static final Pattern REGEX_TIME_OFFSET = Pattern.compile("TIME-OFFSET=(-?[\\d\\.]+)\\b"); private static final Pattern REGEX_TIME_OFFSET = Pattern.compile("TIME-OFFSET=(-?[\\d\\.]+)\\b");
private static final Pattern REGEX_BYTERANGE = Pattern.compile(TAG_BYTERANGE private static final Pattern REGEX_BYTERANGE = Pattern.compile(TAG_BYTERANGE
+ ":(\\d+(?:@\\d+)?)\\b"); + ":(\\d+(?:@\\d+)?)\\b");
...@@ -349,6 +351,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -349,6 +351,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
List<String> tags = new ArrayList<>(); List<String> tags = new ArrayList<>();
long segmentDurationUs = 0; long segmentDurationUs = 0;
String segmentTitle = null;
boolean hasDiscontinuitySequence = false; boolean hasDiscontinuitySequence = false;
int playlistDiscontinuitySequence = 0; int playlistDiscontinuitySequence = 0;
int relativeDiscontinuitySequence = 0; int relativeDiscontinuitySequence = 0;
...@@ -402,7 +405,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -402,7 +405,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
version = parseIntAttr(line, REGEX_VERSION); version = parseIntAttr(line, REGEX_VERSION);
} else if (line.startsWith(TAG_MEDIA_DURATION)) { } else if (line.startsWith(TAG_MEDIA_DURATION)) {
segmentDurationUs = segmentDurationUs =
(long) (parseDoubleAttr(line, REGEX_MEDIA_DURATION) * C.MICROS_PER_SECOND); (long) (parseDoubleAttr(line, REGEX_MEDIA_DURATION) * C.MICROS_PER_SECOND);
segmentTitle = parseOptionalStringAttr(line, REGEX_MEDIA_TITLE);
} else if (line.startsWith(TAG_KEY)) { } else if (line.startsWith(TAG_KEY)) {
String method = parseOptionalStringAttr(line, REGEX_METHOD); String method = parseOptionalStringAttr(line, REGEX_METHOD);
String keyFormat = parseOptionalStringAttr(line, REGEX_KEYFORMAT); String keyFormat = parseOptionalStringAttr(line, REGEX_KEYFORMAT);
...@@ -462,11 +466,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli ...@@ -462,11 +466,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
if (segmentByteRangeLength == C.LENGTH_UNSET) { if (segmentByteRangeLength == C.LENGTH_UNSET) {
segmentByteRangeOffset = 0; segmentByteRangeOffset = 0;
} }
segments.add(new Segment(line, segmentDurationUs, relativeDiscontinuitySequence, segments.add(new Segment(line, segmentDurationUs, segmentTitle, relativeDiscontinuitySequence,
segmentStartTimeUs, encryptionKeyUri, segmentEncryptionIV, segmentStartTimeUs, encryptionKeyUri, segmentEncryptionIV,
segmentByteRangeOffset, segmentByteRangeLength)); segmentByteRangeOffset, segmentByteRangeLength));
segmentStartTimeUs += segmentDurationUs; segmentStartTimeUs += segmentDurationUs;
segmentDurationUs = 0; segmentDurationUs = 0;
segmentTitle = null;
if (segmentByteRangeLength != C.LENGTH_UNSET) { if (segmentByteRangeLength != C.LENGTH_UNSET) {
segmentByteRangeOffset += segmentByteRangeLength; segmentByteRangeOffset += segmentByteRangeLength;
} }
......
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