From 216303448d07556b10674743ab70cad5ac8e249b Mon Sep 17 00:00:00 2001 From: Daniel Hedenius Date: Wed, 6 May 2015 16:26:16 +0200 Subject: [PATCH] Added basic SAMI/SMI parser --- .../data/data.matchingtagsinbody.smi | 27 ++++ .../data/data.mixedmatchingtagsinbody.smi | 27 ++++ .../data/data.nomatchingtagsinbody.smi | 23 +++ parsers/parserSAMI/popcorn.parserSAMI.html | 57 ++++++++ parsers/parserSAMI/popcorn.parserSAMI.js | 81 ++++++++++ .../parserSAMI/popcorn.parserSAMI.unit.html | 44 ++++++ parsers/parserSAMI/popcorn.parserSAMI.unit.js | 138 ++++++++++++++++++ 7 files changed, 397 insertions(+) create mode 100644 parsers/parserSAMI/data/data.matchingtagsinbody.smi create mode 100644 parsers/parserSAMI/data/data.mixedmatchingtagsinbody.smi create mode 100644 parsers/parserSAMI/data/data.nomatchingtagsinbody.smi create mode 100644 parsers/parserSAMI/popcorn.parserSAMI.html create mode 100644 parsers/parserSAMI/popcorn.parserSAMI.js create mode 100644 parsers/parserSAMI/popcorn.parserSAMI.unit.html create mode 100644 parsers/parserSAMI/popcorn.parserSAMI.unit.js diff --git a/parsers/parserSAMI/data/data.matchingtagsinbody.smi b/parsers/parserSAMI/data/data.matchingtagsinbody.smi new file mode 100644 index 000000000..0b16b1208 --- /dev/null +++ b/parsers/parserSAMI/data/data.matchingtagsinbody.smi @@ -0,0 +1,27 @@ + + + + + + +

SAMI 0000 text

+
+ +

SAMI 1000 text

+
+ +

SAMI 2000 text

+
+ +

SAMI 3000 text

+
+ +
\ No newline at end of file diff --git a/parsers/parserSAMI/data/data.mixedmatchingtagsinbody.smi b/parsers/parserSAMI/data/data.mixedmatchingtagsinbody.smi new file mode 100644 index 000000000..8b3051304 --- /dev/null +++ b/parsers/parserSAMI/data/data.mixedmatchingtagsinbody.smi @@ -0,0 +1,27 @@ + + + + + + +

SAMI 0000 text

+

SAMI 0001 text

+
+ +

SAMI 1000 text + +

SAMI 2000 text

+
+ +

SAMI 3000 text

+
+ +
\ No newline at end of file diff --git a/parsers/parserSAMI/data/data.nomatchingtagsinbody.smi b/parsers/parserSAMI/data/data.nomatchingtagsinbody.smi new file mode 100644 index 000000000..b29df9664 --- /dev/null +++ b/parsers/parserSAMI/data/data.nomatchingtagsinbody.smi @@ -0,0 +1,23 @@ + + + + + + +

SAMI 0000 text + +

SAMI 1000 text + +

SAMI 2000 text + +

SAMI 3000 text + + \ No newline at end of file diff --git a/parsers/parserSAMI/popcorn.parserSAMI.html b/parsers/parserSAMI/popcorn.parserSAMI.html new file mode 100644 index 000000000..208218af7 --- /dev/null +++ b/parsers/parserSAMI/popcorn.parserSAMI.html @@ -0,0 +1,57 @@ + + + + Popcorn SAMI parser 1.0 Plug-in Demo + + + + + + + + +

Popcorn SAMI parser 1.0 Plug-in Demo

+ +
+ +
+ +

Expected Output

+
    +
  • From 0 to 1 seconds, "SAMI 0000 text" is shown in the video.
  • +
  • From 1 to 2 seconds, "SAMI 1000 text" is shown in the video.
  • +
  • From 2 to 3 seconds, "SAMI 2000 text" is shown in the video.
  • +
  • From 3 to 6 seconds, "SAMI 3000 text" is shown in the video.
  • +
+ +

Subtitle Source

+ + + \ No newline at end of file diff --git a/parsers/parserSAMI/popcorn.parserSAMI.js b/parsers/parserSAMI/popcorn.parserSAMI.js new file mode 100644 index 000000000..709a5898e --- /dev/null +++ b/parsers/parserSAMI/popcorn.parserSAMI.js @@ -0,0 +1,81 @@ +// PARSER: SAMI 1.0 +(function (Popcorn) { + /** + * SAMI popcorn parser plug-in + * Parses subtitle files in the SAMI format. + * + * @param {Object} data + * + */ + Popcorn.parser('parseSAMI', function (data) { + var subtitles = { + title: '', + remote: '', + data: [] + }, + _data, + _maxDisplayTime = 3; + + if (!data.text) { + return subtitles; + } + + _data = data.text.replace(/body/gi, 'BODY') + .replace(//gi, '

