diff --git a/src/parse-stream.js b/src/parse-stream.js index e9cf1c3..a55fac4 100644 --- a/src/parse-stream.js +++ b/src/parse-stream.js @@ -43,9 +43,14 @@ const attributeSeparator = function() { * @param {string} attributes the attribute line to parse */ const parseAttributes = function(attributes) { + const result = {}; + + if (!attributes) { + return result; + } + // split the string using attributes as the separator const attrs = attributes.split(attributeSeparator()); - const result = {}; let i = attrs.length; let attr; @@ -164,7 +169,7 @@ export default class ParseStream extends Stream { }); return; } - match = (/^#EXTINF:?([0-9\.]*)?,?(.*)?$/).exec(newLine); + match = (/^#EXTINF:([0-9\.]*)?,?(.*)?$/).exec(newLine); if (match) { event = { type: 'tag', @@ -179,7 +184,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-TARGETDURATION:?([0-9.]*)?/).exec(newLine); + match = (/^#EXT-X-TARGETDURATION:([0-9.]*)?/).exec(newLine); if (match) { event = { type: 'tag', @@ -191,7 +196,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-VERSION:?([0-9.]*)?/).exec(newLine); + match = (/^#EXT-X-VERSION:([0-9.]*)?/).exec(newLine); if (match) { event = { type: 'tag', @@ -203,7 +208,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-MEDIA-SEQUENCE:?(\-?[0-9.]*)?/).exec(newLine); + match = (/^#EXT-X-MEDIA-SEQUENCE:(\-?[0-9.]*)?/).exec(newLine); if (match) { event = { type: 'tag', @@ -215,7 +220,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-DISCONTINUITY-SEQUENCE:?(\-?[0-9.]*)?/).exec(newLine); + match = (/^#EXT-X-DISCONTINUITY-SEQUENCE:(\-?[0-9.]*)?/).exec(newLine); if (match) { event = { type: 'tag', @@ -227,7 +232,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-PLAYLIST-TYPE:?(.*)?$/).exec(newLine); + match = (/^#EXT-X-PLAYLIST-TYPE:(.*)?$/).exec(newLine); if (match) { event = { type: 'tag', @@ -239,7 +244,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-BYTERANGE:?(.*)?$/).exec(newLine); + match = (/^#EXT-X-BYTERANGE:(.*)?$/).exec(newLine); if (match) { event = Object.assign(parseByterange(match[1]), { type: 'tag', @@ -248,7 +253,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-ALLOW-CACHE:?(YES|NO)?/).exec(newLine); + match = (/^#EXT-X-ALLOW-CACHE:(YES|NO)?/).exec(newLine); if (match) { event = { type: 'tag', @@ -260,7 +265,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-MAP:?(.*)$/).exec(newLine); + match = (/^#EXT-X-MAP:(.*)$/).exec(newLine); if (match) { event = { type: 'tag', @@ -281,7 +286,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-STREAM-INF:?(.*)$/).exec(newLine); + match = (/^#EXT-X-STREAM-INF:(.*)$/).exec(newLine); if (match) { event = { type: 'tag', @@ -315,7 +320,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-MEDIA:?(.*)$/).exec(newLine); + match = (/^#EXT-X-MEDIA:(.*)$/).exec(newLine); if (match) { event = { type: 'tag', @@ -343,7 +348,7 @@ export default class ParseStream extends Stream { }); return; } - match = (/^#EXT-X-PROGRAM-DATE-TIME:?(.*)$/).exec(newLine); + match = (/^#EXT-X-PROGRAM-DATE-TIME:(.*)$/).exec(newLine); if (match) { event = { type: 'tag', @@ -356,7 +361,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-KEY:?(.*)$/).exec(newLine); + match = (/^#EXT-X-KEY:(.*)$/).exec(newLine); if (match) { event = { type: 'tag', @@ -381,7 +386,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-START:?(.*)$/).exec(newLine); + match = (/^#EXT-X-START:(.*)$/).exec(newLine); if (match) { event = { type: 'tag', @@ -396,7 +401,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-CUE-OUT-CONT:?(.*)?$/).exec(newLine); + match = (/^#EXT-X-CUE-OUT-CONT:(.*)?$/).exec(newLine); if (match) { event = { type: 'tag', @@ -410,7 +415,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-CUE-OUT:?(.*)?$/).exec(newLine); + match = (/^#EXT-X-CUE-OUT:(.*)?$/).exec(newLine); if (match) { event = { type: 'tag', @@ -424,7 +429,7 @@ export default class ParseStream extends Stream { this.trigger('data', event); return; } - match = (/^#EXT-X-CUE-IN:?(.*)?$/).exec(newLine); + match = (/^#EXT-X-CUE-IN:(.*)?$/).exec(newLine); if (match) { event = { type: 'tag', diff --git a/test/parse-stream.test.js b/test/parse-stream.test.js index c9cf912..b4097d7 100644 --- a/test/parse-stream.test.js +++ b/test/parse-stream.test.js @@ -242,7 +242,7 @@ QUnit.test('parses #EXTM3U tags', function(assert) { // #EXTINF QUnit.test('parses minimal #EXTINF tags', function(assert) { - const manifest = '#EXTINF\n'; + const manifest = '#EXTINF:\n'; let element; this.parseStream.on('data', function(elem) { @@ -319,7 +319,7 @@ QUnit.test('parses #EXTINF tags with carriage returns', function(assert) { // #EXT-X-TARGETDURATION QUnit.test('parses minimal #EXT-X-TARGETDURATION tags', function(assert) { - const manifest = '#EXT-X-TARGETDURATION\n'; + const manifest = '#EXT-X-TARGETDURATION:\n'; let element; this.parseStream.on('data', function(elem) { @@ -379,7 +379,7 @@ QUnit.test('parses #EXT-X-VERSION with a version', function(assert) { // #EXT-X-MEDIA-SEQUENCE QUnit.test('parses minimal #EXT-X-MEDIA-SEQUENCE tags', function(assert) { - const manifest = '#EXT-X-MEDIA-SEQUENCE\n'; + const manifest = '#EXT-X-MEDIA-SEQUENCE:\n'; let element; this.parseStream.on('data', function(elem) { @@ -453,7 +453,7 @@ QUnit.test('parses #EXT-X-PLAYLIST-TYPE with mutability info', function(assert) // #EXT-X-BYTERANGE QUnit.test('parses minimal #EXT-X-BYTERANGE tags', function(assert) { - const manifest = '#EXT-X-BYTERANGE\n'; + const manifest = '#EXT-X-BYTERANGE:\n'; let element; this.parseStream.on('data', function(elem) { @@ -589,7 +589,7 @@ QUnit.test('parses #EXT-X-MAP tags with arbitrary attributes', function(assert) }); // #EXT-X-STREAM-INF QUnit.test('parses minimal #EXT-X-STREAM-INF tags', function(assert) { - const manifest = '#EXT-X-STREAM-INF\n'; + const manifest = '#EXT-X-STREAM-INF:\n'; let element; this.parseStream.on('data', function(elem) { @@ -604,7 +604,7 @@ QUnit.test('parses minimal #EXT-X-STREAM-INF tags', function(assert) { }); // #EXT-X-PROGRAM-DATE-TIME QUnit.test('parses minimal EXT-X-PROGRAM-DATE-TIME tags', function(assert) { - const manifest = '#EXT-X-PROGRAM-DATE-TIME\n'; + const manifest = '#EXT-X-PROGRAM-DATE-TIME:\n'; let element; this.parseStream.on('data', function(elem) { @@ -809,16 +809,6 @@ QUnit.test('parses lightly-broken #EXT-X-KEY tags', function(assert) { 'parsed a single-quoted uri' ); - element = null; - manifest = '#EXT-X-KEYURI="https://example.com/key",METHOD=AES-128\n'; - this.lineStream.push(manifest); - assert.strictEqual(element.tagType, 'key', 'parsed the tag type'); - assert.strictEqual( - element.attributes.URI, - 'https://example.com/key', - 'inferred a colon after the tag type' - ); - element = null; manifest = '#EXT-X-KEY: URI = "https://example.com/key",METHOD=AES-128\n'; this.lineStream.push(manifest); diff --git a/test/parser.test.js b/test/parser.test.js index ab73ed0..72cd1a3 100644 --- a/test/parser.test.js +++ b/test/parser.test.js @@ -108,11 +108,10 @@ QUnit.module('m3u8s', function(hooks) { '#EXT-X-CUE-OUT:10', '#EXTINF:5,', 'ex2.ts', - '#EXT-X-CUE-OUT15', '#EXT-UKNOWN-TAG', '#EXTINF:5,', 'ex3.ts', - '#EXT-X-CUE-OUT', + '#EXT-X-CUE-OUT:', '#EXTINF:5,', 'ex3.ts', '#EXT-X-ENDLIST' @@ -122,7 +121,6 @@ QUnit.module('m3u8s', function(hooks) { this.parser.end(); assert.equal(this.parser.manifest.segments[1].cueOut, '10', 'parser attached cue out tag'); - assert.equal(this.parser.manifest.segments[2].cueOut, '15', 'cue out without : seperator'); assert.equal(this.parser.manifest.segments[3].cueOut, '', 'cue out without data'); }); @@ -135,11 +133,10 @@ QUnit.module('m3u8s', function(hooks) { '#EXT-X-CUE-OUT-CONT:10/60', '#EXTINF:5,', 'ex2.ts', - '#EXT-X-CUE-OUT-CONT15/30', '#EXT-UKNOWN-TAG', '#EXTINF:5,', 'ex3.ts', - '#EXT-X-CUE-OUT-CONT', + '#EXT-X-CUE-OUT-CONT:', '#EXTINF:5,', 'ex3.ts', '#EXT-X-ENDLIST' @@ -152,10 +149,6 @@ QUnit.module('m3u8s', function(hooks) { this.parser.manifest.segments[1].cueOutCont, '10/60', 'parser attached cue out cont tag' ); - assert.equal( - this.parser.manifest.segments[2].cueOutCont, '15/30', - 'cue out cont without : seperator' - ); assert.equal(this.parser.manifest.segments[3].cueOutCont, '', 'cue out cont without data'); }); @@ -165,14 +158,13 @@ QUnit.module('m3u8s', function(hooks) { '#EXTINF:5,', '#COMMENT', 'ex1.ts', - '#EXT-X-CUE-IN', + '#EXT-X-CUE-IN:', '#EXTINF:5,', 'ex2.ts', '#EXT-X-CUE-IN:15', '#EXT-UKNOWN-TAG', '#EXTINF:5,', 'ex3.ts', - '#EXT-X-CUE-IN=abc', '#EXTINF:5,', 'ex3.ts', '#EXT-X-ENDLIST' @@ -183,10 +175,6 @@ QUnit.module('m3u8s', function(hooks) { assert.equal(this.parser.manifest.segments[1].cueIn, '', 'parser attached cue in tag'); assert.equal(this.parser.manifest.segments[2].cueIn, '15', 'cue in with data'); - assert.equal( - this.parser.manifest.segments[3].cueIn, '=abc', - 'cue in without colon seperator' - ); }); QUnit.test('parses characteristics attribute', function(assert) {