зеркало из https://github.com/mozilla/popcorn-js.git
replaced file name [#388]
This commit is contained in:
Родитель
4fe3f0f398
Коммит
0400d8ae11
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 SBV parser Plug-in Demo</title>
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
<script src="../../test/jquery.js"></script>
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseSBV.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener( 'DOMContentLoaded', function () {
|
||||
var p = Popcorn( '#video' )
|
||||
.volume( 0 )
|
||||
.play();
|
||||
}, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 SBV parser Plug-in Demo</h1>
|
||||
<p>From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown
|
||||
<br />From 9.712 to 13.399 seconds, "Very good, Lieutenant." is shown
|
||||
<br />From 15.042 to 18.042 seconds, "It's a trap!" is shown</p>
|
||||
<div>
|
||||
<div>
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
data-timeline-sources="data/data.sbv"
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<h4>Subtitle Source<h4>
|
||||
<iframe id="srcDisplay" src="data/data.sbv"></iframe>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,100 @@
|
|||
// PARSER: 0.1 SBV
|
||||
|
||||
(function (Popcorn) {
|
||||
|
||||
/**
|
||||
* SBV popcorn parser plug-in
|
||||
* Parses subtitle files in the SBV format.
|
||||
* Times are expected in H:MM:SS.MIL format, with hours optional
|
||||
* Subtitles which don't match expected format are ignored
|
||||
* Data parameter is given by Popcorn, will need a text.
|
||||
* Text is the file contents to be parsed
|
||||
*
|
||||
* @param {Object} data
|
||||
*
|
||||
* Example:
|
||||
0:00:02.400,0:00:07.200
|
||||
Senator, we're making our final approach into Coruscant.
|
||||
*/
|
||||
Popcorn.parser( "parseSBV", function( data ) {
|
||||
|
||||
// declare needed variables
|
||||
var retObj = {
|
||||
title: "",
|
||||
remote: "",
|
||||
data: []
|
||||
},
|
||||
subs = [],
|
||||
lines,
|
||||
i = 0,
|
||||
len = 0,
|
||||
idx = 0;
|
||||
|
||||
// [H:]MM:SS.MIL string to SS.MIL
|
||||
// Will thrown exception on bad time format
|
||||
var toSeconds = function( t_in ) {
|
||||
var t = t_in.split( ":" ),
|
||||
l = t.length-1,
|
||||
time;
|
||||
|
||||
try {
|
||||
time = parseInt( t[l-1], 10 )*60 + parseFloat( t[l], 10 );
|
||||
|
||||
// Hours optionally given
|
||||
if ( l === 2 ) {
|
||||
time += parseInt( t[0], 10 )*3600;
|
||||
}
|
||||
} catch ( e ) {
|
||||
throw "Bad cue";
|
||||
}
|
||||
|
||||
return time;
|
||||
};
|
||||
|
||||
var createTrack = function( name, attributes ) {
|
||||
var track = {};
|
||||
track[name] = attributes;
|
||||
return track;
|
||||
};
|
||||
|
||||
// Here is where the magic happens
|
||||
// Split on line breaks
|
||||
lines = data.text.split( /(?:\r\n|\r|\n)/gm );
|
||||
len = lines.length;
|
||||
|
||||
while ( i < len ) {
|
||||
var sub = {},
|
||||
text = [],
|
||||
time = lines[i++].split( "," );
|
||||
|
||||
try {
|
||||
sub.start = toSeconds( time[0] );
|
||||
sub.end = toSeconds( time[1] );
|
||||
|
||||
// Gather all lines of text
|
||||
while ( i < len && lines[i] ) {
|
||||
text.push( lines[i++] );
|
||||
}
|
||||
|
||||
// Join line breaks in text
|
||||
sub.text = text.join( "<br />" );
|
||||
subs.push( createTrack( "subtitle", sub ) );
|
||||
} catch ( e ) {
|
||||
// Bad cue, advance to end of cue
|
||||
while ( i < len && lines[i] ) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Consume empty whitespace
|
||||
while ( i < len && !lines[i] ) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
retObj.data = subs;
|
||||
|
||||
return retObj;
|
||||
});
|
||||
|
||||
})( Popcorn );
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 SBV parser Plug-in Test</title>
|
||||
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
|
||||
<script src="../../test/qunit/qunit.js"></script>
|
||||
<!--
|
||||
do not move - this must be called immediately prior to
|
||||
popcorn-api-draft.js
|
||||
-->
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseSBV.js"></script>
|
||||
<script src="popcorn.parseSBV.unit.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 SBV parser Plug-in Test</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="qunit-fixture"> </div>
|
||||
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
data-timeline-sources="data/data.sbv"
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
test( "Popcorn 0.3 SBV Parser Plugin", function () {
|
||||
|
||||
var count = 0,
|
||||
numSubs = 0,
|
||||
sub,
|
||||
poppercorn = Popcorn( "#video" ),
|
||||
subs = [
|
||||
{
|
||||
text: "Senator, we're making our final approach into Coruscant.",
|
||||
start: 2.4,
|
||||
end: 7.2
|
||||
},
|
||||
{
|
||||
text: "Very good, Lieutenant.",
|
||||
start: 9.712,
|
||||
end: 13.399
|
||||
},
|
||||
{
|
||||
text: "It's a trap!",
|
||||
start: 15.042,
|
||||
end: 18.042
|
||||
}
|
||||
],
|
||||
expects = subs.length*3 + 1;
|
||||
|
||||
function plus() {
|
||||
if ( ++count === expects ) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
poppercorn.parseSBV( document.getElementById( "video" ).getAttribute( "data-timeline-sources" ) );
|
||||
|
||||
expect(expects);
|
||||
|
||||
stop( 5000 );
|
||||
|
||||
// Allow load time
|
||||
setTimeout(function () {
|
||||
Popcorn.forEach( poppercorn.getTrackEvents(), function(evt) {
|
||||
if( evt._natives.type === "subtitle" ) {
|
||||
sub = subs[numSubs++];
|
||||
|
||||
equals( evt.start, sub.start, "Correctly parsed start of " + evt.start );
|
||||
plus();
|
||||
equals( evt.text, sub.text, "Correctly parsed text of " + evt.start );
|
||||
plus();
|
||||
equals( evt.end, sub.end, "Correctly parsed end at " + evt.start );
|
||||
plus();
|
||||
}
|
||||
});
|
||||
|
||||
equals( subs.length, numSubs, "Parsed all subtitles" );
|
||||
plus();
|
||||
|
||||
}, 500);
|
||||
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 SSA parser Plug-in Demo</title>
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
<script src="../../test/jquery.js"></script>
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseSSA.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener( 'DOMContentLoaded', function () {
|
||||
var p = Popcorn( '#video' )
|
||||
.volume( 0 )
|
||||
.play();
|
||||
}, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 SSA parser Plug-in Demo</h1>
|
||||
<p>From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown
|
||||
<br />From 9.71 to 13.39 seconds, "Very good, Lieutenant." is shown
|
||||
<br />From 15.04 to 18.04 seconds, "It's a trap!" is shown</p>
|
||||
<div>
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
data-timeline-sources="data/data.ssa"
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
</div>
|
||||
<h4>Subtitle Source<h4>
|
||||
<iframe id="srcDisplay" src="data/data.ssa"></iframe>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,132 @@
|
|||
// PARSER: 0.3 SSA/ASS
|
||||
|
||||
(function (Popcorn) {
|
||||
/**
|
||||
* SSA/ASS popcorn parser plug-in
|
||||
* Parses subtitle files in the identical SSA and ASS formats.
|
||||
* Style information is ignored, and may be found in these
|
||||
* formats: (\N \n {\pos(400,570)} {\kf89})
|
||||
* Out of the [Script Info], [V4 Styles], [Events], [Pictures],
|
||||
* and [Fonts] sections, only [Events] is processed.
|
||||
* Data parameter is given by Popcorn, will need a text.
|
||||
* Text is the file contents to be parsed
|
||||
*
|
||||
* @param {Object} data
|
||||
*
|
||||
* Example:
|
||||
[Script Info]
|
||||
Title: Testing subtitles for the SSA Format
|
||||
[V4 Styles]
|
||||
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding
|
||||
Style: Default,Arial,20,65535,65535,65535,-2147483640,-1,0,1,3,0,2,30,30,30,0,0
|
||||
[Events]
|
||||
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
|
||||
Dialogue: 0,0:00:02.40,0:00:07.20,Default,,0000,0000,0000,,Senator, {\kf89}we're \Nmaking our final \napproach into Coruscant.
|
||||
Dialogue: 0,0:00:09.71,0:00:13.39,Default,,0000,0000,0000,,{\pos(400,570)}Very good, Lieutenant.
|
||||
Dialogue: 0,0:00:15.04,0:00:18.04,Default,,0000,0000,0000,,It's \Na \ntrap!
|
||||
*
|
||||
*/
|
||||
|
||||
// Register for SSA extensions
|
||||
Popcorn.parser( "parseSSA", function( data ) {
|
||||
|
||||
// declare needed variables
|
||||
var retObj = {
|
||||
title: "",
|
||||
remote: "",
|
||||
data: []
|
||||
},
|
||||
subs = [],
|
||||
startIdx,
|
||||
endIdx,
|
||||
textIdx,
|
||||
lines,
|
||||
fields,
|
||||
numFields,
|
||||
sub,
|
||||
text,
|
||||
i = 0,
|
||||
j = 0,
|
||||
len = 0,
|
||||
fieldLen = 0;
|
||||
|
||||
// h:mm:ss.cc (centisec) string to SS.mmm
|
||||
// Returns -1 if invalid
|
||||
var toSeconds = function( t_in ) {
|
||||
var t = t_in.split( ":" ),
|
||||
l = t.length - 1;
|
||||
|
||||
// Not all there
|
||||
if ( t_in.length !== 10 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return parseInt( t[0], 10 )*3600 + parseInt( t[l-1], 10 )*60 + parseFloat( t[l], 10 );
|
||||
};
|
||||
|
||||
var createTrack = function( name, attributes ) {
|
||||
var track = {};
|
||||
track[name] = attributes;
|
||||
return track;
|
||||
};
|
||||
|
||||
// Here is where the magic happens
|
||||
// Split on line breaks
|
||||
lines = data.text.split( /(?:\r\n|\r|\n)/gm );
|
||||
len = lines.length;
|
||||
|
||||
// Ignore non-textual info
|
||||
while ( i < len && lines[i] !== "[Events]" ) {
|
||||
i++;
|
||||
}
|
||||
|
||||
fields = lines[++i].substr( 8 ).split( ", " ); // Trim 'Format: ' off front, split on delim
|
||||
numFields = fields.length;
|
||||
|
||||
//Find where in Dialogue string the start, end and text info is
|
||||
for ( ; j < numFields; j++ ) {
|
||||
if ( fields[j] === "Start" ) {
|
||||
startIdx = j;
|
||||
} else if ( fields[j] === "End" ) {
|
||||
endIdx = j;
|
||||
} else if ( fields[j] === "Text" ) {
|
||||
textIdx = j;
|
||||
}
|
||||
}
|
||||
|
||||
while ( ++i < len && lines[i] && lines[i][0] !== "[" ) {
|
||||
sub = {};
|
||||
|
||||
// Trim beginning 'Dialogue: ' and split on delim
|
||||
fields = lines[i].substr( 10 ).split( "," );
|
||||
|
||||
sub.start = toSeconds( fields[startIdx] );
|
||||
sub.end = toSeconds( fields[endIdx] );
|
||||
|
||||
// Invalid time, skip
|
||||
if ( sub.start === -1 || sub.end === -1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ( fieldLen = fields.length ) === numFields ) {
|
||||
sub.text = fields[textIdx];
|
||||
} else {
|
||||
// There were commas in the text which were split, append back together into one line
|
||||
text = [];
|
||||
|
||||
for( j = textIdx; j < fieldLen; j++ ) {
|
||||
text.push( fields[j] );
|
||||
}
|
||||
sub.text = text.join( "," );
|
||||
}
|
||||
|
||||
// Eliminate advanced styles and convert forced line breaks
|
||||
sub.text = sub.text.replace( /\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}/gi, "" ).replace( /\\N/gi, "<br />" );
|
||||
subs.push( createTrack( "subtitle", sub ) );
|
||||
}
|
||||
|
||||
retObj.data = subs;
|
||||
return retObj;
|
||||
});
|
||||
|
||||
})( Popcorn );
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 SSA parser Plug-in Test</title>
|
||||
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
|
||||
<script src="../../test/qunit/qunit.js"></script>
|
||||
<!--
|
||||
do not move - this must be called immediately prior to
|
||||
popcorn-api-draft.js
|
||||
-->
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseSSA.js"></script>
|
||||
<script src="popcorn.parseSSA.unit.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 SSA parser Plug-in Test</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="qunit-fixture"> </div>
|
||||
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
data-timeline-sources="data/data.ssa"
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
</video>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
test( "Popcorn 0.3 SSA/ASS Parser Plugin", function () {
|
||||
|
||||
var count = 0,
|
||||
numSubs = 0,
|
||||
sub,
|
||||
poppercorn = Popcorn( "#video" ),
|
||||
subs = [
|
||||
{
|
||||
text: "Senator, we're <br />making our final <br />approach into Coruscant.",
|
||||
start: 2.4,
|
||||
end: 7.2
|
||||
},
|
||||
{
|
||||
text: "Very good, Lieutenant.",
|
||||
start: 9.71,
|
||||
end: 13.39
|
||||
},
|
||||
{
|
||||
text: "It's <br />a <br />trap!",
|
||||
start: 15.04,
|
||||
end: 18.04
|
||||
}
|
||||
],
|
||||
expects = subs.length*3 + 1;
|
||||
|
||||
function plus() {
|
||||
if ( ++count === expects ) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
poppercorn.parseSSA( document.getElementById( "video" ).getAttribute( "data-timeline-sources" ) );
|
||||
|
||||
expect( expects );
|
||||
stop( 5000 );
|
||||
|
||||
// Allow load time
|
||||
setTimeout(function () {
|
||||
Popcorn.forEach( poppercorn.getTrackEvents(), function(evt) {
|
||||
if( evt._natives.type === "subtitle" ) {
|
||||
sub = subs[numSubs++];
|
||||
|
||||
equals( evt.start, sub.start, "Correctly parsed start of " + evt.start );
|
||||
plus();
|
||||
equals( evt.text, sub.text, "Correctly parsed text of " + evt.start );
|
||||
plus();
|
||||
equals( evt.end, sub.end, "Correctly parsed end at " + evt.start );
|
||||
plus();
|
||||
}
|
||||
});
|
||||
|
||||
equals( subs.length, numSubs, "Parsed all subtitles" );
|
||||
plus();
|
||||
|
||||
}, 500);
|
||||
|
||||
});
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 TTML parser Plug-in Demo</title>
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseTTML.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener( 'DOMContentLoaded', function () {
|
||||
var p = Popcorn( '#video' )
|
||||
.volume( 0 )
|
||||
.play();
|
||||
}, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 TTML parser Plug-in Demo</h1>
|
||||
<p>From 0.76 to 3.45 seconds, "It seems a paradox, does it not," is shown
|
||||
<br />From 5 to 10 seconds, "that the image formed on the Retina should be inverted?" is shown
|
||||
<br />From 10 to 16 seconds, "It is puzzling, why is it we do not see things upside-down?" is shown
|
||||
<br />From 17.2 to 23 seconds, "You have never heard the Theory, then, that the Brain also is inverted?" is shown
|
||||
<br />From 23 to 27 seconds, "No indeed! What a beautiful fact!" is shown
|
||||
<br />From 27.76 to 30.45 seconds, "It seems a paradox, does it not," is shown
|
||||
<br />From 32 to 37 seconds, "that the image formed on the Retina should be inverted?" is shown
|
||||
<br />From 37 to 43 seconds, "It is puzzling, why is it we do not see things upside-down?" is shown
|
||||
<br />From 44.2 to 50 seconds, "You have never heard the Theory, then, that the Brain also is inverted?" is shown
|
||||
<br />From 50 to 54 seconds, "No indeed! What a beautiful fact!" is shown</p>
|
||||
<div>
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
data-timeline-sources="data/data.ttml"
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<h4>Subtitle Source<h4>
|
||||
<iframe id="srcDisplay" src="data/data.ttml"></iframe>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,171 @@
|
|||
// PARSER: 0.3 TTML
|
||||
|
||||
(function (Popcorn) {
|
||||
|
||||
/**
|
||||
* TTML popcorn parser plug-in
|
||||
* Parses subtitle files in the TTML format.
|
||||
* Times may be absolute to the timeline or relative
|
||||
* Absolute times are ISO 8601 format (hh:mm:ss[.mmm])
|
||||
* Relative times are a fraction followed by a unit metric (d.ddu)
|
||||
* Relative times are relative to the time given on the parent node
|
||||
* Styling information is ignored
|
||||
* Data parameter is given by Popcorn, will need an xml.
|
||||
* Xml is the file contents to be processed
|
||||
*
|
||||
* @param {Object} data
|
||||
*
|
||||
* Example:
|
||||
<tt xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling" xmlns="http://www.w3.org/2006/04/ttaf1">
|
||||
<body region="subtitleArea">
|
||||
<div>
|
||||
<p xml:id="subtitle1" begin="0.76s" end="3.45s">
|
||||
It seems a paradox, does it not,
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</tt>
|
||||
*/
|
||||
Popcorn.parser( "parseTTML", function( data ) {
|
||||
|
||||
// declare needed variables
|
||||
var returnData = {
|
||||
title: "",
|
||||
remote: "",
|
||||
data: []
|
||||
},
|
||||
node,
|
||||
numTracks = 0,
|
||||
region;
|
||||
|
||||
// Convert time expression to SS.mmm
|
||||
// Expression may be absolute to timeline (hh:mm:ss.ms)
|
||||
// or relative ( fraction followedd by metric ) ex: 3.4s, 5.7m
|
||||
// Returns -1 if invalid
|
||||
var toSeconds = function ( t_in, offset ) {
|
||||
if ( !t_in ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var t = t_in.split( ":" ),
|
||||
l = t.length - 1,
|
||||
metric,
|
||||
multiplier,
|
||||
i;
|
||||
|
||||
// Try clock time
|
||||
if ( l >= 2 ) {
|
||||
return parseInt( t[0], 10 )*3600 + parseInt( t[l-1], 10 )*60 + parseFloat( t[l], 10 );
|
||||
}
|
||||
|
||||
// Was not clock time, assume relative time
|
||||
// Take metric from end of string (may not be single character)
|
||||
// First find metric
|
||||
for( i = t_in.length - 1; i >= 0; i-- ) {
|
||||
if ( t_in[i] <= "9" && t_in[i] >= "0" ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Point i at metric and normalize offsete time
|
||||
i++;
|
||||
metric = t_in.substr( i );
|
||||
offset = offset || 0;
|
||||
|
||||
// Determine multiplier for metric relative to seconds
|
||||
if ( metric === "h" ) {
|
||||
multiplier = 3600;
|
||||
} else if ( metric === "m" ) {
|
||||
multiplier = 60;
|
||||
} else if ( metric === "s" ) {
|
||||
multiplier = 1;
|
||||
} else if ( metric === "ms" ) {
|
||||
multiplier = 0.001;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Valid multiplier
|
||||
return parseFloat( t_in.substr( 0, i ) ) * multiplier + offset;
|
||||
};
|
||||
|
||||
// creates an object of all atrributes keyd by name
|
||||
var createTrack = function( name, attributes ) {
|
||||
var track = {};
|
||||
track[name] = attributes;
|
||||
return track;
|
||||
};
|
||||
|
||||
// Parse a node for text content
|
||||
var parseNode = function( node, timeOffset ) {
|
||||
var sub = {};
|
||||
|
||||
// Trim left and right whitespace from text and change non-explicit line breaks to spaces
|
||||
sub.text = node.textContent.replace(/^[\s]+|[\s]+$/gm, "").replace(/(?:\r\n|\r|\n)/gm, "<br />");
|
||||
sub.id = node.getAttribute( "xml:id" );
|
||||
sub.start = toSeconds ( node.getAttribute( "begin" ), timeOffset );
|
||||
sub.end = toSeconds( node.getAttribute( "end" ), timeOffset );
|
||||
sub.target = region;
|
||||
|
||||
if ( sub.end < 0 ) {
|
||||
// No end given, infer duration if possible
|
||||
// Otherwise, give end as MAX_VALUE
|
||||
sub.end = toSeconds( node.getAttribute( "duration" ), 0 );
|
||||
|
||||
if ( sub.end >= 0 ) {
|
||||
sub.end += sub.start;
|
||||
} else {
|
||||
sub.end = Number.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return sub;
|
||||
};
|
||||
|
||||
// Parse the children of the given node
|
||||
var parseChildren = function( node, timeOffset ) {
|
||||
var currNode = node.firstChild,
|
||||
sub,
|
||||
newOffset;
|
||||
|
||||
while ( currNode ) {
|
||||
if ( currNode.nodeType === 1 ) {
|
||||
if ( currNode.nodeName === "p" ) {
|
||||
// p is a teextual node, process contents as subtitle
|
||||
sub = parseNode( currNode, timeOffset );
|
||||
returnData.data.push( createTrack( "subtitle", sub ) );
|
||||
numTracks++;
|
||||
} else if ( currNode.nodeName === "div" ) {
|
||||
// div is container for subtitles, recurse
|
||||
newOffset = toSeconds( currNode.getAttribute("begin") );
|
||||
|
||||
if (newOffset < 0 ) {
|
||||
newOffset = timeOffset;
|
||||
}
|
||||
|
||||
parseChildren( currNode, newOffset );
|
||||
}
|
||||
}
|
||||
|
||||
currNode = currNode.nextSibling;
|
||||
}
|
||||
};
|
||||
|
||||
// Null checks
|
||||
if ( !data.xml || !data.xml.documentElement || !( node = data.xml.documentElement.firstChild ) ) {
|
||||
return returnData;
|
||||
}
|
||||
|
||||
// Find body tag
|
||||
while ( node.nodeName !== "body" ) {
|
||||
node = node.nextSibling;
|
||||
}
|
||||
|
||||
region = "";
|
||||
parseChildren( node, 0 );
|
||||
|
||||
return returnData;
|
||||
});
|
||||
|
||||
})( Popcorn );
|
||||
;
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 TTML parser Plug-in Test</title>
|
||||
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
|
||||
<script src="../../test/qunit/qunit.js"></script>
|
||||
<!--
|
||||
do not move - this must be called immediately prior to
|
||||
popcorn-api-draft.js
|
||||
-->
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseTTML.js"></script>
|
||||
<script src="popcorn.parseTTML.unit.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 TTML parser Plug-in Test</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="qunit-fixture"> </div>
|
||||
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
data-timeline-sources="data/unit.ttml"
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
</video>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,103 @@
|
|||
test( "Popcorn 0.3 TTML Parser Plugin", function () {
|
||||
var count = 0,
|
||||
numSubs = 0,
|
||||
sub,
|
||||
poppercorn = Popcorn( "#video" ),
|
||||
subs = [
|
||||
{
|
||||
id: "subtitle1",
|
||||
text: "It seems a paradox, does it not,",
|
||||
start: 0.76,
|
||||
end: 3.45
|
||||
},
|
||||
{
|
||||
id: "subtitle2",
|
||||
text: "that the image formed on<br />the Retina should be inverted?",
|
||||
start: 5,
|
||||
end: 10
|
||||
},
|
||||
{
|
||||
id: "subtitle3",
|
||||
text: "It is puzzling, why is it<br />we do not see things upside-down?",
|
||||
start: 10,
|
||||
end: 16
|
||||
},
|
||||
{
|
||||
id: "subtitle4",
|
||||
text: "You have never heard the Theory,<br />then, that the Brain also is inverted?",
|
||||
start: 17.2,
|
||||
end: 23
|
||||
},
|
||||
{
|
||||
id: "subtitle5",
|
||||
text: "No indeed! What a beautiful fact!",
|
||||
start: 23,
|
||||
end: 27
|
||||
},
|
||||
{
|
||||
id: "subtitle6",
|
||||
text: "It seems a paradox, does it not,",
|
||||
start: 27.76,
|
||||
end: 30.45
|
||||
},
|
||||
{
|
||||
id: "subtitle7",
|
||||
text: "that the image formed on<br />the Retina should be inverted?",
|
||||
start: 33,
|
||||
end: 37
|
||||
},
|
||||
{
|
||||
id: "subtitle8",
|
||||
text: "It is puzzling, why is it<br />we do not see things upside-down?",
|
||||
start: 37,
|
||||
end: 43
|
||||
},
|
||||
{
|
||||
id: "subtitle9",
|
||||
text: "You have never heard the Theory,<br />then, that the Brain also is inverted?",
|
||||
start: 44.2,
|
||||
end: 50
|
||||
},
|
||||
{
|
||||
id: "subtitle10",
|
||||
text: "No indeed! What a beautiful fact!",
|
||||
start: 50,
|
||||
end: 54
|
||||
}
|
||||
],
|
||||
expects = subs.length*4 + 1;
|
||||
|
||||
function plus() {
|
||||
if ( ++count === expects ) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
poppercorn.parseTTML( document.getElementById( 'video' ).getAttribute( "data-timeline-sources" ) );
|
||||
|
||||
expect( expects );
|
||||
stop( 5000 );
|
||||
|
||||
// Allow load time
|
||||
setTimeout(function () {
|
||||
Popcorn.forEach( poppercorn.getTrackEvents(), function( evt ) {
|
||||
if( evt._natives.type === "subtitle" ) {
|
||||
sub = subs[numSubs++];
|
||||
|
||||
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.end, sub.end, "Correctly parsed end of " + evt.id + " at " + evt.start );
|
||||
plus();
|
||||
}
|
||||
});
|
||||
|
||||
strictEqual( subs.length, numSubs, "Parsed all subtitles" );
|
||||
plus();
|
||||
|
||||
}, 500);
|
||||
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 TTXT parser Plug-in Demo</title>
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseTTXT.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var p = Popcorn('#video')
|
||||
.volume(0)
|
||||
.play()
|
||||
}, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 TTXT parser Plug-in Demo</h1>
|
||||
<p>Subtitles are processed from <a href="data/data.TTXT">here</a></p>
|
||||
|
||||
<p>From 2.4 to 5.2 seconds, "[Background Music Playing]" is shown
|
||||
<br />From 15.712 to 17.399 seconds, "Heay!!" is shown
|
||||
<br />From 25.712 to 30.399 seconds, "[Bird noises]" is shown</p>
|
||||
<div>
|
||||
<video id='video'
|
||||
data-timeline-sources="data/data.TTXT"
|
||||
controls
|
||||
width= '250px'
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,73 @@
|
|||
// PARSER: 0.1 TTXT
|
||||
|
||||
(function (Popcorn) {
|
||||
|
||||
/**
|
||||
* TTXT popcorn parser plug-in
|
||||
* Parses subtitle files in the TTXT format.
|
||||
* Style information is ignored.
|
||||
* Data parameter is given by Popcorn, will need an xml.
|
||||
* Xml is the file contents to be parsed as a DOM tree
|
||||
*
|
||||
* @param {Object} data
|
||||
*
|
||||
* Example:
|
||||
<TextSample sampleTime="00:00:00.000" text=""></TextSample>
|
||||
*/
|
||||
Popcorn.parser( "parseTTXT", function( data ) {
|
||||
|
||||
// declare needed variables
|
||||
var returnData = {
|
||||
title: "",
|
||||
remote: "",
|
||||
data: []
|
||||
};
|
||||
|
||||
// Simple function to convert HH:MM:SS.MMM to SS.MMM
|
||||
// Assume valid, returns 0 on error
|
||||
var toSeconds = function(t_in) {
|
||||
var t = t_in.split(":");
|
||||
var time = 0;
|
||||
|
||||
try {
|
||||
return parseFloat(t[0], 10)*60*60 + parseFloat(t[1], 10)*60 + parseFloat(t[2], 10);
|
||||
} catch (e) { time = 0; }
|
||||
|
||||
return time;
|
||||
};
|
||||
|
||||
// creates an object of all atrributes keyed by name
|
||||
var createTrack = function( name, attributes ) {
|
||||
var track = {};
|
||||
track[name] = attributes;
|
||||
return track;
|
||||
};
|
||||
|
||||
// this is where things actually start
|
||||
var node = data.xml.lastChild.lastChild; // Last Child of TextStreamHeader
|
||||
var lastStart = Number.MAX_VALUE;
|
||||
var cmds = [];
|
||||
|
||||
// Work backwards through DOM, processing TextSample nodes
|
||||
while (node) {
|
||||
if ( node.nodeType === 1 && node.nodeName === "TextSample") {
|
||||
var sub = {};
|
||||
sub.start = toSeconds(node.getAttribute('sampleTime'));
|
||||
sub.text = node.getAttribute('text');
|
||||
|
||||
if (sub.text) { // Only process if text to display
|
||||
// Infer end time from prior element, ms accuracy
|
||||
sub.end = lastStart - 0.001;
|
||||
cmds.push( createTrack("subtitle", sub) );
|
||||
}
|
||||
lastStart = sub.start;
|
||||
}
|
||||
node = node.previousSibling;
|
||||
}
|
||||
|
||||
returnData.data = cmds.reverse();
|
||||
|
||||
return returnData;
|
||||
});
|
||||
|
||||
})( Popcorn );
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.3 TTXT parser Plug-in Test</title>
|
||||
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
|
||||
<script src="../../test/qunit/qunit.js"></script>
|
||||
<!--
|
||||
do not move - this must be called immediately prior to
|
||||
popcorn-api-draft.js
|
||||
-->
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
|
||||
<script src="popcorn.parseTTXT.js"></script>
|
||||
<script src="../../plugins/subtitle/popcorn.subtitle.js"></script>
|
||||
<script src="popcorn.parseTTXT.unit.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.3 TTXT parser Plug-in Test</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="qunit-fixture"> </div>
|
||||
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
data-timeline-sources="data/data.ttxt"
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,61 @@
|
|||
test("Popcorn 0.3 TTXT Parser Plugin", function () {
|
||||
|
||||
var expects = 0,
|
||||
count = 0,
|
||||
sub = {},
|
||||
numSubs = 0,
|
||||
poppercorn = Popcorn( "#video" ),
|
||||
subs = [ // Expected values
|
||||
{
|
||||
start: 2.4,
|
||||
end: 5.199,
|
||||
text: "[Background Music Playing]"
|
||||
},
|
||||
{
|
||||
start: 15.712,
|
||||
end: 17.398,
|
||||
text: "Heay!!"
|
||||
},
|
||||
{
|
||||
start: 25.712,
|
||||
end: 30.398,
|
||||
text: "[Bird noises]"
|
||||
}
|
||||
];
|
||||
|
||||
function plus() {
|
||||
if ( ++count === expects ) {
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
poppercorn.parseTTXT(document.getElementById('video').getAttribute('data-timeline-sources'));
|
||||
|
||||
expects = subs.length*3+1;
|
||||
expect(expects);
|
||||
|
||||
stop( 5000 );
|
||||
|
||||
// Allow load time
|
||||
setTimeout(function () {
|
||||
Popcorn.forEach(poppercorn.getTrackEvents(), function(evt) {
|
||||
if(evt._natives.type === "subtitle") {
|
||||
sub = subs[numSubs++];
|
||||
|
||||
equals(sub.end, evt.end , "Correct end" );
|
||||
plus();
|
||||
|
||||
equals(sub.start, evt.start , "Correct start" );
|
||||
plus();
|
||||
|
||||
equals(sub.text, evt.text , "Correct text" );
|
||||
plus();
|
||||
}
|
||||
});
|
||||
|
||||
equals(subs.length, numSubs , "Correctly parsed all subs" );
|
||||
plus();
|
||||
|
||||
}, 500);
|
||||
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.1 parser Plug-in Demo</title>
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
<script src="../../test/jquery.js"></script>
|
||||
<script src="../../plugins/flickr/popcorn.flickr.js"></script>
|
||||
<script src="popcorn.parseXML.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.1 parser Plug-in Demo</h1>
|
||||
<p></p>
|
||||
<div>
|
||||
<video data-timeline-sources="data/data.XML"
|
||||
controls
|
||||
width= '250px'
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<div id="flickrdiv"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,121 @@
|
|||
// PARSER: 0.1 XML
|
||||
|
||||
(function (Popcorn) {
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
Popcorn.parser( "parseXML", "XML", function( data ) {
|
||||
|
||||
// declare needed variables
|
||||
var returnData = {
|
||||
title: "",
|
||||
remote: "",
|
||||
data: []
|
||||
},
|
||||
manifestData = {};
|
||||
|
||||
// Simple function to convert 0:05 to 0.5 in seconds
|
||||
// acceptable formats are HH:MM:SS:MM, MM:SS:MM, SS:MM, SS
|
||||
var toSeconds = function(time) {
|
||||
var t = time.split(":");
|
||||
if (t.length === 1) {
|
||||
return parseFloat(t[0], 10);
|
||||
} else if (t.length === 2) {
|
||||
return parseFloat(t[0], 10) + parseFloat(t[1] / 12, 10);
|
||||
} else if (t.length === 3) {
|
||||
return parseInt(t[0] * 60, 10) + parseFloat(t[1], 10) + parseFloat(t[2] / 12, 10);
|
||||
} else if (t.length === 4) {
|
||||
return parseInt(t[0] * 3600, 10) + parseInt(t[1] * 60, 10) + parseFloat(t[2], 10) + parseFloat(t[3] / 12, 10);
|
||||
}
|
||||
};
|
||||
|
||||
// turns a node tree element into a straight up javascript object
|
||||
// also converts in and out to start and end
|
||||
// also links manifest data with ids
|
||||
var objectifyAttributes = function ( nodeAttributes ) {
|
||||
|
||||
var returnObject = {};
|
||||
|
||||
for ( var i = 0, nal = nodeAttributes.length; i < nal; i++ ) {
|
||||
|
||||
var key = nodeAttributes.item(i).nodeName,
|
||||
data = nodeAttributes.item(i).nodeValue;
|
||||
|
||||
// converts in into start
|
||||
if (key === "in") {
|
||||
returnObject.start = toSeconds( data );
|
||||
// converts out into end
|
||||
} else if ( key === "out" ){
|
||||
returnObject.end = toSeconds( data );
|
||||
// this is where ids in the manifest are linked
|
||||
} else if ( key === "resourceid" ) {
|
||||
Popcorn.extend( returnObject, manifestData[data] );
|
||||
// everything else
|
||||
} else {
|
||||
returnObject[key] = data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return returnObject;
|
||||
};
|
||||
|
||||
// creates an object of all atrributes keyd by name
|
||||
var createTrack = function( name, attributes ) {
|
||||
var track = {};
|
||||
track[name] = attributes;
|
||||
return track;
|
||||
};
|
||||
|
||||
// recursive function to process a node, or process the next child node
|
||||
var parseNode = function ( node, allAttributes, manifest ) {
|
||||
var attributes = {};
|
||||
Popcorn.extend( attributes, allAttributes, objectifyAttributes( node.attributes ), { text: node.textContent } );
|
||||
|
||||
var childNodes = node.childNodes;
|
||||
|
||||
// processes the node
|
||||
if ( childNodes.length < 1 || ( childNodes.length === 1 && childNodes[0].nodeType === 3 ) ) {
|
||||
|
||||
if ( !manifest ) {
|
||||
returnData.data.push( createTrack( node.nodeName, attributes ) );
|
||||
} else {
|
||||
manifestData[attributes.id] = attributes;
|
||||
}
|
||||
|
||||
// process the next child node
|
||||
} else {
|
||||
|
||||
for ( var i = 0; i < childNodes.length; i++ ) {
|
||||
|
||||
if ( childNodes[i].nodeType === 1 ) {
|
||||
parseNode( childNodes[i], attributes, manifest );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// this is where things actually start
|
||||
var x = data.documentElement.childNodes;
|
||||
|
||||
for ( var i = 0, xl = x.length; i < xl; i++ ) {
|
||||
|
||||
if ( x[i].nodeType === 1 ) {
|
||||
|
||||
// start the process of each main node type, manifest or timeline
|
||||
if ( x[i].nodeName === "manifest" ) {
|
||||
parseNode( x[i], {}, true );
|
||||
} else { // timeline
|
||||
parseNode( x[i], {}, false );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return returnData;
|
||||
});
|
||||
|
||||
})( Popcorn );
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popcorn 0.1 parser Plug-in Test</title>
|
||||
<link rel="stylesheet" href="../../test/qunit/qunit.css" type="text/css" media="screen">
|
||||
<script src="../../test/qunit/qunit.js"></script>
|
||||
<!--
|
||||
do not move - this must be called immediately prior to
|
||||
popcorn-api-draft.js
|
||||
-->
|
||||
|
||||
<script src="../../popcorn.js"></script>
|
||||
|
||||
<script src="popcorn.parseXML.js"></script>
|
||||
<script src="popcorn.parseXML.unit.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="qunit-header">Popcorn 0.1 parser Plug-in Test</h1>
|
||||
<h2 id="qunit-banner"></h2>
|
||||
<div id="qunit-testrunner-toolbar"></div>
|
||||
<h2 id="qunit-userAgent"></h2>
|
||||
<ol id="qunit-tests"></ol>
|
||||
<div id="qunit-fixture"> </div>
|
||||
|
||||
<video id='video'
|
||||
controls
|
||||
width= '250px'
|
||||
poster="../../test/poster.png">
|
||||
|
||||
<source id='mp4'
|
||||
src="../../test/trailer.mp4"
|
||||
type='video/mp4; codecs="avc1, mp4a"'>
|
||||
|
||||
<source id='ogv'
|
||||
src="../../test/trailer.ogv"
|
||||
type='video/ogg; codecs="theora, vorbis"'>
|
||||
|
||||
<p>Your user agent does not support the HTML5 Video element.</p>
|
||||
|
||||
</video>
|
||||
<div id="footnotediv"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,63 @@
|
|||
test("Popcorn 0.1 XML Parser Plugin", function () {
|
||||
|
||||
var expects = 7,
|
||||
count = 0,
|
||||
timeOut = 0,
|
||||
interval,
|
||||
poppercorn = Popcorn( "#video" );
|
||||
|
||||
function plus() {
|
||||
if ( ++count === expects ) {
|
||||
start();
|
||||
// clean up added events after tests
|
||||
clearInterval( interval );
|
||||
}
|
||||
}
|
||||
|
||||
expect(expects);
|
||||
|
||||
stop( 10000 );
|
||||
|
||||
Popcorn.plugin("parserTest1", {
|
||||
|
||||
start: function ( event, options ) {
|
||||
ok( options.item2 === "item2", "parserTest1 has data directly from manifest" );
|
||||
plus();
|
||||
ok( options.item3 === "item3", "parserTest1 has cascading data from manifest" );
|
||||
plus();
|
||||
},
|
||||
end: function ( event, options ) {}
|
||||
});
|
||||
|
||||
Popcorn.plugin("parserTest2", {
|
||||
|
||||
start: function ( event, options ) {
|
||||
ok( options.text === "item4", "parserTest2 has text data" );
|
||||
plus();
|
||||
ok( options.item1 === "item1", "parserTest2 has cascading data from parent" );
|
||||
plus();
|
||||
},
|
||||
end: function ( event, options ) {}
|
||||
});
|
||||
|
||||
Popcorn.plugin("parserTest3", {
|
||||
|
||||
start: function ( event, options ) {
|
||||
ok( options.item1 === "item1", "parserTest3 has cascading data from parent" );
|
||||
plus();
|
||||
ok( options.item2 === "item2", "parserTest3 has data directly from manifest" );
|
||||
plus();
|
||||
ok( options.item3 === "item3", "parserTest3 has cascading data from manifest" );
|
||||
plus();
|
||||
},
|
||||
end: function ( event, options ) {}
|
||||
});
|
||||
|
||||
poppercorn.parseXML("data/unit.XML");
|
||||
|
||||
// interval used to wait for data to be parsed
|
||||
interval = setInterval( function() {
|
||||
poppercorn.currentTime(5).play().currentTime(6);
|
||||
}, 2000);
|
||||
|
||||
});
|
Загрузка…
Ссылка в новой задаче