') + .replace(/<\/sync>/gi, '
'); + + _data = _data.substring(6 + _data.indexOf(''), _data.indexOf('')); + + var nextStartPosition = _data.indexOf('START='), + nextEndPosition = -1, + nextLineStartPosition = -1, + nextEndPPosition = -1, + nextEndSyncPosition = -1, + nextStartSyncPosition = - 1, + startTime; + while (-1 !== nextStartPosition) { + nextStartPosition += 6; + nextEndPosition = _data.indexOf('>', nextStartPosition); + startTime = (_data.substring(nextStartPosition, nextEndPosition).replace(/"/g, '')) / 1000; + + nextStartPosition = _data.indexOf('>', _data.indexOf('', nextStartPosition); + nextEndSyncPosition = _data.indexOf('', nextStartPosition); + nextStartSyncPosition = _data.indexOf(' nextLineStartPosition) { + // More data lines before nextEndPosition - those will be discarded + nextEndPosition = nextLineStartPosition; + } + + subtitles.data.push({ + subtitle: { + id: subtitles.data.length, + text: (_data.substring(nextStartPosition, nextEndPosition) || '').replace(/(style([^>]+)"|]+)>|<\/div>|(\r\n|\n|\r)|^[.\s]+|[.\s]+$)/gi, ''), + start: startTime, + end: null + } + }); + + nextStartPosition = _data.indexOf('START=', nextEndPosition); + } + + for(var i = 0; subtitles.data.length > i; i++){ + subtitles.data[i].subtitle.end = subtitles.data[i].subtitle.start + ((subtitles.data.length - 1 === i) + ? _maxDisplayTime + : (_maxDisplayTime >= subtitles.data[1 + i].subtitle.start - subtitles.data[i].subtitle.start) + ? subtitles.data[1 + i].subtitle.start - subtitles.data[i].subtitle.start + : _maxDisplayTime); + } + + return subtitles; + }); +})(Popcorn); \ No newline at end of file diff --git a/parsers/parserSAMI/popcorn.parserSAMI.unit.html b/parsers/parserSAMI/popcorn.parserSAMI.unit.html new file mode 100644 index 000000000..bda867e0d --- /dev/null +++ b/parsers/parserSAMI/popcorn.parserSAMI.unit.html @@ -0,0 +1,44 @@ + + + + Popcorn SAMI parser 1.0 Plug-in Test + + + + + + + + + + + + +

Popcorn SAMI parser 1.0 Plug-in Test

+

+
+

+
    +
    + + + + \ No newline at end of file diff --git a/parsers/parserSAMI/popcorn.parserSAMI.unit.js b/parsers/parserSAMI/popcorn.parserSAMI.unit.js new file mode 100644 index 000000000..6bafb001c --- /dev/null +++ b/parsers/parserSAMI/popcorn.parserSAMI.unit.js @@ -0,0 +1,138 @@ +var count = 0, + i = 0, + sub, + poppercorn, + subs = [ + { + id: 0, + text: 'SAMI 0000 text', + target: 'subtitle-container', + start: 0, + end: 1 + }, + { + id: 1, + text: 'SAMI 1000 text', + target: 'subtitle-container', + start: 1, + end: 2 + }, + { + id: 2, + text: 'SAMI 2000 text', + target: 'subtitle-container', + start: 2, + end: 3 + }, + { + id: 3, + text: 'SAMI 3000 text', + target: 'subtitle-container', + start: 3, + end: 6 + } + ], + expects = subs.length * 5 + 1, + reset = function () { + count = i = 0; + poppercorn = Popcorn('#video'); + }; + +asyncTest('Popcorn SAMI parser 1.0 Plugin - Matching Tags In Body', function () { + function plus() { + if (++count === expects) { + start(); + } + } + + reset(); + poppercorn.parseSAMI('data/data.matchingtagsinbody.smi', function () { + Popcorn.forEach(poppercorn.getTrackEvents(), function (evt) { + if( evt._natives.type === 'subtitle') { + sub = subs[i++]; + + strictEqual(evt.id, sub.id, 'Correctly parsed id of ' + evt.id); + plus(); + strictEqual(evt.start, sub.start, 'Correctly parsed start of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.text, sub.text, 'Correctly parsed text of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.target, sub.target, 'Correctly parsed target of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.end, sub.end, 'Correctly parsed end of ' + evt.id + ' at ' + evt.start); + plus(); + } + }); + + strictEqual(subs.length, i, 'Parsed all subtitles'); + plus(); + }); + + expect(expects); +}); + +asyncTest('Popcorn SAMI parser 1.0 Plugin - No Matching Tags In Body', function () { + function plus() { + if (++count === expects) { + start(); + } + } + + reset(); + poppercorn.parseSAMI('data/data.nomatchingtagsinbody.smi', function () { + Popcorn.forEach(poppercorn.getTrackEvents(), function (evt) { + if( evt._natives.type === 'subtitle') { + sub = subs[i++]; + + strictEqual(evt.id, sub.id, 'Correctly parsed id of ' + evt.id); + plus(); + strictEqual(evt.start, sub.start, 'Correctly parsed start of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.text, sub.text, 'Correctly parsed text of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.target, sub.target, 'Correctly parsed target of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.end, sub.end, 'Correctly parsed end of ' + evt.id + ' at ' + evt.start); + plus(); + } + }); + + strictEqual(subs.length, i, 'Parsed all subtitles'); + plus(); + }); + + expect(expects); +}); + +asyncTest('Popcorn SAMI parser 1.0 Plugin - Mixed Matching Tags In Body', function () { + function plus() { + if (++count === expects) { + start(); + } + } + + reset(); + poppercorn.parseSAMI('data/data.mixedmatchingtagsinbody.smi', function () { + Popcorn.forEach(poppercorn.getTrackEvents(), function (evt) { + if( evt._natives.type === 'subtitle') { + sub = subs[i++]; + + strictEqual(evt.id, sub.id, 'Correctly parsed id of ' + evt.id); + plus(); + strictEqual(evt.start, sub.start, 'Correctly parsed start of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.text, sub.text, 'Correctly parsed text of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.target, sub.target, 'Correctly parsed target of ' + evt.id + ' at ' + evt.start); + plus(); + strictEqual(evt.end, sub.end, 'Correctly parsed end of ' + evt.id + ' at ' + evt.start); + plus(); + } + }); + + strictEqual(subs.length, i, 'Parsed all subtitles'); + plus(); + }); + + expect(expects); +}); \ No newline at end of file