From ff4c81b3b1a9696a5347b8128e1d95ec0b18c60a Mon Sep 17 00:00:00 2001 From: Christopher De Cairos Date: Fri, 30 Sep 2011 00:09:46 -0400 Subject: [PATCH 01/78] Re-write of the Vimeo Player plug-in to use the new Player API [#728] --- players/vimeo/popcorn.vimeo.html | 59 +- players/vimeo/popcorn.vimeo.js | 767 +++++++------------------- players/vimeo/popcorn.vimeo.unit.html | 19 +- players/vimeo/popcorn.vimeo.unit.js | 487 +++++++++++----- 4 files changed, 581 insertions(+), 751 deletions(-) diff --git a/players/vimeo/popcorn.vimeo.html b/players/vimeo/popcorn.vimeo.html index 6c0bea897..63f0a9089 100644 --- a/players/vimeo/popcorn.vimeo.html +++ b/players/vimeo/popcorn.vimeo.html @@ -21,7 +21,7 @@ padding-left: 20px; } - + @@ -32,67 +32,61 @@ - +
-

+

-
Current Time (s):
Video Duration (s): -
Volume (0-1): +
Volume (0-100):
Load Status: Not Started
@@ -243,9 +232,9 @@

Expected Events

Web Page Area
- +

- + diff --git a/players/vimeo/popcorn.vimeo.js b/players/vimeo/popcorn.vimeo.js index c995f47c7..5f73eb6f8 100644 --- a/players/vimeo/popcorn.vimeo.js +++ b/players/vimeo/popcorn.vimeo.js @@ -1,613 +1,246 @@ -// Popcorn Vimeo Player Wrapper -( function( Popcorn, global ) { - /** - * Vimeo wrapper for Popcorn. - * This player adds enables Popcorn.js to handle Vimeo videos. It does so by masking an embedded Vimeo video Flash object - * as a video and implementing the HTML5 Media Element interface. - * - * You can specify the video in four ways: - * 1. Use the embed code path supplied by Vimeo as a div's src, and pass the div id into a new Popcorn.vimeo object - * - *
- * - & - * 2. Pass the div id and the embed code path supplied by Vimeo into a new Popcorn.vimeo object - * - *
- * - * - * 3. Use a web url as a div's src, and pass the div id into a new Popcorn.vimeo object - * - *
- * - * - * 4. Pass the div id and the web url into a new Popcorn.vimeo object - * - *
- * - * - * Due to Vimeo's API, certain events must be subscribed to at different times, and some not at all. - * These events are completely custom-implemented and may be subscribed to at any time: - * canplaythrough - * durationchange - * load - * loadedmetadata - * loadstart - * play - * readystatechange - * volumechange - * - * These events are related to player functionality and must be subscribed to during or after the load event: - * abort - * emptied - * ended - * pause - * playing - * progress - * seeked - * timeupdate - * - * These events are not supported: - * canplay - * error - * loadeddata - * ratechange - * seeking - * stalled - * suspend - * waiting - * - * Due to Vimeo's API, some attributes are be supported while others are not. - * Supported media attributes: - * autoplay ( via Popcorn ) - * currentTime - * duration ( get only ) - * ended ( get only ) - * initialTime ( get only, always 0 ) - * loop ( get only, set by calling setLoop() ) - * muted ( get only ) - * paused ( get only ) - * readyState ( get only ) - * volume - * - * load() function - * mute() function ( toggles on/off ) - * - * Unsupported media attributes: - * buffered - * defaultPlaybackRate - * networkState - * playbackRate - * played - * preload - * seekable - * seeking - * src - * startOffsetTime - */ - - // Trackers - var timeupdateInterval = 33, - timeCheckInterval = 0.75, - abs = Math.abs, - registry = {}; - - // base object for DOM-related behaviour like events - var EventManager = function ( owner ) { - var evts = {}; - - function makeHandler( evtName ) { - if ( !evts[evtName] ) { - evts[evtName] = []; - - // Create a wrapper function to all registered listeners - this["on"+evtName] = function( args ) { - Popcorn.forEach( evts[evtName], function( fn ) { - if ( fn ) { - fn.call( owner, args ); - } - }); - }; - } - } - - return { - addEventListener: function( evtName, fn, doFire ) { - evtName = evtName.toLowerCase(); - - makeHandler.call( this, evtName ); - evts[evtName].push( fn ); - - if ( doFire ) { - dispatchEvent( evtName ); - } - - return fn; - }, - // Add many listeners for a single event - // Takes an event name and array of functions - addEventListeners: function( evtName, events ) { - evtName = evtName.toLowerCase(); - - makeHandler.call( this, evtName ); - evts[evtName] = evts[evtName].concat( events ); - }, - removeEventListener: function( evtName, fn ) { - var evtArray = this.getEventListeners( evtName ), - i, - l; - - // Find and remove from events array - for ( i = 0, l = evtArray.length; i < l; i++) { - if ( evtArray[i] === fn ) { - var removed = evtArray[i]; - evtArray[i] = 0; - return removed; - } - } - }, - getEventListeners: function( evtName ) { - if( evtName ) { - return evts[ evtName.toLowerCase() ] || []; - } else { - return evts; - } - }, - dispatchEvent: function( evt, args ) { - // If event object was passed in, toString will yield event type as string (timeupdate) - // If a string, toString() will return the string itself (timeupdate) - evt = "on"+evt.toString().toLowerCase(); - this[evt] && this[evt]( args ); - } - }; - }; +(function() { - Popcorn.vimeo = function( mediaId, list, options ) { - return new Popcorn.vimeo.init( mediaId, list, options ); + // global callback for vimeo.. yuck. + vimeo_player_loaded = function( playerId ) { + vimeo_player_loaded[ playerId ] && vimeo_player_loaded[ playerId ](); }; + vimeo_player_loaded.seek = {}; + vimeo_player_loaded.loadProgress = {}; + vimeo_player_loaded.play = {}; + vimeo_player_loaded.pause = {}; + + Popcorn.player( "vimeo", { + _setup: function( options ) { + + var media = this, + vimeoObject, + vimeoContainer = document.createElement( "div" ), + currentTime = 0, + seekTime = 0, + seeking = false, + volumeChanged = false, + lastMuted = false, + lastVolume = 0; + + vimeoContainer.id = media.id + Popcorn.guid(); + + media.appendChild( vimeoContainer ); + + var vimeoInit = function() { + + var flashvars, + params, + attributes = {}, + src = media.src, + toggleMuteVolume = 0, + loadStarted = false; + + vimeo_player_loaded[ vimeoContainer.id ] = function() { + vimeoObject = document.getElementById( vimeoContainer.id ); + + vimeo_player_loaded.seek[ vimeoContainer.id ] = function( time ) { + if( time !== currentTime ) { + currentTime = time; + media.dispatchEvent( "seeked" ); + media.dispatchEvent( "timeupdate" ); + } + }; - Popcorn.vimeo.onLoad = function( playerId ) { - var player = registry[ playerId ]; + vimeo_player_loaded.play[ vimeoContainer.id ] = function() { + if ( media.paused ) { + media.paused = false; + media.dispatchEvent( "play" ); - player.swfObj = document.getElementById( playerId ); + media.dispatchEvent( "playing" ); + timeUpdate(); + } + }; - // For calculating position relative to video (like subtitles) - player.offsetWidth = player.swfObj.offsetWidth; - player.offsetHeight = player.swfObj.offsetHeight; - player.offsetParent = player.swfObj.offsetParent; - player.offsetLeft = player.swfObj.offsetLeft; - player.offsetTop = player.swfObj.offsetTop; + vimeo_player_loaded.pause[ vimeoContainer.id ] = function() { + if ( !media.paused ) { + media.paused = true; + media.dispatchEvent( "pause" ); + } + }; - player.dispatchEvent( "load" ); - }; + vimeo_player_loaded.loadProgress[ vimeoContainer.id ] = function( progress ) { - Popcorn.getScript( "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" ); + if ( !loadStarted ) { + loadStarted = true; + media.dispatchEvent( "loadstart" ); + } - // A constructor, but we need to wrap it to allow for "static" functions - Popcorn.vimeo.init = (function() { - var rPlayerUri = /^http:\/\/player\.vimeo\.com\/video\/[\d]+/i, - rWebUrl = /vimeo\.com\/[\d]+/, - hasAPILoaded = false; + if ( progress.percent === 100 ) { + media.dispatchEvent( "canplaythrough" ); + } + }; - // Extract the numeric video id from container uri: 'http://player.vimeo.com/video/11127501' or 'http://player.vimeo.com/video/4282282' - // Expect id to be a valid 32/64-bit unsigned integer - // Returns string, empty string if could not match - function extractIdFromUri( uri ) { - if ( !uri ) { - return; - } + vimeoObject.api_addEventListener( "seek", "vimeo_player_loaded.seek." + vimeoContainer.id ); + vimeoObject.api_addEventListener( "loadProgress", "vimeo_player_loaded.loadProgress." + vimeoContainer.id ); + vimeoObject.api_addEventListener( "play", "vimeo_player_loaded.play." + vimeoContainer.id ); + vimeoObject.api_addEventListener( "pause", "vimeo_player_loaded.pause." + vimeoContainer.id ); - var matches = uri.match( rPlayerUri ); - return matches ? matches[0].substr(30) : ""; - } + var timeUpdate = function() { + if ( !media.paused ) { + currentTime = vimeoObject.api_getCurrentTime(); + media.dispatchEvent( "timeupdate" ); + setTimeout( timeUpdate, 10 ); + } + }, - // Extract the numeric video id from url: 'http://vimeo.com/11127501' or simply 'vimeo.com/4282282' - // Ignores protocol and subdomain, but one would expecct it to be http://www.vimeo.com/####### - // Expect id to be a valid 32/64-bit unsigned integer - // Returns string, empty string if could not match - function extractIdFromUrl( url ) { - if ( !url ) { - return; - } + isMuted = function() { - var matches = url.match( rWebUrl ); - return matches ? matches[0].substr(10) : ""; - } + return vimeoObject.api_getVolume() === 0; + }; - function makeSwf( self, vidId, containerId ) { - if ( !window.swfobject ) { - setTimeout( function() { - makeSwf( self, vidId, containerId ); - }, 1); - return; - } + var volumeUpdate = function() { - var params, - flashvars, - attributes = {}; - - flashvars = { - clip_id: vidId, - show_portrait: 1, - show_byline: 1, - show_title: 1, - // required in order to use the Javascript API - js_api: 1, - // moogaloop will call this JS function when it's done loading (optional) - js_onLoad: 'Popcorn.vimeo.onLoad', - // this will be passed into all event methods so you can keep track of multiple moogaloops (optional) - js_swf_id: containerId - }; - params = { - allowscriptaccess: 'always', - allowfullscreen: 'true', - // This is so we can overlay html ontop o fFlash - wmode: 'transparent' - }; + m = isMuted(); + vol = vimeoObject.api_getVolume(); + if ( lastMuted !== m ) { + lastMuted = m; + media.dispatchEvent( "volumechange" ); + } - swfobject.embedSWF( "http://vimeo.com/moogaloop.swf", containerId, self.offsetWidth, self.offsetHeight, "9.0.0", "expressInstall.swf", flashvars, params, attributes ); - } + if ( lastVolume !== vol ) { + lastVolume = vol; + media.dispatchEvent( "volumechange" ); + } - // If container id is not supplied, assumed to be same as player id - var ctor = function ( containerId, videoUrl, options ) { - if ( !containerId ) { - throw "Must supply an id!"; - } else if ( /file/.test( location.protocol ) ) { - throw "Must run from a web server!"; - } + setTimeout( volumeUpdate, 250 ); + }; - var vidId, - that = this, - tmp; - - this._container = document.createElement( "div" ); - this._container.id = containerId + "object"; - this._target = document.getElementById( containerId ); - this._target.appendChild( this._container ); - - options = options || {}; - - options.css && Popcorn.extend( this._target.style, options.css ); - - this.addEventFn = null; - this.evtHolder = null; - this.paused = true; - this.duration = Number.MAX_VALUE; - this.ended = 0; - this.currentTime = 0; - this.volume = 1; - this.loop = 0; - this.initialTime = 0; - this.played = 0; - this.readyState = 0; - this.parentNode = this._target.parentNode; - - this.previousCurrentTime = this.currentTime; - this.previousVolume = this.volume; - this.evtHolder = new EventManager( this ); - - // For calculating position relative to video (like subtitles) - this.width = this._target.style.width || "504px"; - this.height = this._target.style.height || "340px"; - - if ( !/[\d]%/.test( this.width ) ) { - this.offsetWidth = parseInt( this.width, 10 ); - this._target.style.width = this.width + "px"; - } else { - // convert from pct to abs pixels - tmp = this._target.style.width; - this._target.style.width = this.width; - this.offsetWidth = this._target.offsetWidth; - this._target.style.width = tmp; - } + var mute = function() { - if ( !/[\d]%/.test( this.height ) ) { - this.offsetHeight = parseInt( this.height, 10 ); - this._target.style.height = this.height + "px"; - } else { - // convert from pct to abs pixels - tmp = this._target.style.height; - this._target.style.height = this.height; - this.offsetHeight = this._target.offsetHeight; - this._target.style.height = tmp; - } + }; - this.offsetLeft = 0; - this.offsetTop = 0; + media.play = function() { + media.paused = false; + media.dispatchEvent( "play" ); - // Try and get a video id from a vimeo site url - // Try either from ctor param or from iframe itself - vidId = extractIdFromUrl( videoUrl ) || extractIdFromUri( videoUrl ); + media.dispatchEvent( "playing" ); + timeUpdate(); + vimeoObject.api_play(); + }; - if ( !vidId ) { - throw "No video id"; - } + media.pause = function() { - registry[ this._container.id ] = this; + if ( !media.paused ) { - makeSwf( this, vidId, this._container.id ); + media.paused = true; + media.dispatchEvent( "pause" ); + vimeoObject.api_pause(); + } + }; - // Set up listeners to internally track state as needed - this.addEventListener( "load", function() { - var hasLoaded = false; + Popcorn.player.defineProperty( media, "currentTime", { + + set: function( val ) { + if ( !val ) { + return currentTime; + } + currentTime = seekTime = +val; + seeking = true; + media.dispatchEvent( "seeked" ); + media.dispatchEvent( "timeupdate" ); + vimeoObject.api_seekTo( currentTime ); + return currentTime; + }, + get: function() { + return currentTime; + } + }); - that.duration = that.swfObj.api_getDuration(); - that.evtHolder.dispatchEvent( "durationchange" ); - that.evtHolder.dispatchEvent( "loadedmetadata" ); + Popcorn.player.defineProperty( media, "muted", { + set: function( val ) { + if ( isMuted() !== val ) { + if ( val ) { + toggleMuteVolume = vimeoObject.api_getVolume(); + vimeoObject.api_setVolume( 0 ); + } else { + vimeoObject.api_setVolume( toggleMuteVolume ); + } + } + }, + get: function() { + return isMuted(); + } + }); - // Chain events and calls together so that this.currentTime reflects the current time of the video - // Done by Getting the Current Time while the video plays - that.addEventListener( "timeupdate", function() { - that.currentTime = that.swfObj.api_getCurrentTime(); - }); + Popcorn.player.defineProperty( media, "volume", { + set: function( val ) { - // Add pause listener to keep track of playing state + if ( !val || typeof val !== "number" || ( val < 0 && val > 1 ) ) { + return vimeoObject.api_getVolume(); + } - that.addEventListener( "pause", function() { - that.paused = true; - }); + if ( vimeoObject.api_getVolume() !== val ) { + vimeoObject.api_setVolume( val ); + lastVolume = vimeoObject.api_getVolume(); + media.dispatchEvent( "volumechange" ); + } - // Add play listener to keep track of playing state - that.addEventListener( "playing", function() { - that.paused = false; - that.ended = 0; - }); + return vimeoObject.api_getVolume(); + }, + get: function() { + return vimeoObject.api_getVolume(); + } + }); - // Add ended listener to keep track of playing state - that.addEventListener( "ended", function() { - if ( that.loop !== "loop" ) { - that.paused = true; - that.ended = 1; - } - }); + media.readyState = 4; + media.dispatchEvent( "load" ); + media.duration = vimeoObject.api_getDuration(); + media.dispatchEvent( "durationchange" ); + volumeUpdate(); - // Add progress listener to keep track of ready state - that.addEventListener( "progress", function( data ) { - if ( !hasLoaded ) { - hasLoaded = 1; - that.readyState = 3; - that.evtHolder.dispatchEvent( "readystatechange" ); - } + media.dispatchEvent( "loadeddata" ); + } - // Check if fully loaded - if ( data.percent === 100 ) { - that.readyState = 4; - that.evtHolder.dispatchEvent( "readystatechange" ); - that.evtHolder.dispatchEvent( "canplaythrough" ); + function extractId( videoUrl ) { + if ( !videoUrl ) { + return; } - }); - }); - }; - return ctor; - })(); - - Popcorn.vimeo.init.prototype = Popcorn.vimeo.prototype; - - // Sequence object prototype - Popcorn.extend( Popcorn.vimeo.prototype, { - // Do everything as functions instead of get/set - setLoop: function( val ) { - if ( !val ) { - return; - } + var rPlayerUri = /^http:\/\/player\.vimeo\.com\/video\/[\d]+/i, + rWebUrl = /vimeo\.com\/[\d]+/; - this.loop = val; - var isLoop = val === "loop" ? 1 : 0; - // HTML convention says to loop if value is 'loop' - this.swfObj.api_setLoop( isLoop ); - }, - // Set the volume as a value between 0 and 1 - setVolume: function( val ) { - if ( !val && val !== 0 ) { - return; - } - - // Normalize in case outside range of expected values - if ( val < 0 ) { - val = -val; - } - - if ( val > 1 ) { - val %= 1; - } - - // HTML video expects to be 0.0 -> 1.0, Vimeo expects 0-100 - this.volume = this.previousVolume = val; - this.swfObj.api_setVolume( val*100 ); - this.evtHolder.dispatchEvent( "volumechange" ); - }, - // Seeks the video - setCurrentTime: function ( time ) { - if ( !time && time !== 0 ) { - return; - } - - this.currentTime = this.previousCurrentTime = time; - this.ended = time >= this.duration; - this.swfObj.api_seekTo( time ); - - // Fire events for seeking and time change - this.evtHolder.dispatchEvent( "seeked" ); - this.evtHolder.dispatchEvent( "timeupdate" ); - }, - // Play the video - play: function() { - // In case someone is cheeky enough to try this before loaded - if ( !this.swfObj ) { - this.addEventListener( "load", this.play ); - return; - } - - if ( !this.played ) { - this.played = 1; - this.startTimeUpdater(); - this.evtHolder.dispatchEvent( "loadstart" ); - } - - this.evtHolder.dispatchEvent( "play" ); - this.swfObj.api_play(); - }, - // Pause the video - pause: function() { - // In case someone is cheeky enough to try this before loaded - if ( !this.swfObj ) { - this.addEventListener( "load", this.pause ); - return; - } - - this.swfObj.api_pause(); - }, - // Toggle video muting - // Unmuting will leave it at the old value - mute: function() { - // In case someone is cheeky enough to try this before loaded - if ( !this.swfObj ) { - this.addEventListener( "load", this.mute ); - return; - } - - if ( !this.muted() ) { - this.oldVol = this.volume; - - if ( this.paused ) { - this.setVolume( 0 ); - } else { - this.volume = 0; + var matches = videoUrl.match( rPlayerUri ) ? videoUrl.match( rPlayerUri )[ 0 ].substr( 30 ) : ""; + return matches ? matches : videoUrl.match( rWebUrl ) ? videoUrl.match( rWebUrl )[ 0 ].substr( 10 ) : ""; } - } else { - if ( this.paused ) { - this.setVolume( this.oldVol ); - } else { - this.volume = this.oldVol; + + if ( !( src = extractId( src ) ) ) { + throw "Invalid Video Id"; } - } - }, - muted: function() { - return this.volume === 0; - }, - // Force loading by playing the player. Pause afterwards - load: function() { - // In case someone is cheeky enough to try this before loaded - if ( !this.swfObj ) { - this.addEventListener( "load", this.load ); - return; - } - this.play(); - this.pause(); - }, - unload: function() { - // In case someone is cheeky enough to try this before loaded - if ( !this.swfObj ) { - this.addEventListener( "load", this.unload ); - return; - } + flashvars = { + clip_id: src, + show_portrait: 1, + show_byline: 1, + show_title: 1, + js_api: 1, + js_swf_id: vimeoContainer.id + }; + params = { + allowscriptaccess: "always", + allowfullscreen: "true", + wmode: "transparent" + }; - this.pause(); - - this.swfObj.api_unload(); - this.evtHolder.dispatchEvent( "abort" ); - this.evtHolder.dispatchEvent( "emptied" ); - }, - // Hook an event listener for the player event into internal event system - // Stick to HTML conventions of add event listener and keep lowercase, without prependinng "on" - addEventListener: function( evt, fn ) { - var playerEvt, - that = this; - - // In case event object is passed in - evt = evt.type || evt.toLowerCase(); - - // If it's an HTML media event supported by player, map - if ( evt === "seeked" ) { - playerEvt = "onSeek"; - } else if ( evt === "timeupdate" ) { - playerEvt = "onProgress"; - } else if ( evt === "progress" ) { - playerEvt = "onLoading"; - } else if ( evt === "ended" ) { - playerEvt = "onFinish"; - } else if ( evt === "playing" ) { - playerEvt = "onPlay"; - } else if ( evt === "pause" ) { - // Direct mapping, CamelCase the event name as vimeo API expects - playerEvt = "on"+evt[0].toUpperCase() + evt.substr(1); - } + swfobject.embedSWF( "http://vimeo.com/moogaloop.swf", vimeoContainer.id, + media.offsetWidth + "", media.offsetHeight + "", "9.0.0", "expressInstall.swf", + flashvars, params, attributes ); - // Vimeo only stores 1 callback per event - // Have vimeo call internal collection of callbacks - this.evtHolder.addEventListener( evt, fn, false ); + vimeoContainer.addEventListener( "load", function() { + console.log("asdfasdf"); + }); - // Link manual event structure with Vimeo's if not already - if( playerEvt && this.evtHolder.getEventListeners( evt ).length === 1 ) { - // Setup global functions on Popcorn.vimeo to sync player events to an internal collection - // Some events expect 2 args, some only one (the player id) - if ( playerEvt === "onSeek" || playerEvt === "onProgress" || playerEvt === "onLoading" ) { - Popcorn.vimeo[playerEvt] = function( arg1, arg2 ) { - var player = registry[arg2]; + }; - player.evtHolder.dispatchEvent( evt, arg1 ); - }; - } else { - Popcorn.vimeo[playerEvt] = function( arg1 ) { - var player = registry[arg1]; - player.evtHolder.dispatchEvent( evt ); - }; - } + if ( !window.swfobject ) { - this.swfObj.api_addEventListener( playerEvt, "Popcorn.vimeo."+playerEvt ); - } - }, - removeEventListener: function( evtName, fn ) { - return this.evtHolder.removeEventListener( evtName, fn ); - }, - dispatchEvent: function( evtName ) { - return this.evtHolder.dispatchEvent( evtName ); - }, - getBoundingClientRect: function() { - return this._target.getBoundingClientRect(); - }, - startTimeUpdater: function() { - var self = this, - seeked = 0; - - if ( abs( this.currentTime - this.previousCurrentTime ) > timeCheckInterval ) { - // Has programatically set the currentTime - this.setCurrentTime( this.currentTime ); - seeked = 1; + Popcorn.getScript( "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js", vimeoInit ); } else { - this.previousCurrentTime = this.currentTime; - } - - if ( this.volume !== this.previousVolume ) { - this.setVolume( this.volume ); - } - - if ( !self.paused || seeked ) { - this.dispatchEvent( 'timeupdate' ); - } - - if( !self.ended ) { - setTimeout( function() { - self.startTimeUpdater.call(self); - }, timeupdateInterval); + vimeoInit(); } } }); -})( Popcorn, window ); +})(); \ No newline at end of file diff --git a/players/vimeo/popcorn.vimeo.unit.html b/players/vimeo/popcorn.vimeo.unit.html index 91c9d37f1..8936e85a7 100644 --- a/players/vimeo/popcorn.vimeo.unit.html +++ b/players/vimeo/popcorn.vimeo.unit.html @@ -1,28 +1,29 @@ - Popcorn API + Vimeo Player Unit Test Suite - - + - + - + -

Popcorn Vimeo Player Plugin

+

Popcorn Vimeo Player Unit Tests

    - -
    + +
    +
    diff --git a/players/vimeo/popcorn.vimeo.unit.js b/players/vimeo/popcorn.vimeo.unit.js index 42e4262a0..194012337 100644 --- a/players/vimeo/popcorn.vimeo.unit.js +++ b/players/vimeo/popcorn.vimeo.unit.js @@ -1,159 +1,366 @@ -test("Popcorn Vimeo Plugin", function () { - function makeHandler( evtName ) { - return( function() { - var count = 0; - return function() { - count++; - - if ( count === 1 ) { - ok( true, "Event '"+evtName+"' is supported" ); +test("Update Timer", function () { + + QUnit.reset(); + + var p2 = Popcorn.vimeo( "#player_1", "http://player.vimeo.com/video/6960892" ), + expects = 12, + count = 0, + execCount = 0, + // These make sure events are only fired once + // any second call will produce a failed test + forwardStart = false, + forwardEnd = false, + backwardStart = false, + backwardEnd = false, + wrapperRunning = { one: false, two: false, }; + + function plus() { + if ( ++count === expects ) { + // clean up added events after tests + Popcorn.removePlugin( "forwards" ); + Popcorn.removePlugin( "backwards" ); + Popcorn.removePlugin( "wrapper" ); + p2.removePlugin( "exec" ); + p2.pause(); + start(); + } + } + + // These tests come close to 10 seconds on chrome, increasing to 15 + stop(); + + Popcorn.plugin( "forwards", function () { + return { + start: function ( event, options ) { + + if ( !options.startFired ) { + + options.startFired = true; + forwardStart = !forwardStart; + ok( forwardStart, "forward's start fired" ); + plus(); + } + }, + end: function ( event, options ) { + + if ( !options.endFired ) { + + options.endFired = true; + forwardEnd = !forwardEnd; + p2.currentTime(1).play(); + ok( forwardEnd, "forward's end fired" ); plus(); } } - })(); - } - + }; + }); + + p2.forwards({ + start: 3, + end: 4 + }); + + Popcorn.plugin( "backwards", function () { + return { + start: function ( event, options ) { + + if ( !options.startFired ) { + + options.startFired = true; + backwardStart = !backwardStart; + ok( true, "backward's start fired" ); + plus(); + } + }, + end: function ( event, options ) { + + if ( !options.endFired ) { + + options.endFired = true; + backwardEnd = !backwardEnd; + ok( backwardEnd, "backward's end fired" ); + plus(); + p2.currentTime( 0 ).play(); + } + } + }; + }); + + p2.backwards({ + start: 1, + end: 2 + }); + + Popcorn.plugin( "wrapper", { + start: function ( event, options ) { + + wrapperRunning[ options.wrapper ] = true; + }, + end: function ( event, options ) { + + wrapperRunning[ options.wrapper ] = false; + } + }); + + // second instance of wrapper is wrapping the first + p2.wrapper({ + start: 6, + end: 7, + wrapper: "one" + }) + .wrapper({ + start: 5, + end: 8, + wrapper: "two" + }) + // checking wrapper 2's start + .exec( 5, function() { + + if ( execCount === 0 ) { + + execCount++; + ok( wrapperRunning.two, "wrapper two is running at second 5" ); + plus(); + ok( !wrapperRunning.one, "wrapper one is stopped at second 5" ); + plus(); + } + }) + // checking wrapper 1's start + .exec( 6, function() { + + if ( execCount === 1 ) { + + execCount++; + ok( wrapperRunning.two, "wrapper two is running at second 6" ); + plus(); + ok( wrapperRunning.one, "wrapper one is running at second 6" ); + plus(); + } + }) + // checking wrapper 1's end + .exec( 7, function() { + + if ( execCount === 2 ) { + + execCount++; + ok( wrapperRunning.two, "wrapper two is running at second 7" ); + plus(); + ok( !wrapperRunning.one, "wrapper one is stopped at second 7" ); + plus(); + } + }) + // checking wrapper 2's end + .exec( 8, function() { + + if ( execCount === 3 ) { + + execCount++; + ok( !wrapperRunning.two, "wrapper two is stopped at second 9" ); + plus(); + ok( !wrapperRunning.one, "wrapper one is stopped at second 9" ); + plus(); + } + }); + + p2.exec( 3, function() { + + p2.play(); + }); + + p2.currentTime(3); + +}); + +test("Plugin Factory", function () { + + QUnit.reset(); + + var popped = Popcorn.vimeo( "#player_1", "http://player.vimeo.com/video/6960892" ), + methods = "load play pause currentTime mute volume roundTime exec removePlugin", + expects = 34, // 15*2+2+2. executor/complicator each do 15 + count = 0; + function plus() { - if ( ++count === expects ) { + if ( ++count == expects ) { + Popcorn.removePlugin("executor"); + Popcorn.removePlugin("complicator"); + popped.pause(); start(); } } - - var popped = Popcorn( Popcorn.vimeo( "player_1", "http://vimeo.com/11127501" ) ), - expects = 22, - playCount = 0, - pauseCount = 0, - count = 0, - events = { - "durationchange": makeHandler( "durationchange" ), - "play": makeHandler( "play" ), - "loadstart": function() { - (makeHandler( "loadstart" ))(); - this.play(); - }, - "readystatechange": makeHandler( "readystatechange" ), - "volumechange": (function() { - var timesCalled = 0; - - return function() { - timesCalled++; - - if (timesCalled === 1) { - ok( true, "Volume changed event works" ); - plus(); - - equals( popped.volume(), 0, "Volume correctly set" ); - plus(); - - ok( popped.video.muted(), "Muted set when player volume 0" ); - plus(); - - popped.volume( 0.333 ); - } else if ( timesCalled === 2 ) { - ok( !popped.video.muted(), "Unmuted when volume not 0" ); - plus(); - - popped.mute(); - } else if ( timesCalled === 3 ) { - ok( popped.video.muted(), "Mute mutes when volume is non-zero" ); - plus(); - - popped.mute(); - } else if ( timesCalled === 4 ) { - equals( popped.volume(), 0.333, "Mute unmutes to last volume" ); - plus(); - - popped.exec( 4, function() { - popped.video.unload(); - }); - } - }; - })(), - "emptied": makeHandler( "emptied" ), - "ended": 0, - "pause": (function() { - var timesCalled = 0; - - return function() { - timesCalled++; - - if ( timesCalled === 1 ) { - ok( true, "Pause event works" ); - plus(); - ok( popped.video.paused, "Pause attribute set" ); - plus(); - popped.play(); - } - }; - })(), - "playing": (function() { - var timesCalled = 0; - - return function() { - timesCalled++; - - if ( timesCalled === 1 ) { - ok( true, "Play event works" ); - plus(); - - ok( true, "Video autoplay attribute works" ); - plus(); - - ok( !popped.video.paused, "Player paused attribute not set" ); - plus(); - - popped.exec( 5, function() { - popped.currentTime( 0 ); - popped.pause(); - }); - } else if ( timesCalled === 2 ) { - ok( true, "Popcorn play function works" ); - plus(); - popped.volume( 0 ); - } - }; - })(), - "progress": makeHandler( "progress" ), - "seeked": makeHandler( "seeked" ), - "timeupdate": makeHandler( "timeupdate" ) - }; - + expect( expects ); - - stop( 20000 ); - - ok( "vimeo" in Popcorn, "Vimeo is a method of Popcorn" ); + stop( 15000 ); + + Popcorn.plugin("executor", function () { + + return { + + start: function () { + var self = this; + + // These ensure that a popcorn instance is the value of `this` inside a plugin definition + + methods.split(/\s+/g).forEach(function (k,v) { + ok( k in self, "executor instance has method: " + k ); + + plus(); + }); + + ok( "media" in this, "executor instance has `media` property" ); + plus(); + ok( Object.prototype.toString.call(popped.media) === "[object Object]", "video property is a HTML DIV element" ); + plus(); + + ok( "data" in this, "executor instance has `data` property" ); + plus(); + ok( Object.prototype.toString.call(popped.data) === "[object Object]", "data property is an object" ); + plus(); + + ok( "trackEvents" in this.data, "executor instance has `trackEvents` property" ); + plus(); + ok( Object.prototype.toString.call(popped.data.trackEvents) === "[object Object]", "executor trackEvents property is an object" ) + plus(); + }, + end: function () { + + } + }; + + }); + + ok( "executor" in popped, "executor plugin is now available to instance" ); plus(); - - equals( popped.video.initialTime, 0, "Player initial time is 0" ); + equals( Popcorn.registry.length, 1, "One item in the registry"); plus(); - - Popcorn.plugin( "timingTest", { - start: function ( event, options ) { - ok( true, "Popcorn plugin started" ); + + popped.executor({ + start: 1, + end: 2 + }); + + Popcorn.plugin("complicator", { + + start: function ( event ) { + + var self = this; + + // These ensure that a popcorn instance is the value of `this` inside a plugin definition + + methods.split(/\s+/g).forEach(function (k,v) { + ok( k in self, "complicator instance has method: " + k ); + + plus(); + }); + + ok( "media" in this, "complicator instance has `media` property" ); plus(); - }, - end: function ( event, options ) { - ok( true, "Popcorn plugin stopped" ); + ok( Object.prototype.toString.call(popped.media) === "[object Object]", "video property is a HTMLVideoElement" ); + plus(); + + ok( "data" in this, "complicator instance has `data` property" ); plus(); + ok( Object.prototype.toString.call(popped.data) === "[object Object]", "complicator data property is an object" ); + plus(); + + ok( "trackEvents" in this.data, " complicatorinstance has `trackEvents` property" ); + plus(); + ok( Object.prototype.toString.call(popped.data.trackEvents) === "[object Object]", "complicator trackEvents property is an object" ) + plus(); + }, + end: function () { + + //start(); + + }, + timeupdate: function () { } }); - - popped.timingTest({ - start: 3, // seconds - end: 4, // seconds + + ok( "complicator" in popped, "complicator plugin is now available to instance" ); + plus(); + equals( Popcorn.registry.length, 2, "Two items in the registry"); + plus(); + + popped.complicator({ + start: 4, + end: 5 }); - - popped.listen( "load", function() { - ok ( this.video.swfObj.id === popped.video.swfObj.id, "Correctly kept track of 'this'" ); + + popped.currentTime(0).play(); + +}); + +test( "Popcorn vimeo Plugin Url and Duration Tests", function() { + function plus(){ + if ( ++count == expects ) { + popcorn.pause(); + start(); + } + } + + QUnit.reset(); + + var count = 0, + expects = 3, + popcorn = Popcorn.vimeo( "#player_1", "http://player.vimeo.com/video/6960892" ); + + expect( expects ); + stop( 10000 ); + + equals( popcorn.media.id, "player_1", "Video id set" ); + plus(); + + equals( popcorn.duration(), 0, "Duration starts as 0"); + plus(); + + popcorn.listen( "durationchange", function() { + notEqual( popcorn.duration(), 0, "Duration has been changed from 0" ); plus(); - - Popcorn.forEach( events, function( fn, evtName ) { - fn && popped.listen( evtName, fn ); + + popcorn.pause(); + }); + + popcorn.play(); +}); + +test( "Popcorn vimeo Plugin Url Regex Test", function() { + + QUnit.reset(); + + var urlTests = [ + { name: 'standard', + url: 'http://player.vimeo.com/video/6960892', + expected: 'http://player.vimeo.com/video/6960892', + }, + { name: 'short url', + url: 'http://vimeo.com/6960892', + expected: 'http://vimeo.com/6960892', + } + ]; + + var count = 0, + expects = urlTests.length; + + expect( expects ); + stop( 10000 ); + + Popcorn.forEach( urlTests, function( values, key ) { + + var urlTest = urlTests[ key ], + popcorn = Popcorn.vimeo( '#player_2', urlTest.url ); + + popcorn.listen( "loadeddata", function() { + + equals( popcorn.media.src, urlTest.expected, 'Video id is correct for ' + urlTest.name + ': ' + urlTest.url ); + popcorn.pause(); + + count++; + if ( count === expects ) { + + start(); + popcorn.pause(); + } }); - - // Queue load - // Load event will play when beginning to load - popped.load(); }); }); From 27a2fbdb41c93ff242bafbbcfb8c52f97affcb3f Mon Sep 17 00:00:00 2001 From: stevenaw Date: Sat, 1 Oct 2011 10:57:44 -0400 Subject: [PATCH 02/78] [#402] Refactored, updated to spec changes since last version --- parsers/parserVTT/data/data.vtt | 52 ++++-- parsers/parserVTT/data/unit.vtt | 23 +-- parsers/parserVTT/popcorn.parserVTT.js | 184 +++++++++++--------- parsers/parserVTT/popcorn.parserVTT.unit.js | 20 +-- 4 files changed, 158 insertions(+), 121 deletions(-) diff --git a/parsers/parserVTT/data/data.vtt b/parsers/parserVTT/data/data.vtt index f2e62a0f1..d36aef71f 100644 --- a/parsers/parserVTT/data/data.vtt +++ b/parsers/parserVTT/data/data.vtt @@ -1,12 +1,40 @@ -1 -00:00:02.400 --> 00:00:07.200 -Senator, we're making -our final approach into Coruscant. - -2 -00:00:09.712 --> 00:00:13.399 -Very good, Lieutenant. - -Track-3 -00:00:15.542 --> 00:00:18.542 A:start D:vertical L:98% -It's a trap! \ No newline at end of file +WEBVTT + +00:11.000 --> 00:13.000 +We are in New York City + +00:13.000 --> 00:16.000 +We're actually at the Lucern Hotel, just down the street + +00:16.000 --> 00:18.000 +from the American Museum of Natural History + +00:18.000 --> 00:20.000 +And with me is Neil DeGrasse Tyson + +00:20.000 --> 00:22.000 +Astrophysicist, Director of the Hayden Planetarium + +00:22.000 --> 00:24.000 +at the AMNH. + +00:24.000 --> 00:26.000 +Thank you for walking down here. + +00:27.000 --> 00:30.000 +And I want to do a follow-up on the last conversation we did. + +00:30.000 --> 00:31.500 A:end S:50% +When we e-mailed— + +00:30.500 --> 00:32.500 A:start S:50% +Didn't we talk about enough in that conversation? + +00:32.000 --> 00:35.500 A:end S:50% +No! No no no no; 'cos 'cos obviously 'cos + +00:32.500 --> 00:33.500 A:start S:50% +Laughs + +00:35.500 --> 00:38.000 +You know I'm so excited my glasses are falling off here. \ No newline at end of file diff --git a/parsers/parserVTT/data/unit.vtt b/parsers/parserVTT/data/unit.vtt index b7ead465e..a252a8854 100644 --- a/parsers/parserVTT/data/unit.vtt +++ b/parsers/parserVTT/data/unit.vtt @@ -1,43 +1,32 @@ -1 +WEBVTT + 00:00:02.400 --> 00:00:07.200 -Senator, we're making -our final approach into Coruscant. +A typical multiline +subtitle. -2 00:09.712-->00:13.399 -Very good, Lieutenant. +No whitespace between time tokens -3 00:00:13.400 --> 00:00:20 A bad cue, no milliseconds. Should be ignored ---> -00:00:14.456--> 00:00:20.000 -A bad cue, bad id. Should be ignored - -4 00:00:9.456--> 00:00:20.000 A bad cue, seconds are single digit. Should be ignored -5 00:1:00.456--> 00:00:20.000 A bad cue, minutes are single digit. Should be ignored -6 1:00:00.456--> 00:00:20.000 A bad cue, hours are supplied as single digit. Should be ignored -7 00:00:00.46--> 00:00:20.000 A bad cue, ms are not 3 digits. Should be ignored -Track-3 00:00:15.042 --> 00:00:18.042 A:start D:vertical L:98% -It's a trap! +It's a trap! Ignore the timeline styling for now! -ID9 00:00:20.000--> 00:00:21.670 This text is boldy italicized \ No newline at end of file diff --git a/parsers/parserVTT/popcorn.parserVTT.js b/parsers/parserVTT/popcorn.parserVTT.js index 1bcdbc73c..e7acf2567 100644 --- a/parsers/parserVTT/popcorn.parserVTT.js +++ b/parsers/parserVTT/popcorn.parserVTT.js @@ -2,123 +2,143 @@ (function ( Popcorn ) { /** - * WebSRT/VTT popcorn parser plug-in - * Parses subtitle files in the WebSRT/VTT format. - * Styles which appear after timing information are ignored. - * Inline styling tags follow HTML conventions and are left in for the browser to handle - * TrackEvents (cues) which are malformed are ignored. - * Data parameter is given by Popcorn, will need a text. + * WebVTT popcorn parser plug-in + * Parses subtitle files in the WebVTT format. + * Specification here: http://www.whatwg.org/specs/web-apps/current-work/webvtt.html + * Styles which appear after timing information are presently ignored. + * Inline styling tags follow HTML conventions and are left in for the browser to handle (or ignore if VTT-specific) + * Data parameter is given by Popcorn, text property holds file contents. * Text is the file contents to be parsed * * @param {Object} data * * Example: - Track-3 - 00:00:15.542 --> 00:00:18.542 A:start D:vertical L:98% - It's a trap! - */ - Popcorn.parser( "parseVTT", function( data ) { + 00:32.500 --> 00:00:33.500 A:start S:50% D:vertical L:98% + Laughs + */ + Popcorn.parser( 'parseVTT', function( data ) { // declare needed variables var retObj = { - title: "", - remote: "", + title: '', + remote: '', data: [] }, subs = [], i = 0, len = 0, - idx = 0, lines, - time, text, - sub; + sub, + rNewLine = /(?:\r\n|\r|\n)/gm; - // [HH:]MM:SS.mmm string to SS.mmm float - // Throws exception if invalid - var toSeconds = function( t_in ) { - var t = t_in.split( ":" ), - l = t_in.length, - time; - - // Invalid time string provided - if ( l !== 12 && l !== 9 ) { - throw "Bad cue"; - } - - l = t.length - 1; - - try { - time = parseInt( t[l-1], 10 )*60 + parseFloat( t[l], 10 ); - - // Hours were 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 ); + lines = data.text.split( rNewLine ); len = lines.length; + // Check for BOF token + if ( len === 0 || lines[0] !== 'WEBVTT' ) { + return retObj; + } + + i++; + while ( i < len ) { - sub = {}; text = []; try { - sub.id = lines[i++]; - // Ignore if id contains "-->" - if ( !sub.id || sub.id.indexOf( "-->" ) !== -1 ) { - throw "Bad cue"; - } - - time = lines[i++].split( /[\t ]*-->[\t ]*/ ); - - sub.start = toSeconds(time[0]); - - // Filter out any trailing styling info - idx = time[1].indexOf( " " ); - if ( idx !== -1 ) { - time[1] = time[1].substr( 0, idx ); - } - - sub.end = toSeconds( time[1] ); + i = skipWhitespace( lines, len, i ); + sub = parseCueHeader( lines[i++] ); // Build single line of text from multi-line subtitle in file while ( i < len && lines[i] ) { text.push( lines[i++] ); } - // Join lines together to one and build subtitle - sub.text = text.join( "
    " ); - subs.push( createTrack( "subtitle", sub ) ); + // Join lines together to one and build subtitle text + sub.text = text.join( '
    ' ); + subs.push( createTrack( 'subtitle', sub ) ); } catch ( e ) { - // Bad cue, advance to end of cue - while ( i < len && lines[i] ) { - i++; - } - } - - // Consume empty whitespace after a cue - while ( i < len && !lines[i] ) { - i++; + i = skipNonWhitespace( lines, len, i ); } } retObj.data = subs; return retObj; }); - + + // [HH:]MM:SS.mmm string to SS.mmm float + // Throws exception if invalid + function toSeconds ( t_in ) { + var t = t_in.split( ':' ), + l = t_in.length, + time; + + // Invalid time string provided + if ( l !== 12 && l !== 9 ) { + throw 'Bad cue'; + } + + l = t.length - 1; + + try { + time = parseInt( t[l-1], 10 ) * 60 + parseFloat( t[l], 10 ); + + // Hours were given + if ( l === 2 ) { + time += parseInt( t[0], 10 ) * 3600; + } + } catch ( e ) { + throw 'Bad cue'; + } + + return time; + }; + + function createTrack( name, attributes ) { + var track = {}; + track[name] = attributes; + return track; + } + + function parseCueHeader ( line ) { + var lineSegments, + args, + sub = {}, + rToken = /-->/, + rWhitespace = /[\t ]+/; + + if ( !line || line.indexOf( '-->' ) === -1 ) { + throw 'Bad cue'; + } + + lineSegments = line.replace( rToken, ' --> ' ).split( rWhitespace ); + + if ( lineSegments.length < 2 ) { + throw 'Bad cue'; + } + + sub.id = line; + sub.start = toSeconds( lineSegments[0] ); + sub.end = toSeconds( lineSegments[2] ); + + return sub; + } + + function skipWhitespace ( lines, len, i ) { + while ( i < len && !lines[i] ) { + i++; + } + + return i; + } + + function skipNonWhitespace ( lines, len, i ) { + while ( i < len && lines[i] ) { + i++; + } + + return i; + } })( Popcorn ); diff --git a/parsers/parserVTT/popcorn.parserVTT.unit.js b/parsers/parserVTT/popcorn.parserVTT.unit.js index c8ea8f4f6..f9be8e602 100644 --- a/parsers/parserVTT/popcorn.parserVTT.unit.js +++ b/parsers/parserVTT/popcorn.parserVTT.unit.js @@ -6,25 +6,25 @@ test( "Popcorn 0.3 WebSRT/VTT Parser Plugin", function () { poppercorn = Popcorn( "#video" ), expectedSubs = [ { - id: "1", - text: "Senator, we're making
    our final approach into Coruscant.", + id: "00:00:02.400 --> 00:00:07.200", + text: "A typical multiline
    subtitle.", start: 2.4, end: 7.2 }, { - id: "2", - text: "Very good, Lieutenant.", + id: "00:09.712-->00:13.399", + text: "No whitespace between time tokens", start: 9.712, end: 13.399 }, { - id: "Track-3", - text: "It's a trap!", + id: "00:00:15.042 --> 00:00:18.042 A:start D:vertical L:98%", + text: "It's a trap! Ignore the timeline styling for now!", start: 15.042, end: 18.042 }, { - id: "ID9", + id: "00:00:20.000--> 00:00:21.670", text: "This text is boldy italicized", start: 20.000, end: 21.670 @@ -50,11 +50,11 @@ test( "Popcorn 0.3 WebSRT/VTT Parser Plugin", function () { strictEqual( evt.id, sub.id, "Correctly parsed id" ); plus(); - strictEqual( evt.text, sub.text, "Correctly parsed text of " + evt.id ); + strictEqual( evt.text, sub.text, "Correctly parsed text of '" + evt.id + "'" ); plus(); - strictEqual( evt.start, sub.start, "Correctly parsed start at " + evt.id ); + strictEqual( evt.start, sub.start, "Correctly parsed start at '" + evt.id + "'" ); plus(); - strictEqual( evt.end, sub.end, "Correctly parsed end at " + evt.id ); + strictEqual( evt.end, sub.end, "Correctly parsed end at '" + evt.id + "'" ); plus(); } }); From 18e818f640a4df29e65db0a67539ed7898e30c91 Mon Sep 17 00:00:00 2001 From: stevenaw Date: Sat, 1 Oct 2011 13:41:18 -0400 Subject: [PATCH 03/78] [#751] Refactored --- parsers/parserSSA/popcorn.parserSSA.js | 160 +++++++++++++------------ 1 file changed, 85 insertions(+), 75 deletions(-) diff --git a/parsers/parserSSA/popcorn.parserSSA.js b/parsers/parserSSA/popcorn.parserSSA.js index 51574c192..993752b9b 100644 --- a/parsers/parserSSA/popcorn.parserSSA.js +++ b/parsers/parserSSA/popcorn.parserSSA.js @@ -26,53 +26,25 @@ 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: [] }, + rNewLineFile = /(?:\r\n|\r|\n)/gm, subs = [], - startIdx, - endIdx, - textIdx, lines, - fields, - numFields, - sub, - text, + headers, 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; - }; + len; // Here is where the magic happens // Split on line breaks - lines = data.text.split( /(?:\r\n|\r|\n)/gm ); + lines = data.text.split( rNewLineFile ); len = lines.length; // Ignore non-textual info @@ -80,53 +52,91 @@ 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; - } - } + headers = parseFieldHeaders( lines[++i] ); 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, "
    " ); - subs.push( createTrack( "subtitle", sub ) ); + try { + subs.push( createTrack( "subtitle", parseSub( lines[i], headers ) ) ); + } catch ( e ) {} } retObj.data = subs; return retObj; }); - + + function parseSub( line, headers ) { + // Trim beginning 'Dialogue: ' and split on delim + var fields = line.substr( 10 ).split( "," ), + rAdvancedStyles = /\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}/gi, + rNewLineSSA = /\\N/gi, + sub; + + sub = { + start: toSeconds( fields[headers.start] ), + end: toSeconds( fields[headers.end] ) + }; + + // Invalid time, skip + if ( sub.start === -1 || sub.end === -1 ) { + throw "Invalid time"; + } + + // Eliminate advanced styles and convert forced line breaks + sub.text = getTextFromFields( fields, headers.text ).replace( rAdvancedStyles, "" ).replace( rNewLineSSA, "
    " ); + + return sub; + } + + // h:mm:ss.cc (centisec) string to SS.mmm + // Returns -1 if invalid + function toSeconds( t_in ) { + var t = t_in.split( ":" ); + + // Not all there + if ( t_in.length !== 10 || t.length < 3 ) { + return -1; + } + + return parseInt( t[0], 10 )*3600 + parseInt( t[1], 10 )*60 + parseFloat( t[2], 10 ); + } + + function getTextFromFields( fields, startIdx ) { + var fieldLen = fields.length, + text = [], + i = startIdx; + + // There may be commas in the text which were split, append back together into one line + for( ; i < fieldLen; i++ ) { + text.push( fields[i] ); + } + + return text.join( "," ); + } + + function createTrack( name, attributes ) { + var track = {}; + track[name] = attributes; + return track; + } + + function parseFieldHeaders( line ) { + // Trim 'Format: ' off front, split on delim + var fields = line.substr( 8 ).split( ", " ), + result = {}, + len, + i; + + //Find where in Dialogue string the start, end and text info is + for ( i = 0, len = fields.length; i < len; i++ ) { + if ( fields[i] === "Start" ) { + result.start = i; + } else if ( fields[i] === "End" ) { + result.end = i; + } else if ( fields[i] === "Text" ) { + result.text = i; + } + } + + return result; + } })( Popcorn ); From 4c30f02987a33d14c52d99afb948d3b71e5d53e0 Mon Sep 17 00:00:00 2001 From: Matthew Schranz Date: Tue, 4 Oct 2011 13:14:52 -0400 Subject: [PATCH 04/78] [#740] Initial workings of Comment Plugin. Still need to see if it's current functionality is indended. --- plugins/facebook/popcorn.facebook.html | 10 ++++++++++ plugins/facebook/popcorn.facebook.js | 12 +++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/plugins/facebook/popcorn.facebook.html b/plugins/facebook/popcorn.facebook.html index 4da792618..66c5900da 100755 --- a/plugins/facebook/popcorn.facebook.html +++ b/plugins/facebook/popcorn.facebook.html @@ -10,6 +10,7 @@ var p = Popcorn( "#video" ) .volume( 0 ) .play() + /* .facebook({ type: "live-stream", target: "activitydiv", @@ -55,6 +56,13 @@ width: 300, start: 10, end: 50 + })*/ + .facebook({ + href: "facebook.com", + type: "COMMENTS", + target: "commentdiv", + start: 5, + end: 60 }); }, false); @@ -85,6 +93,8 @@

    Popcorn Facebook Plug-in Demo

    +
    +

    diff --git a/plugins/facebook/popcorn.facebook.js b/plugins/facebook/popcorn.facebook.js index 2ec920b54..976092011 100755 --- a/plugins/facebook/popcorn.facebook.js +++ b/plugins/facebook/popcorn.facebook.js @@ -59,7 +59,7 @@ options: { type: { elem: "select", - options: [ "LIKE", "LIKE-BOX", "ACTIVITY", "FACEPILE", "LIVE-STREAM", "SEND" ], + options: [ "LIKE", "LIKE-BOX", "ACTIVITY", "FACEPILE", "LIVE-STREAM", "SEND", "COMMENTS" ], label: "Type" }, target: "facebook-container", @@ -158,6 +158,11 @@ elem: "input", options: [ "false", "true" ], label: "Always_post_to_friends" + }, + num_posts: { + elem: "input", + type: "number", + label: "Number of Comments" } } }, @@ -194,7 +199,7 @@ _type = _type.toLowerCase(); var validType = function( type ) { - return ( [ "like", "like-box", "activity", "facepile", "live-stream", "send" ].indexOf( type ) > -1 ); + return ( [ "like", "like-box", "activity", "facepile", "live-stream", "send", "comments" ].indexOf( type ) > -1 ); }; // Checks if type is valid @@ -218,7 +223,8 @@ // create an array of Facebook widget attributes var fbAttrs = ( "width height layout show_faces stream header colorscheme" + - " maxrows border_color recommendations font always_post_to_friends xid" + " maxrows border_color recommendations font always_post_to_friends xid" + + " num_posts" ).split(" "); Popcorn.forEach( fbAttrs, function( attr ) { From c9ebedd2378c23584085cedf6d1f4aeb72a9427a Mon Sep 17 00:00:00 2001 From: Matthew Schranz Date: Tue, 4 Oct 2011 20:50:06 -0400 Subject: [PATCH 05/78] [#734]Setup demo to show how comment is currently functioning --- plugins/facebook/popcorn.facebook.html | 18 ++++++++++-------- plugins/facebook/popcorn.facebook.js | 6 +++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/plugins/facebook/popcorn.facebook.html b/plugins/facebook/popcorn.facebook.html index 66c5900da..656390d59 100755 --- a/plugins/facebook/popcorn.facebook.html +++ b/plugins/facebook/popcorn.facebook.html @@ -24,12 +24,12 @@ target: "likediv", layout: "box_count", start: 5, - end: 50 + end: 15 }) .facebook({ type: "send", target: "likediv", - start: 1, + start: 10, end: 15 }) .facebook({ @@ -39,7 +39,7 @@ header: "false", target: "likeboxdiv", start: 6, - end: 50 + end: 15 }) .facebook({ site: "http://popcornjs.org/", @@ -47,7 +47,7 @@ target: "activitydiv", header: true, start: 11, - end: 50 + end: 15 }) .facebook({ href: "https://www.facebook.com/boardwalkempire", @@ -55,14 +55,16 @@ target: "facepilediv", width: 300, start: 10, - end: 50 - })*/ + end: 15 + }) + */ .facebook({ - href: "facebook.com", + href: "popcornjs.org", type: "COMMENTS", target: "commentdiv", start: 5, - end: 60 + end: 50, + width: 400 }); }, false); diff --git a/plugins/facebook/popcorn.facebook.js b/plugins/facebook/popcorn.facebook.js index 976092011..43d09bf6f 100755 --- a/plugins/facebook/popcorn.facebook.js +++ b/plugins/facebook/popcorn.facebook.js @@ -161,14 +161,14 @@ }, num_posts: { elem: "input", - type: "number", - label: "Number of Comments" + type: "text", + label: "Number_of_Comments" } } }, _setup: function( options ) { - + var target = document.getElementById( options.target ), _type = options.type; From 08e08ddc045e1eaff933d1feb44915eca2b7ce0c Mon Sep 17 00:00:00 2001 From: Matthew Schranz Date: Tue, 4 Oct 2011 21:03:23 -0400 Subject: [PATCH 06/78] [#734]Setup demo to show how comment is currently functioning --- plugins/facebook/popcorn.facebook.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/facebook/popcorn.facebook.js b/plugins/facebook/popcorn.facebook.js index 43d09bf6f..5eb3e513e 100755 --- a/plugins/facebook/popcorn.facebook.js +++ b/plugins/facebook/popcorn.facebook.js @@ -233,7 +233,11 @@ options._facebookdiv.setAttribute( attr, options[ attr ] ); } }); - + + if ( _type === "comments" ) { + target.style.overflow = "auto"; + } + if ( !target && Popcorn.plugin.debug ) { throw new Error( "Facebook target container doesn't exist" ); } From cedcd7646c25e5e9a040b1e1e62d19a9918a544f Mon Sep 17 00:00:00 2001 From: David Seifried Date: Thu, 6 Oct 2011 11:30:57 -0400 Subject: [PATCH 07/78] [#770] Removed the old baseplayer code from the players directory --- players/baseplayer/popcorn.baseplayer.html | 90 --------- players/baseplayer/popcorn.baseplayer.js | 142 -------------- .../baseplayer/popcorn.baseplayer.unit.html | 78 -------- players/baseplayer/popcorn.baseplayer.unit.js | 180 ------------------ 4 files changed, 490 deletions(-) delete mode 100644 players/baseplayer/popcorn.baseplayer.html delete mode 100644 players/baseplayer/popcorn.baseplayer.js delete mode 100644 players/baseplayer/popcorn.baseplayer.unit.html delete mode 100644 players/baseplayer/popcorn.baseplayer.unit.js diff --git a/players/baseplayer/popcorn.baseplayer.html b/players/baseplayer/popcorn.baseplayer.html deleted file mode 100644 index 85358cbf9..000000000 --- a/players/baseplayer/popcorn.baseplayer.html +++ /dev/null @@ -1,90 +0,0 @@ - - - - Popcorn Base Player Example - - - - - - - - - -
    - Ticks:
    - Seconds:
    - Event Output:
    - -
    - Top:
    - Left:
    - Bottom:
    - Right:
    - Width:
    - Height:
    -
    - - This is a container for the player, auto-sized for testing purposes. It displays CSS values. - -
    -
    - This demo showcases basic functionality of a player. It is a shell of an HTMLMediaElement with basic timing routines.
    - At 2 seconds, the phrase "2 seconds reached" will appear beside 'Event Output'
    - - diff --git a/players/baseplayer/popcorn.baseplayer.js b/players/baseplayer/popcorn.baseplayer.js deleted file mode 100644 index 5e3d1dce7..000000000 --- a/players/baseplayer/popcorn.baseplayer.js +++ /dev/null @@ -1,142 +0,0 @@ -(function( global, doc ) { - Popcorn.baseplayer = function() { - return new Popcorn.baseplayer.init(); - }; - - Popcorn.baseplayer.init = function() { - this.readyState = 0; - this.currentTime = 0; - this.baselineTime = new Date(); - this.duration = 0; - this.paused = 1; - this.ended = 0; - this.volume = 1; - this.muted = 0; - this.playbackRate = 1; - - // These are considered to be "on" by being defined. Initialize to undefined - this.autoplay = null; - this.loop = null; - - // List of events - this._events = {}; - - // The underlying player resource. May be , diff --git a/parsers/parserSSA/popcorn.parserSSA.js b/parsers/parserSSA/popcorn.parserSSA.js index 5dea065ec..09cadc85c 100644 --- a/parsers/parserSSA/popcorn.parserSSA.js +++ b/parsers/parserSSA/popcorn.parserSSA.js @@ -1,8 +1,8 @@ // PARSER: 0.3 SSA/ASS -(function (Popcorn) { +(function ( Popcorn ) { /** - * SSA/ASS popcorn parser plug-in + * 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}) @@ -10,9 +10,9 @@ * 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 @@ -26,7 +26,7 @@ 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 @@ -41,91 +41,91 @@ headers, i = 0, len; - + // Here is where the magic happens // Split on line breaks lines = data.text.split( rNewLineFile ); len = lines.length; - + // Ignore non-textual info while ( i < len && lines[ i ] !== "[Events]" ) { i++; } - + headers = parseFieldHeaders( lines[ ++i ] ); - + while ( ++i < len && lines[ i ] && lines[ i ][ 0 ] !== "[" ) { try { subs.push( createTrack( "subtitle", parseSub( lines[ i ], headers ) ) ); } catch ( e ) {} } - + retObj.data = subs; return retObj; }); - + function parseSub( line, headers ) { // Trim beginning 'Dialogue: ' and split on delim var fields = line.substr( 10 ).split( "," ), rAdvancedStyles = /\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}/gi, rNewLineSSA = /\\N/gi, sub; - + sub = { start: toSeconds( fields[ headers.start ] ), end: toSeconds( fields[ headers.end ] ) }; - + // Invalid time, skip if ( sub.start === -1 || sub.end === -1 ) { throw "Invalid time"; } - + // Eliminate advanced styles and convert forced line breaks sub.text = getTextFromFields( fields, headers.text ).replace( rAdvancedStyles, "" ).replace( rNewLineSSA, "
    " ); - + return sub; } - + // h:mm:ss.cc (centisec) string to SS.mmm // Returns -1 if invalid function toSeconds( t_in ) { var t = t_in.split( ":" ); - + // Not all there if ( t_in.length !== 10 || t.length < 3 ) { return -1; } - - return parseInt( t[ 0 ], 10 )*3600 + parseInt( t[ 1 ], 10 )*60 + parseFloat( t[ 2 ], 10 ); + + return parseInt( t[ 0 ], 10 )*3600 + parseInt( t[ 1 ], 10 ) * 60 + parseFloat( t[ 2 ], 10 ); } - + function getTextFromFields( fields, startIdx ) { var fieldLen = fields.length, text = [ ], i = startIdx; - + // There may be commas in the text which were split, append back together into one line for( ; i < fieldLen; i++ ) { text.push( fields[ i ] ); } - + return text.join( "," ); } - + function createTrack( name, attributes ) { var track = {}; track[ name ] = attributes; return track; } - + function parseFieldHeaders( line ) { // Trim 'Format: ' off front, split on delim var fields = line.substr( 8 ).split( ", " ), result = {}, len, i; - + //Find where in Dialogue string the start, end and text info is for ( i = 0, len = fields.length; i < len; i++ ) { if ( fields[ i ] === "Start" ) { @@ -136,7 +136,7 @@ result.text = i; } } - + return result; } })( Popcorn ); diff --git a/parsers/parserSSA/popcorn.parserSSA.unit.html b/parsers/parserSSA/popcorn.parserSSA.unit.html index bb5511661..f04845bb7 100644 --- a/parsers/parserSSA/popcorn.parserSSA.unit.html +++ b/parsers/parserSSA/popcorn.parserSSA.unit.html @@ -4,11 +4,11 @@ Popcorn 0.3 SSA parser Plug-in Test - - + @@ -22,25 +22,25 @@

      - - diff --git a/parsers/parserSSA/popcorn.parserSSA.unit.js b/parsers/parserSSA/popcorn.parserSSA.unit.js index 37eb03014..82ca47781 100644 --- a/parsers/parserSSA/popcorn.parserSSA.unit.js +++ b/parsers/parserSSA/popcorn.parserSSA.unit.js @@ -1,5 +1,5 @@ test( "Popcorn 0.3 SSA/ASS Parser Plugin", function () { - + var count = 0, numSubs = 0, sub, @@ -21,25 +21,25 @@ test( "Popcorn 0.3 SSA/ASS Parser Plugin", function () { end: 18.04 } ], - expects = subs.length*3 + 1; - + expects = subs.length * 3 + 1; + function plus() { if ( ++count === expects ) { start(); } } - + poppercorn.parseSSA( "data/data.ssa" ); - + expect( expects ); stop( 5000 ); - + // Allow load time setTimeout(function () { - Popcorn.forEach( poppercorn.getTrackEvents(), function(evt) { + Popcorn.forEach( poppercorn.getTrackEvents(), function( evt ) { if( evt._natives.type === "subtitle" ) { - sub = subs[numSubs++]; - + 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 ); @@ -48,10 +48,9 @@ test( "Popcorn 0.3 SSA/ASS Parser Plugin", function () { plus(); } }); - + equals( subs.length, numSubs, "Parsed all subtitles" ); plus(); }, 500); - }); From f9e02e9bae81b5561242a3d63335290fe7335b8f Mon Sep 17 00:00:00 2001 From: stevenaw Date: Tue, 18 Oct 2011 21:10:32 -0400 Subject: [PATCH 20/78] [#751] Fix lint --- parsers/parserVTT/popcorn.parserVTT.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parsers/parserVTT/popcorn.parserVTT.js b/parsers/parserVTT/popcorn.parserVTT.js index 6d5e5f52d..6fdf5cae2 100644 --- a/parsers/parserVTT/popcorn.parserVTT.js +++ b/parsers/parserVTT/popcorn.parserVTT.js @@ -94,7 +94,7 @@ } return time; - }; + } function createTrack( name, attributes ) { var track = {}; From 169a9d765f950514252a834ea7b8c0d53baf4e8d Mon Sep 17 00:00:00 2001 From: ScottDowne Date: Thu, 20 Oct 2011 11:32:35 -0400 Subject: [PATCH 21/78] #t781 proper html5 to youtube sound conversion --- players/youtube/popcorn.youtube.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/players/youtube/popcorn.youtube.js b/players/youtube/popcorn.youtube.js index 3af9f2ef6..3a38918d3 100755 --- a/players/youtube/popcorn.youtube.js +++ b/players/youtube/popcorn.youtube.js @@ -18,7 +18,7 @@ Popcorn.player( "youtube", { // state code for volume changed polling volumeChanged = false, lastMuted = false, - lastVolume = 0; + lastVolume = 100; container.id = media.id + Popcorn.guid(); @@ -159,18 +159,18 @@ Popcorn.player( "youtube", { Popcorn.player.defineProperty( media, "volume", { set: function( val ) { - if ( youtubeObject.getVolume() !== val ) { + if ( youtubeObject.getVolume() / 100 !== val ) { - youtubeObject.setVolume( val ); + youtubeObject.setVolume( val * 100 ); lastVolume = youtubeObject.getVolume(); media.dispatchEvent( "volumechange" ); } - return youtubeObject.getVolume(); + return youtubeObject.getVolume() / 100; }, get: function() { - return youtubeObject.getVolume(); + return youtubeObject.getVolume() / 100; } }); From 595b111b5f6350664b6364891bc2dff592ec3338 Mon Sep 17 00:00:00 2001 From: Matthew Schranz Date: Thu, 20 Oct 2011 11:45:22 -0400 Subject: [PATCH 22/78] [#740] Finished 2 small style errors --- plugins/facebook/popcorn.facebook.html | 2 +- plugins/facebook/popcorn.facebook.js | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/facebook/popcorn.facebook.html b/plugins/facebook/popcorn.facebook.html index 5c540fcac..25a8434ea 100755 --- a/plugins/facebook/popcorn.facebook.html +++ b/plugins/facebook/popcorn.facebook.html @@ -38,7 +38,7 @@ header: "false", target: "likeboxdiv", start: 6, - end: 15 + end: 15 }) .facebook({ site: "http://popcornjs.org/", diff --git a/plugins/facebook/popcorn.facebook.js b/plugins/facebook/popcorn.facebook.js index 9b256b4e1..f4a15a83d 100755 --- a/plugins/facebook/popcorn.facebook.js +++ b/plugins/facebook/popcorn.facebook.js @@ -194,7 +194,6 @@ }; } - // Lowercase to make value consistent no matter what user inputs _type = _type.toLowerCase(); @@ -207,7 +206,6 @@ throw new Error( "Facebook plugin type was invalid." ); } - options._container = document.createElement( "div" ); options._container.id = "facebookdiv-" + Popcorn.guid(); options._facebookdiv = document.createElement( "fb:" + _type ); From 501fbbdf7f885b4eeee2ffcef43e4ccd7585da48 Mon Sep 17 00:00:00 2001 From: ScottDowne Date: Thu, 20 Oct 2011 12:13:27 -0400 Subject: [PATCH 23/78] #t782 default youtube player size --- players/youtube/popcorn.youtube.html | 2 +- players/youtube/popcorn.youtube.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/players/youtube/popcorn.youtube.html b/players/youtube/popcorn.youtube.html index 9700f77da..91678f399 100644 --- a/players/youtube/popcorn.youtube.html +++ b/players/youtube/popcorn.youtube.html @@ -141,7 +141,7 @@
      -

      +

      diff --git a/players/youtube/popcorn.youtube.js b/players/youtube/popcorn.youtube.js index 3af9f2ef6..d243d6f68 100755 --- a/players/youtube/popcorn.youtube.js +++ b/players/youtube/popcorn.youtube.js @@ -29,7 +29,9 @@ Popcorn.player( "youtube", { var flashvars, params, attributes, - src; + src, + width, + height; // expose a callback to this scope, that is called from the global callback youtube calls onYouTubePlayerReady[ container.id ] = function() { @@ -203,8 +205,12 @@ Popcorn.player( "youtube", { src = /^.*[\/=](.{11})/.exec( media.src )[ 1 ]; + // setting youtube player's height and width, default to 560 x 315 + width = media.style.width ? ""+media.offsetWidth : "560"; + height = media.style.height ? ""+media.offsetHeight : "315"; + swfobject.embedSWF( "http://www.youtube.com/e/" + src + "?enablejsapi=1&playerapiid=" + container.id + "&version=3", - container.id, media.offsetWidth, media.offsetHeight, "8", null, + container.id, width, height, "8", null, flashvars, params, attributes ); }; From e6be45f2a7a5f9a3e5c532911e8a6da833185165 Mon Sep 17 00:00:00 2001 From: ScottDowne Date: Thu, 20 Oct 2011 12:14:41 -0400 Subject: [PATCH 24/78] #t782 removed testing code left behind --- players/youtube/popcorn.youtube.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/players/youtube/popcorn.youtube.html b/players/youtube/popcorn.youtube.html index 91678f399..9700f77da 100644 --- a/players/youtube/popcorn.youtube.html +++ b/players/youtube/popcorn.youtube.html @@ -141,7 +141,7 @@
      -

      +

      From d51c1fcf1426d44da39495c254f4f88bb84b51bf Mon Sep 17 00:00:00 2001 From: stevenaw Date: Thu, 20 Oct 2011 20:40:32 -0400 Subject: [PATCH 25/78] [#t751] Styling --- parsers/parserSSA/popcorn.parserSSA.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parsers/parserSSA/popcorn.parserSSA.js b/parsers/parserSSA/popcorn.parserSSA.js index 09cadc85c..1c2088251 100644 --- a/parsers/parserSSA/popcorn.parserSSA.js +++ b/parsers/parserSSA/popcorn.parserSSA.js @@ -97,7 +97,7 @@ return -1; } - return parseInt( t[ 0 ], 10 )*3600 + parseInt( t[ 1 ], 10 ) * 60 + parseFloat( t[ 2 ], 10 ); + return parseInt( t[ 0 ], 10 ) * 3600 + parseInt( t[ 1 ], 10 ) * 60 + parseFloat( t[ 2 ], 10 ); } function getTextFromFields( fields, startIdx ) { @@ -105,7 +105,7 @@ text = [ ], i = startIdx; - // There may be commas in the text which were split, append back together into one line + // There may be commas in the text which were split, append back together into one line for( ; i < fieldLen; i++ ) { text.push( fields[ i ] ); } From 5a888f6feb7d9680b9bfebd8d83d3f042912251b Mon Sep 17 00:00:00 2001 From: stevenaw Date: Thu, 20 Oct 2011 21:57:40 -0400 Subject: [PATCH 26/78] [#t543] Popcorn tries parse XML on xhr, Opera now reads ns'd id attribute on subtitle --- parsers/parserTTML/popcorn.parserTTML.js | 2 +- popcorn.js | 26 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/parsers/parserTTML/popcorn.parserTTML.js b/parsers/parserTTML/popcorn.parserTTML.js index 97a83142a..048ce433f 100644 --- a/parsers/parserTTML/popcorn.parserTTML.js +++ b/parsers/parserTTML/popcorn.parserTTML.js @@ -102,7 +102,7 @@ // 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, "
      "); - sub.id = node.getAttribute( "xml:id" ); + sub.id = node.getAttribute( "xml:id" ) || node.getAttribute( "id" ); sub.start = toSeconds ( node.getAttribute( "begin" ), timeOffset ); sub.end = toSeconds( node.getAttribute( "end" ), timeOffset ); sub.target = region; diff --git a/popcorn.js b/popcorn.js index f685b662f..9e1fc3f9c 100644 --- a/popcorn.js +++ b/popcorn.js @@ -1799,6 +1799,27 @@ var data, json = null; + function textToXML ( text ) { + try { + if ( window.DOMParser ) { + + var parser = new DOMParser(); + return parser.parseFromString( text, "text/xml" ); + + } else { + + var xml = new ActiveXObject( "Microsoft.XMLDOM" ); + + xml.async = false; + xml.loadXML( text ); + + return xml; + } + } catch ( e ) { + // return null on error + } + } + settings.ajax.onreadystatechange = function() { if ( settings.ajax.readyState === 4 ) { @@ -1815,6 +1836,11 @@ json: json }; + if ( !data.xml || !data.xml.documentElement ) { + // Check for null documentElement as well so IE will cooperate + data.xml = textToXML( settings.ajax.responseText ); + } + // If a dataType was specified, return that type of data if ( settings.dataType ) { data = data[ settings.dataType ]; From 710eae9ae717563539b91080ca13ee503af055ce Mon Sep 17 00:00:00 2001 From: stevenaw Date: Thu, 20 Oct 2011 23:46:46 -0400 Subject: [PATCH 27/78] [#543] Unit tests, minor fix in parse error handling --- popcorn.js | 15 ++++++++-- test/data/test.ttml | 11 ++++++++ test/popcorn.unit.js | 66 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 test/data/test.ttml diff --git a/popcorn.js b/popcorn.js index 9e1fc3f9c..a4f0e2d90 100644 --- a/popcorn.js +++ b/popcorn.js @@ -1801,14 +1801,23 @@ function textToXML ( text ) { try { + var xml = null; + if ( window.DOMParser ) { var parser = new DOMParser(); - return parser.parseFromString( text, "text/xml" ); + xml = parser.parseFromString( text, "text/xml" ); + + var found = xml.getElementsByTagName( "parsererror" ); + if ( !found || !found.length || !found[ 0 ].childNodes.length ) { + return xml; + } + + return null; } else { - var xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml = new ActiveXObject( "Microsoft.XMLDOM" ); xml.async = false; xml.loadXML( text ); @@ -1816,7 +1825,7 @@ return xml; } } catch ( e ) { - // return null on error + // suppress } } diff --git a/test/data/test.ttml b/test/data/test.ttml new file mode 100644 index 000000000..10f6b3347 --- /dev/null +++ b/test/data/test.ttml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/test/popcorn.unit.js b/test/popcorn.unit.js index b5610da39..5714359bc 100644 --- a/test/popcorn.unit.js +++ b/test/popcorn.unit.js @@ -3218,6 +3218,71 @@ test( "dataType: Text Response", function() { }); }); +test( "XML Conversion", function() { + + var expects, + count = 0, + i, + len, + validXML = [ "data/test.xml", "data/test.ttml" ], + invalidXML = [ "data/test.txt", "data/remoteA.js" ]; + + function plus() { + if ( ++count === expects ) { + start(); + } + } + + expects = validXML.length * 2 + invalidXML.length * 3; + + expect( expects ); + + stop(); + + function testValidXML( fileName ) { + Popcorn.xhr({ + url: fileName, + success: function( data ) { + + ok( data, "xhr returns data" ); + plus(); + + var parser = new DOMParser(), + xml = parser.parseFromString( ' ',"text/xml" ); + + equal( data.xml.toString(), xml.toString(), "data.xml returns a document of xml for " + fileName ); + plus(); + } + }); + } + + function testInvalidXML( fileName ) { + Popcorn.xhr({ + url: fileName, + success: function( data ) { + + ok( data, "xhr returns data" ); + plus(); + + ok( !data.xml, "data.xml is null for non-xml file: " + fileName ); + plus(); + + ok( data.text, "data.text is still not null" ); + plus(); + } + }); + } + + for ( i = 0, len = validXML.length; i < len; i++ ) { + testValidXML( validXML[ i ] ); + } + + for ( i = 0, len = invalidXML.length; i < len; i++ ) { + testInvalidXML( invalidXML[ i ] ); + } +}); + + test( "JSON Response", function() { var expects = 2, @@ -3477,6 +3542,7 @@ test( "XML Response", function() { }); }); + test( "dataType: XML Response", function() { var expects = 2, From a82a329a0cad711a9e347605a220426a33e5225b Mon Sep 17 00:00:00 2001 From: stevenaw Date: Sat, 22 Oct 2011 02:46:53 -0400 Subject: [PATCH 28/78] [#543] Remove ActiveX references, IE9+ has DOMParser --- popcorn.js | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/popcorn.js b/popcorn.js index a4f0e2d90..ce708eacb 100644 --- a/popcorn.js +++ b/popcorn.js @@ -1799,29 +1799,14 @@ var data, json = null; + // Returns null on error function textToXML ( text ) { try { - var xml = null; - - if ( window.DOMParser ) { - - var parser = new DOMParser(); - xml = parser.parseFromString( text, "text/xml" ); - - var found = xml.getElementsByTagName( "parsererror" ); - - if ( !found || !found.length || !found[ 0 ].childNodes.length ) { - return xml; - } - - return null; - } else { - - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - - xml.async = false; - xml.loadXML( text ); + var parser = new DOMParser(); + var xml = parser.parseFromString( text, "text/xml" ); + var foundErrors = xml.getElementsByTagName( "parsererror" ); + if ( !foundErrors || !foundErrors.length || !foundErrors[ 0 ].childNodes.length ) { return xml; } } catch ( e ) { From 3452997045606dc774be01bca0c3630d7af72168 Mon Sep 17 00:00:00 2001 From: Christopher De Cairos Date: Mon, 24 Oct 2011 10:47:00 -0400 Subject: [PATCH 29/78] fixes as per review [#728] --- players/vimeo/popcorn.vimeo.html | 4 ++-- players/vimeo/popcorn.vimeo.js | 18 ++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/players/vimeo/popcorn.vimeo.html b/players/vimeo/popcorn.vimeo.html index b92feac62..78a797af8 100644 --- a/players/vimeo/popcorn.vimeo.html +++ b/players/vimeo/popcorn.vimeo.html @@ -56,7 +56,7 @@ // Volume document.getElementById( "btnVolume" ).addEventListener( "click", function() { - volume = volume === 100 ? 50 : 100; + volume = volume === 1 ? 0.5 : 1; player.volume( volume ); }, false); @@ -178,7 +178,7 @@
      Current Time (s):
      Video Duration (s): -
      Volume (0-100): +
      Volume (0-1):
      Load Status: Not Started
      diff --git a/players/vimeo/popcorn.vimeo.js b/players/vimeo/popcorn.vimeo.js index 79ec595f8..134d88d75 100644 --- a/players/vimeo/popcorn.vimeo.js +++ b/players/vimeo/popcorn.vimeo.js @@ -20,12 +20,18 @@ seeking = false, volumeChanged = false, lastMuted = false, - lastVolume = 0; + lastVolume = 0, + height, + width; vimeoContainer.id = media.id + Popcorn.guid(); media.appendChild( vimeoContainer ); + // setting vimeo player's height and width, default to 560 x 315 + width = media.style.width ? ""+media.offsetWidth : "560"; + height = media.style.height ? ""+media.offsetHeight : "315"; + var vimeoInit = function() { var flashvars, @@ -179,20 +185,20 @@ set: function( val ) { if ( !val || typeof val !== "number" || ( val < 0 || val > 1 ) ) { - return vimeoObject.api_getVolume(); + return vimeoObject.api_getVolume() / 100; } if ( vimeoObject.api_getVolume() !== val ) { - vimeoObject.api_setVolume( val ); + vimeoObject.api_setVolume( val * 100 ); lastVolume = vimeoObject.api_getVolume(); media.dispatchEvent( "volumechange" ); } - return vimeoObject.api_getVolume(); + return vimeoObject.api_getVolume() / 100; }, get: function() { - return vimeoObject.api_getVolume(); + return vimeoObject.api_getVolume() / 100; } }); @@ -238,7 +244,7 @@ }; swfobject.embedSWF( "http://vimeo.com/moogaloop.swf", vimeoContainer.id, - media.offsetWidth + "", media.offsetHeight + "", "9.0.0", "expressInstall.swf", + width, height, "9.0.0", "expressInstall.swf", flashvars, params, attributes ); }; From d1e4881a045f9683db376253d7814a470ff12f9c Mon Sep 17 00:00:00 2001 From: Christopher De Cairos Date: Mon, 24 Oct 2011 12:10:30 -0400 Subject: [PATCH 30/78] added effects to min list [#788] --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index b5ccd9f50..06636f1fb 100644 --- a/Makefile +++ b/Makefile @@ -81,6 +81,7 @@ MODULES_UNIT := $(shell find $(MODULES_DIR) -name 'popcorn.*.unit.js' -print) # popcorn + plugins POPCORN_COMPLETE_LIST := --js ${POPCORN_SRC} \ $(shell for js in ${MODULES_SRC} ; do echo --js $$js ; done) \ + $(shell for js in ${EFFECTS_SRC} ; do echo --js $$js ; done) \ $(shell for js in ${PLUGINS_SRC} ; do echo --js $$js ; done) \ $(shell for js in ${PARSERS_SRC} ; do echo --js $$js ; done) \ $(shell for js in ${PLAYERS_SRC} ; do echo --js $$js ; done) From 6eca106cd3eef163ebd90f36b21b4c9488be28b2 Mon Sep 17 00:00:00 2001 From: stevenaw Date: Mon, 24 Oct 2011 19:56:57 -0400 Subject: [PATCH 31/78] [#750] Fixing whitespace issues --- parsers/parserVTT/popcorn.parserVTT.html | 102 +++++++++--------- parsers/parserVTT/popcorn.parserVTT.js | 70 ++++++------ parsers/parserVTT/popcorn.parserVTT.unit.html | 16 +-- parsers/parserVTT/popcorn.parserVTT.unit.js | 19 ++-- 4 files changed, 103 insertions(+), 104 deletions(-) diff --git a/parsers/parserVTT/popcorn.parserVTT.html b/parsers/parserVTT/popcorn.parserVTT.html index 69aba6f13..65519e253 100644 --- a/parsers/parserVTT/popcorn.parserVTT.html +++ b/parsers/parserVTT/popcorn.parserVTT.html @@ -1,54 +1,54 @@ - - Popcorn 0.3 WebSRT/VTT parser Plug-in Demo - - - - - - - - -

      Popcorn 0.3 WebSRT/VTT parser Plug-in Demo

      -

      From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown -
      From 9.712 to 13.399 seconds, "Very good, Lieutenant." is shown -
      From 15.542 to 18.542 seconds, "It's a trap!" is shown, with trap in italics

      -
      - -
      - -

      Subtitle Source

      - - - - - + + Popcorn 1.0 WebSRT/VTT parser Plug-in Demo + + + + + + + + +

      Popcorn 1.0 WebSRT/VTT parser Plug-in Demo

      +

      From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown +
      From 9.712 to 13.399 seconds, "Very good, Lieutenant." is shown +
      From 15.542 to 18.542 seconds, "It's a trap!" is shown, with trap in italics

      +
      + +
      + +

      Subtitle Source

      + + + + + diff --git a/parsers/parserVTT/popcorn.parserVTT.js b/parsers/parserVTT/popcorn.parserVTT.js index 6fdf5cae2..c2d0a7f38 100644 --- a/parsers/parserVTT/popcorn.parserVTT.js +++ b/parsers/parserVTT/popcorn.parserVTT.js @@ -2,89 +2,89 @@ (function ( Popcorn ) { /** - * WebVTT popcorn parser plug-in + * WebVTT popcorn parser plug-in * Parses subtitle files in the WebVTT format. * Specification here: http://www.whatwg.org/specs/web-apps/current-work/webvtt.html * Styles which appear after timing information are presently ignored. * Inline styling tags follow HTML conventions and are left in for the browser to handle (or ignore if VTT-specific) * Data parameter is given by Popcorn, text property holds file contents. * Text is the file contents to be parsed - * + * * @param {Object} data - * + * * Example: 00:32.500 --> 00:00:33.500 A:start S:50% D:vertical L:98% Laughs - */ + */ Popcorn.parser( "parseVTT", function( data ) { - + // declare needed variables var retObj = { title: "", remote: "", - data: [ ] + data: [] }, - subs = [ ], + subs = [], i = 0, len = 0, lines, text, sub, rNewLine = /(?:\r\n|\r|\n)/gm; - + // Here is where the magic happens // Split on line breaks lines = data.text.split( rNewLine ); len = lines.length; - + // Check for BOF token if ( len === 0 || lines[ 0 ] !== "WEBVTT" ) { return retObj; } - + i++; - + while ( i < len ) { - text = [ ]; - + text = []; + try { i = skipWhitespace( lines, len, i ); sub = parseCueHeader( lines[ i++ ] ); - + // Build single line of text from multi-line subtitle in file while ( i < len && lines[ i ] ) { text.push( lines[ i++ ] ); } - + // Join lines together to one and build subtitle text - sub.text = text.join( "
      " ); + sub.text = text.join( "
      " ); subs.push( createTrack( "subtitle", sub ) ); } catch ( e ) { i = skipNonWhitespace( lines, len, i ); } } - + retObj.data = subs; return retObj; }); - + // [HH:]MM:SS.mmm string to SS.mmm float // Throws exception if invalid function toSeconds ( t_in ) { var t = t_in.split( ":" ), l = t_in.length, time; - + // Invalid time string provided if ( l !== 12 && l !== 9 ) { throw "Bad cue"; } - + l = t.length - 1; - - try { + + try { time = parseInt( t[ l-1 ], 10 ) * 60 + parseFloat( t[ l ], 10 ); - + // Hours were given if ( l === 2 ) { time += parseInt( t[ 0 ], 10 ) * 3600; @@ -92,53 +92,53 @@ } catch ( e ) { throw "Bad cue"; } - + return time; } - + function createTrack( name, attributes ) { var track = {}; track[ name ] = attributes; return track; } - + function parseCueHeader ( line ) { var lineSegments, args, sub = {}, rToken = /-->/, rWhitespace = /[\t ]+/; - + if ( !line || line.indexOf( "-->" ) === -1 ) { throw "Bad cue"; } - + lineSegments = line.replace( rToken, " --> " ).split( rWhitespace ); - + if ( lineSegments.length < 2 ) { throw "Bad cue"; } - + sub.id = line; sub.start = toSeconds( lineSegments[ 0 ] ); sub.end = toSeconds( lineSegments[ 2 ] ); - + return sub; } - + function skipWhitespace ( lines, len, i ) { while ( i < len && !lines[ i ] ) { i++; } - + return i; } - + function skipNonWhitespace ( lines, len, i ) { while ( i < len && lines[ i ] ) { i++; } - + return i; } })( Popcorn ); diff --git a/parsers/parserVTT/popcorn.parserVTT.unit.html b/parsers/parserVTT/popcorn.parserVTT.unit.html index 945e97193..60e62ede3 100644 --- a/parsers/parserVTT/popcorn.parserVTT.unit.html +++ b/parsers/parserVTT/popcorn.parserVTT.unit.html @@ -16,27 +16,27 @@ -

      Popcorn 0.3 WebSRT/VTT parser Plug-in Test

      +

      Popcorn 1.0 WebSRT/VTT parser Plug-in Test

        - - +
        From 58626a6547a89d8a31fe48b6a06084be98544015 Mon Sep 17 00:00:00 2001 From: Jon Buckley Date: Tue, 1 Nov 2011 21:56:02 -0400 Subject: [PATCH 76/78] Update Processing.js script to v1.3.6 on the CDN --- plugins/processing/popcorn.processing.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/processing/popcorn.processing.js b/plugins/processing/popcorn.processing.js index ab1b1eaaa..596dffad6 100644 --- a/plugins/processing/popcorn.processing.js +++ b/plugins/processing/popcorn.processing.js @@ -74,7 +74,7 @@ } if ( !window.Processing ) { - Popcorn.getScript( "//processingjs.org/content/download/processing-js-1.3.0/processing-1.3.0.js", function() { + Popcorn.getScript( "//wac.1237.edgecastcdn.net/801237/cdn.processingjs.org/content/download/processing-js-1.3.6/processing-1.3.6.min.js", function() { scriptReady( options ); }); } else { From 3184bf087f38e4f92a30f4a85c1674d293cfbede Mon Sep 17 00:00:00 2001 From: stevenaw Date: Wed, 2 Nov 2011 00:09:41 -0400 Subject: [PATCH 77/78] [#819] Numerous fixes to parser demo .html pages --- parsers/parserJSON/popcorn.parserJSON.html | 88 ++++++++--------- parsers/parserSBV/popcorn.parserSBV.html | 90 ++++++++--------- parsers/parserSRT/popcorn.parserSRT.html | 107 +++++++++++---------- parsers/parserSSA/popcorn.parserSSA.html | 87 ++++++++--------- parsers/parserTTML/popcorn.parserTTML.html | 104 ++++++++++---------- parsers/parserTTXT/popcorn.parserTTXT.html | 87 ++++++++--------- parsers/parserVTT/popcorn.parserVTT.html | 20 +++- parsers/parserXML/popcorn.parserXML.html | 68 ++++++------- 8 files changed, 334 insertions(+), 317 deletions(-) diff --git a/parsers/parserJSON/popcorn.parserJSON.html b/parsers/parserJSON/popcorn.parserJSON.html index ab44e22af..f401f46a1 100644 --- a/parsers/parserJSON/popcorn.parserJSON.html +++ b/parsers/parserJSON/popcorn.parserJSON.html @@ -1,47 +1,47 @@ - - Popcorn 0.3 JSON parser Plug-in Demo - - - - - - - - - - -

        Popcorn 0.3 JSON parser Plug-in Demo

        -

        -
        - -
        - - -
        -
        -
        - - + + Popcorn 1.0 JSON parser Plug-in Demo + + + + + + + + + + +

        Popcorn 1.0 JSON parser Plug-in Demo

        +

        +
        + +
        + + +
        +
        +
        + + diff --git a/parsers/parserSBV/popcorn.parserSBV.html b/parsers/parserSBV/popcorn.parserSBV.html index c7ff3e917..8821edace 100644 --- a/parsers/parserSBV/popcorn.parserSBV.html +++ b/parsers/parserSBV/popcorn.parserSBV.html @@ -1,48 +1,48 @@ - - Popcorn 0.3 SBV parser Plug-in Demo - - - - - - - - - -

        Popcorn 0.3 SBV parser Plug-in Demo

        -

        From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown -
        From 9.712 to 13.399 seconds, "Very good, Lieutenant." is shown -
        From 15.042 to 18.042 seconds, "It's a trap!" is shown

        -
        -
        - -
        - -

        Subtitle Source

        - - + + Popcorn 1.0 SBV parser Plug-in Demo + + + + + + + + +

        Popcorn 1.0 SBV parser Plug-in Demo

        + +

        From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown +
        From 9.712 to 13.399 seconds, "Very good, Lieutenant." is shown +
        From 15.042 to 18.042 seconds, "It's a trap!" is shown

        + +
        + +
        + +

        Subtitle Source

        + + diff --git a/parsers/parserSRT/popcorn.parserSRT.html b/parsers/parserSRT/popcorn.parserSRT.html index 3aa8575bf..70314a719 100644 --- a/parsers/parserSRT/popcorn.parserSRT.html +++ b/parsers/parserSRT/popcorn.parserSRT.html @@ -1,56 +1,57 @@ - - Popcorn 0.3 SRT parser Plug-in Demo - - - - - - - - -

        Popcorn 0.3 SRT parser Plug-in Demo

        - -

        From 2.4 to 5.2 seconds, "[Background Music Playing]" is shown -
        From 6 to 13.7 seconds, "<true> To say that 2 is greater than three (3 > 2) would be lying<true>" is shown -
        From 15.712 to 17.399 seconds, "Oh my god, Watch out! It's coming!!" is shown -
        From 25.712 to 30.399 seconds, "[Bird noises]" is shown

        -
        - -
        - -

        Subtitle Source

        - - - - - + + Popcorn 1.0 SRT parser Plug-in Demo + + + + + + + + +

        Popcorn 1.0 SRT parser Plug-in Demo

        + +

        From 2.4 to 5.2 seconds, "[Background Music Playing]" is shown +
        From 6 to 13.7 seconds, "<true> To say that 2 is greater than three (3 > 2) would be lying<true>" is shown +
        From 15.712 to 17.399 seconds, "Oh my god, Watch out! It's coming!!" is shown +
        From 25.712 to 30.399 seconds, "[Bird noises]" is shown

        + +
        + +
        + +

        Subtitle Source

        + + + + + diff --git a/parsers/parserSSA/popcorn.parserSSA.html b/parsers/parserSSA/popcorn.parserSSA.html index aedb6cb05..b0a053886 100644 --- a/parsers/parserSSA/popcorn.parserSSA.html +++ b/parsers/parserSSA/popcorn.parserSSA.html @@ -1,46 +1,47 @@ - - Popcorn 0.3 SSA parser Plug-in Demo - - - - - - - - - -

        Popcorn 0.3 SSA parser Plug-in Demo

        -

        From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown -
        From 9.71 to 13.39 seconds, "Very good, Lieutenant." is shown -
        From 15.04 to 18.04 seconds, "It's a trap!" is shown

        -
        - -
        -

        Subtitle Source

        - - + + Popcorn 1.0 SSA parser Plug-in Demo + + + + + + + + +

        Popcorn 1.0 SSA parser Plug-in Demo

        + +

        From 2.4 to 7.2 seconds, "Senator, we're making our final approach into Coruscant." is shown +
        From 9.71 to 13.39 seconds, "Very good, Lieutenant." is shown +
        From 15.04 to 18.04 seconds, "It's a trap!" is shown

        + +
        + +
        +

        Subtitle Source

        + + diff --git a/parsers/parserTTML/popcorn.parserTTML.html b/parsers/parserTTML/popcorn.parserTTML.html index 3c410773e..7876161e6 100644 --- a/parsers/parserTTML/popcorn.parserTTML.html +++ b/parsers/parserTTML/popcorn.parserTTML.html @@ -1,54 +1,56 @@ - - Popcorn 0.3 TTML parser Plug-in Demo - - - - - - - - -

        Popcorn 0.3 TTML parser Plug-in Demo

        -

        From 0.76 to 3.45 seconds, "It seems a paradox, does it not," is shown -
        From 5 to 10 seconds, "that the image formed on the Retina should be inverted?" is shown -
        From 10 to 16 seconds, "It is puzzling, why is it we do not see things upside-down?" is shown -
        From 17.2 to 23 seconds, "You have never heard the Theory, then, that the Brain also is inverted?" is shown -
        From 23 to 27 seconds, "No indeed! What a beautiful fact!" is shown -
        From 27.76 to 30.45 seconds, "It seems a paradox, does it not," is shown -
        From 32 to 37 seconds, "that the image formed on the Retina should be inverted?" is shown -
        From 37 to 43 seconds, "It is puzzling, why is it we do not see things upside-down?" is shown -
        From 44.2 to 50 seconds, "You have never heard the Theory, then, that the Brain also is inverted?" is shown -
        From 50 to 54 seconds, "No indeed! What a beautiful fact!" is shown

        -
        - -
        - -

        Subtitle Source

        - - - + + Popcorn 1.0 TTML parser Plug-in Demo + + + + + + + + +

        Popcorn 1.0 TTML parser Plug-in Demo

        + +

        From 0.76 to 3.45 seconds, "It seems a paradox, does it not," is shown +
        From 5 to 10 seconds, "that the image formed on the Retina should be inverted?" is shown +
        From 10 to 16 seconds, "It is puzzling, why is it we do not see things upside-down?" is shown +
        From 17.2 to 23 seconds, "You have never heard the Theory, then, that the Brain also is inverted?" is shown +
        From 23 to 27 seconds, "No indeed! What a beautiful fact!" is shown +
        From 27.76 to 30.45 seconds, "It seems a paradox, does it not," is shown +
        From 32 to 37 seconds, "that the image formed on the Retina should be inverted?" is shown +
        From 37 to 43 seconds, "It is puzzling, why is it we do not see things upside-down?" is shown +
        From 44.2 to 50 seconds, "You have never heard the Theory, then, that the Brain also is inverted?" is shown +
        From 50 to 54 seconds, "No indeed! What a beautiful fact!" is shown

        + +
        + +
        + +

        Subtitle Source

        + + + diff --git a/parsers/parserTTXT/popcorn.parserTTXT.html b/parsers/parserTTXT/popcorn.parserTTXT.html index 92ae798d5..b6ff55b7b 100644 --- a/parsers/parserTTXT/popcorn.parserTTXT.html +++ b/parsers/parserTTXT/popcorn.parserTTXT.html @@ -1,46 +1,47 @@ - - Popcorn 0.3 TTXT parser Plug-in Demo - - - - - - - - -

        Popcorn 0.3 TTXT parser Plug-in Demo

        -

        Subtitles are processed from here

        - -

        From 2.4 to 5.2 seconds, "[Background Music Playing]" is shown -
        From 15.712 to 17.399 seconds, "Heay!!" is shown -
        From 25.712 to 30.399 seconds, "[Bird noises]" is shown

        -
        - -
        - - + + Popcorn 1.0 TTXT parser Plug-in Demo + + + + + + + + +

        Popcorn 0.3 TTXT parser Plug-in Demo

        +

        Subtitles are processed from here

        + +

        From 2.4 to 5.2 seconds, "[Background Music Playing]" is shown +
        From 15.712 to 17.399 seconds, "Heay!!" is shown +
        From 25.712 to 30.399 seconds, "[Bird noises]" is shown

        + +
        + +
        + + diff --git a/parsers/parserVTT/popcorn.parserVTT.html b/parsers/parserVTT/popcorn.parserVTT.html index 65519e253..cb0400f79 100644 --- a/parsers/parserVTT/popcorn.parserVTT.html +++ b/parsers/parserVTT/popcorn.parserVTT.html @@ -10,6 +10,7 @@ - - - - - - -

        Popcorn 0.1 parser Plug-in Demo

        -

        -
        - -
        - -
        - - + + Popcorn 1.0 parser Plug-in Demo + + + + + + + + +

        Popcorn 1.0 parser Plug-in Demo

        +

        +
        + +
        + +
        + + From 00973c0fa6fe510cf689bd7a4f9234f3881b4aeb Mon Sep 17 00:00:00 2001 From: stevenaw Date: Wed, 2 Nov 2011 00:40:56 -0400 Subject: [PATCH 78/78] [#819] Missed one change --- parsers/parserTTXT/popcorn.parserTTXT.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parsers/parserTTXT/popcorn.parserTTXT.html b/parsers/parserTTXT/popcorn.parserTTXT.html index b6ff55b7b..c5927ecd4 100644 --- a/parsers/parserTTXT/popcorn.parserTTXT.html +++ b/parsers/parserTTXT/popcorn.parserTTXT.html @@ -17,7 +17,7 @@ -

        Popcorn 0.3 TTXT parser Plug-in Demo

        +

        Popcorn 1.0 TTXT parser Plug-in Demo

        Subtitles are processed from here

        From 2.4 to 5.2 seconds, "[Background Music Playing]" is shown