Merge pull request #52 from ScottDowne/t1023

[#1023] added player queue to easily allow player authors to fire play a...
This commit is contained in:
David Seifried 2012-05-28 12:59:34 -07:00
Родитель 023eaf4505 a9d3d99cf9
Коммит 863da326ea
9 изменённых файлов: 448 добавлений и 454 удалений

Просмотреть файл

@ -301,23 +301,6 @@
basePlayer.dispatchEvent( "error" );
}
// when a custom player is loaded, load basePlayer state into custom player
basePlayer.addEventListener( "loadedmetadata", function() {
// if a player is not ready before currentTime is called, this will set it after it is ready
basePlayer.currentTime = currentTime;
// same as above with volume and muted
basePlayer.volume = volume;
basePlayer.muted = muted;
});
basePlayer.addEventListener( "loadeddata", function() {
// if play was called before player ready, start playing video
!basePlayer.paused && basePlayer.play();
});
popcorn = new Popcorn.p.init( basePlayer, options );
if ( player._teardown ) {
@ -344,6 +327,36 @@
object.__defineSetter__( description, options.set || Popcorn.nop );
};
// player queue is to help players queue things like play and pause
// HTML5 video's play and pause are asynch, but do fire in sequence
// play() should really mean "requestPlay()" or "queuePlay()" and
// stash a callback that will play the media resource when it's ready to be played
Popcorn.player.playerQueue = function() {
var _queue = [],
_running = false;
return {
next: function() {
_running = false;
_queue.shift();
_queue[ 0 ] && _queue[ 0 ]();
},
add: function( callback ) {
_queue.push(function() {
_running = true;
callback && callback();
});
// if there is only one item on the queue, start it
!_running && _queue[ 0 ]();
}
};
};
// smart will attempt to find you a match, if it does not find a match,
// it will attempt to create a video element with the source,
// if that failed, it will throw.

Просмотреть файл

@ -13,32 +13,43 @@
container = document.createElement( "iframe" ),
lastVolume = 1,
currentTime = 0,
paused = true,
realPaused = true,
widget,
duration = 0,
muted = false;
muted = false,
playerQueue = Popcorn.player.playerQueue();
options._container = container;
media.style.visibility = "hidden";
media.play = function() {
if ( media.paused ) {
paused = false;
playerQueue.add(function() {
media.paused = false;
media.dispatchEvent( "playing" );
media.dispatchEvent( "play" );
widget && widget.play();
}
if ( realPaused ) {
widget && widget.play();
} else {
playerQueue.next();
}
});
};
media.pause = function() {
if ( !media.paused ) {
paused = true;
media.paused = true;
media.dispatchEvent( "pause" );
widget && widget.pause();
}
playerQueue.add(function() {
if ( !realPaused ) {
widget && widget.pause();
} else {
playerQueue.next();
}
});
};
// getter and setter for muted property, multiply volume by 100 as that is the scale soundcloud works on
@ -86,6 +97,11 @@
get: function() {
return duration;
}
},
paused: {
get: function() {
return paused;
}
}
});
// called when the SoundCloud api script has loaded
@ -118,25 +134,34 @@
options.widget = widget = SC.Widget( container.id );
// setup all of our listeners
widget.bind(SC.Widget.Events.FINISH, function() {
media.pause();
media.dispatchEvent( "ended" );
});
widget.bind(SC.Widget.Events.PLAY_PROGRESS, function( data ) {
currentTime = data.currentPosition / 1000;
media.dispatchEvent( "timeupdate" );
});
widget.bind(SC.Widget.Events.PLAY, function( data ) {
if ( media.paused ) {
media.currentTime = currentTime;
media.paused && media.play();
}
paused = realPaused = false;
media.dispatchEvent( "play" );
media.dispatchEvent( "playing" );
media.currentTime = currentTime;
playerQueue.next();
});
widget.bind(SC.Widget.Events.PAUSE, function( data ) {
!media.paused && media.pause();
paused = realPaused = true;
media.dispatchEvent( "pause" );
playerQueue.next();
});
widget.bind(SC.Widget.Events.READY, function( data ) {
widget.getDuration(function( data ) {
@ -209,7 +234,7 @@
// remove all bound soundcloud listeners
for ( var prop in events ) {
widget.unbind( events[ prop ] );
widget && widget.unbind( events[ prop ] );
}
}
});

Просмотреть файл

@ -6,8 +6,8 @@
<script src="../../test/qunit/qunit.js"></script>
<script src="../../popcorn.js"></script>
<script src="../../modules/player/popcorn.player.js"></script>
<script src="popcorn.soundcloud.unit.js"></script>
<script src="popcorn.soundcloud.js"></script>
<script src="popcorn.soundcloud.unit.js"></script>
<script src="../../test/inject.js"></script>
<style>
.soundcloudPlayer {

Просмотреть файл

@ -110,6 +110,7 @@ asyncTest( "Popcorn Integration", function () {
player = Popcorn.soundcloud( "player_1", "http://api.soundcloud.com/tracks/12643174" );
function plus() {
if ( ++count === expects ) {
start();
player.destroy();
@ -118,7 +119,8 @@ asyncTest( "Popcorn Integration", function () {
expect(expects);
player.on( "load", function() {
player.on( "canplaythrough", function() {
ok( true, "Listen works (load event)" );
plus();
@ -130,6 +132,7 @@ asyncTest( "Popcorn Integration", function () {
});
player.on( "pause", function() {
ok( true, "Pause explicitly called" );
plus();
@ -165,13 +168,23 @@ asyncTest( "Events and Player Control", function () {
plus();
});
player.on( "playing", function() {
ok( true, "Playing was fired" );
plus();
player.on( "playing", (function() {
var hasFired = 0;
equal( player.paused(), 0, "Paused is unset" );
plus();
});
return function() {
if ( hasFired ) {
return;
}
hasFired = 1;
ok( true, "Playing was fired" );
plus();
equal( player.paused(), false, "Paused is unset" );
plus();
player.pause();
};
})());
player.on( "play", (function() {
var hasFired = 0;
@ -198,15 +211,16 @@ asyncTest( "Events and Player Control", function () {
equal( player.readyState(), 4, "Ready State is now 4" );
plus();
player.pause();
}, false);
player.on( "pause", function() {
ok( true, "Pause was fired by dispatch" );
plus();
equal( player.paused(), 1, "Paused is set" );
equal( player.paused(), true, "Paused is set" );
player.play();
plus();
});
@ -225,32 +239,52 @@ asyncTest( "Events and Player Control", function () {
})());
player.on( "volumechange", function() {
player.off( "volumechange" );
ok( true, "volumechange was fired by dispatch" );
plus();
});
player.cue( 10, function() {
// Will trigger a "seeked" event to near end
player.currentTime( player.duration() - 1 );
});
player.on( "canplaythrough", function() {
ok( true, "Can play through" );
plus();
// Will trigger a "seeked" event to near end
player.currentTime( player.duration() - 1 );
});
player.on( "seeked", function() {
ok( true, "Seeked was fired" );
plus();
player.on( "seeked", (function() {
var hasFired = 0;
player.emit( "play" );
});
return function() {
if ( hasFired ) {
return;
}
hasFired = 1;
ok( true, "Seeked was fired" );
plus();
};
})());
player.on( "ended", function() {
ok( true, "Media is done playing" );
plus();
equal( player.paused, 1, "Paused is set on end" );
equal( player.paused(), true, "Paused is set on end" );
plus();
});
player.play();
var ready = function() {
player.off( "canplaythrough", ready );
player.play();
};
if ( player.readyState() >= 4 ) {
ready();
} else {
player.on( "canplaythrough", ready );
}
});

Просмотреть файл

@ -20,13 +20,15 @@
vimeoObject,
vimeoContainer = document.createElement( "div" ),
currentTime = 0,
paused = true,
seekTime = 0,
seeking = false,
volumeChanged = false,
lastMuted = false,
lastVolume = 0,
height,
width;
width,
playerQueue = Popcorn.player.playerQueue();
vimeoContainer.id = media.id + Popcorn.guid();
@ -46,6 +48,7 @@
loadStarted = false;
vimeo_player_loaded[ vimeoContainer.id ] = function() {
vimeoObject = document.getElementById( vimeoContainer.id );
vimeo_player_loaded.seek[ vimeoContainer.id ] = function( time ) {
@ -57,20 +60,21 @@
};
vimeo_player_loaded.play[ vimeoContainer.id ] = function() {
if ( media.paused ) {
media.paused = false;
media.dispatchEvent( "play" );
media.dispatchEvent( "playing" );
timeUpdate();
}
paused = false;
media.dispatchEvent( "play" );
media.dispatchEvent( "playing" );
timeUpdate();
playerQueue.next();
};
vimeo_player_loaded.pause[ vimeoContainer.id ] = function() {
if ( !media.paused ) {
media.paused = true;
media.dispatchEvent( "pause" );
}
paused = true;
media.dispatchEvent( "pause" );
playerQueue.next();
};
vimeo_player_loaded.loadProgress[ vimeoContainer.id ] = function( progress ) {
@ -121,22 +125,32 @@
};
media.play = function() {
media.paused = false;
media.dispatchEvent( "play" );
media.dispatchEvent( "playing" );
timeUpdate();
vimeoObject.api_play();
paused = false;
playerQueue.add(function() {
if ( vimeoObject.api_paused() ) {
vimeoObject.api_play();
} else {
playerQueue.next();
}
});
};
media.pause = function() {
if ( !media.paused ) {
paused = true;
playerQueue.add(function() {
media.paused = true;
media.dispatchEvent( "pause" );
vimeoObject.api_pause();
}
if ( !vimeoObject.api_paused() ) {
vimeoObject.api_pause();
} else {
playerQueue.next();
}
});
};
Popcorn.player.defineProperty( media, "currentTime", {
@ -163,6 +177,14 @@
}
});
Popcorn.player.defineProperty( media, "paused", {
get: function() {
return paused;
}
});
Popcorn.player.defineProperty( media, "muted", {
set: function( val ) {
@ -206,7 +228,6 @@
}
});
media.duration = vimeoObject.api_getDuration();
media.dispatchEvent( "durationchange" );
media.dispatchEvent( "loadedmetadata" );

Просмотреть файл

@ -66,7 +66,7 @@ asyncTest( "Update Timer", function() {
ok( true, "'loadedmetadata' fired" );
plus();
// make sure that we always have a duration at this point
ok( this.duration() > 0, "Videos duration is greather than 0" );
ok( this.duration() > 0, "Video's duration is greater than 0" );
plus();
});
@ -216,11 +216,21 @@ asyncTest( "Update Timer", function() {
});
p2.exec( 3, function() {
p2.play();
});
p2.currentTime( 3 );
var ready = function() {
p2.off( "canplaythrough", ready );
p2.volume( 0 ).currentTime( 3 );
};
if ( p2.readyState() >= 4 ) {
ready();
} else {
p2.on( "canplaythrough", ready );
}
});
@ -338,8 +348,16 @@ asyncTest( "Plugin Factory", function() {
end: 5
});
popped.currentTime( 0 ).play();
var ready = function() {
popped.off( "canplaythrough", ready );
popped.volume( 0 ).currentTime( 0 ).play();
};
if ( popped.readyState() >= 4 ) {
ready();
} else {
popped.on( "canplaythrough", ready );
}
});
asyncTest( "Popcorn vimeo Plugin Url and Duration Tests", function() {

Просмотреть файл

@ -138,7 +138,7 @@
<body>
<div>
<div>
<div id="video" style="width: 360px; height: 300px;" ></div><br />
<div id="video" style="width: 640px; height: 390px;" ></div><br />
<button class="simple" id="btn-play-pause">Play</button>
<button class="seek" id="btn-seek">Seek to 30</button>
<button class="volume" id="btn-volume">Toggle Volume</button>

Просмотреть файл

@ -1,10 +1,15 @@
// A global callback for youtube... that makes me angry
var onYouTubePlayerReady = function( containerId ) {
var onYouTubePlayerAPIReady = function() {
onYouTubePlayerReady[ containerId ] && onYouTubePlayerReady[ containerId ]();
onYouTubePlayerAPIReady.ready = true;
for ( var i = 0; i < onYouTubePlayerAPIReady.waiting.length; i++ ) {
onYouTubePlayerAPIReady.waiting[ i ]();
}
};
onYouTubePlayerReady.stateChangeEventHandler = {};
onYouTubePlayerReady.onErrorEventHandler = {};
onYouTubePlayerAPIReady.waiting = [];
Popcorn.getScript( "http://www.youtube.com/player_api" );
Popcorn.player( "youtube", {
_canPlayType: function( nodeName, url ) {
@ -17,302 +22,179 @@ Popcorn.player( "youtube", {
autoPlay = false,
container = document.createElement( "div" ),
currentTime = 0,
paused = true,
seekTime = 0,
firstGo = true,
seeking = false,
fragmentStart = 0,
// state code for volume changed polling
volumeChanged = false,
lastMuted = false,
lastVolume = 100;
lastVolume = 100,
playerQueue = Popcorn.player.playerQueue();
var createProperties = function() {
Popcorn.player.defineProperty( media, "currentTime", {
set: function( val ) {
Popcorn.player.defineProperty( media, "currentTime", {
set: function( val ) {
// make sure val is a number
currentTime = seekTime = +val;
seeking = true;
if ( options.destroyed ) {
return currentTime;
}
media.dispatchEvent( "seeked" );
media.dispatchEvent( "timeupdate" );
options.youtubeObject.seekTo( currentTime );
return currentTime;
},
get: function() {
return currentTime;
if ( options.destroyed ) {
return;
}
});
Popcorn.player.defineProperty( media, "muted", {
set: function( val ) {
seeking = true;
// make sure val is a number
currentTime = Math.round( +val * 100 ) / 100;
},
get: function() {
if ( options.destroyed ) {
return currentTime;
}
});
return val;
}
Popcorn.player.defineProperty( media, "paused", {
get: function() {
if ( options.youtubeObject.isMuted() !== val ) {
return paused;
}
});
if ( val ) {
options.youtubeObject.mute();
} else {
options.youtubeObject.unMute();
}
lastMuted = options.youtubeObject.isMuted();
media.dispatchEvent( "volumechange" );
}
return options.youtubeObject.isMuted();
},
get: function() {
if ( options.destroyed ) {
return 0;
}
return options.youtubeObject.isMuted();
}
});
Popcorn.player.defineProperty( media, "volume", {
set: function( val ) {
if ( options.destroyed ) {
return val;
}
if ( options.youtubeObject.getVolume() / 100 !== val ) {
options.youtubeObject.setVolume( val * 100 );
lastVolume = options.youtubeObject.getVolume();
media.dispatchEvent( "volumechange" );
}
return options.youtubeObject.getVolume() / 100;
},
get: function() {
if ( options.destroyed ) {
return 0;
}
return options.youtubeObject.getVolume() / 100;
}
});
};
// setting paused to undefined because youtube has state for not paused or playing
media.paused = undefined;
container.id = media.id + Popcorn.guid();
options._container = container;
media.appendChild( container );
var youtubeInit = function() {
var flashvars, params, attributes,
src, width, height, query;
// expose a callback to this scope, that is called from the global callback youtube calls
onYouTubePlayerReady[ container.id ] = function() {
options.youtubeObject = document.getElementById( container.id );
// more youtube callback nonsense
onYouTubePlayerReady.stateChangeEventHandler[ container.id ] = function( state ) {
Popcorn.player.defineProperty( media, "muted", {
set: function( val ) {
if ( options.destroyed ) {
return;
return val;
}
// youtube fires paused events while seeking
// this is the only way to get seeking events
if ( state === 2 ) {
if ( options.youtubeObject.isMuted() !== val ) {
// silly logic forced on me by the youtube API
// calling youtube.seekTo triggers multiple events
// with the second events getCurrentTime being the old time
if ( seeking && seekTime === currentTime && seekTime !== options.youtubeObject.getCurrentTime() ) {
if ( val ) {
seeking = false;
options.youtubeObject.seekTo( currentTime );
return;
options.youtubeObject.mute();
} else {
options.youtubeObject.unMute();
}
currentTime = options.youtubeObject.getCurrentTime();
media.dispatchEvent( "timeupdate" );
!media.paused && media.pause();
return;
} else
// playing is state 1
// paused is state 2
if ( state === 1 && !firstGo ) {
media.paused && media.play();
return;
} else
// this is the real player ready check
// -1 is for unstarted, but ready to go videos
// before this the player object exists, but calls to it may go unheard
if ( state === -1 ) {
options.youtubeObject.playVideo();
return;
} else if ( state === 1 && firstGo ) {
firstGo = false;
if ( media.paused === true ) {
media.pause();
} else if ( media.paused === false ) {
media.play();
} else if ( autoPlay ) {
media.play();
} else if ( !autoPlay ) {
media.pause();
}
media.duration = options.youtubeObject.getDuration();
media.dispatchEvent( "durationchange" );
volumeupdate();
media.currentTime = options.youtubeObject.getCurrentTime();
createProperties();
media.dispatchEvent( "loadedmetadata" );
media.dispatchEvent( "loadeddata" );
media.readyState = 4;
media.dispatchEvent( "canplaythrough" );
return;
} else if ( state === 0 ) {
media.dispatchEvent( "ended" );
}
};
onYouTubePlayerReady.onErrorEventHandler[ container.id ] = function( errorCode ) {
if ( [ 2, 100, 101, 150 ].indexOf( errorCode ) !== -1 ) {
media.error = {
customCode: errorCode
};
media.dispatchEvent( "error" );
}
};
// youtube requires callbacks to be a string to a function path from the global scope
options.youtubeObject.addEventListener( "onStateChange", "onYouTubePlayerReady.stateChangeEventHandler." + container.id );
options.youtubeObject.addEventListener( "onError", "onYouTubePlayerReady.onErrorEventHandler." + container.id );
var timeupdate = function() {
if ( options.destroyed ) {
return;
}
if ( !media.paused ) {
currentTime = options.youtubeObject.getCurrentTime();
media.dispatchEvent( "timeupdate" );
setTimeout( timeupdate, 10 );
}
};
var volumeupdate = function() {
if ( options.destroyed ) {
return;
}
if ( lastMuted !== options.youtubeObject.isMuted() ) {
lastMuted = options.youtubeObject.isMuted();
media.dispatchEvent( "volumechange" );
}
if ( lastVolume !== options.youtubeObject.getVolume() ) {
return options.youtubeObject.isMuted();
},
get: function() {
if ( options.destroyed ) {
return 0;
}
return options.youtubeObject.isMuted();
}
});
Popcorn.player.defineProperty( media, "volume", {
set: function( val ) {
if ( options.destroyed ) {
return val;
}
if ( options.youtubeObject.getVolume() / 100 !== val ) {
options.youtubeObject.setVolume( val * 100 );
lastVolume = options.youtubeObject.getVolume();
media.dispatchEvent( "volumechange" );
}
setTimeout( volumeupdate, 250 );
};
media.play = function() {
return options.youtubeObject.getVolume() / 100;
},
get: function() {
if ( options.destroyed ) {
return;
return 0;
}
if ( media.paused !== false || options.youtubeObject.getPlayerState() !== 1 ) {
return options.youtubeObject.getVolume() / 100;
}
});
media.paused = false;
media.dispatchEvent( "play" );
media.play = function() {
media.dispatchEvent( "playing" );
if ( options.destroyed ) {
return;
}
paused = false;
playerQueue.add(function() {
if ( options.youtubeObject.getPlayerState() !== 1 ) {
seeking = false;
options.youtubeObject.playVideo();
} else {
playerQueue.next();
}
});
};
timeupdate();
options.youtubeObject.playVideo();
};
media.pause = function() {
media.pause = function() {
if ( options.destroyed ) {
if ( options.destroyed ) {
return;
}
return;
}
paused = true;
playerQueue.add(function() {
if ( media.paused !== true || options.youtubeObject.getPlayerState() !== 2 ) {
if ( options.youtubeObject.getPlayerState() !== 2 ) {
media.paused = true;
media.dispatchEvent( "pause" );
options.youtubeObject.pauseVideo();
} else {
playerQueue.next();
}
};
});
};
};
container.id = media.id + Popcorn.guid();
options._container = container;
media.appendChild( container );
var youtubeInit = function() {
var src, height, width, query;
var timeUpdate = function() {
if ( options.destroyed ) {
return;
}
if ( !seeking ) {
currentTime = options.youtubeObject.getCurrentTime();
media.dispatchEvent( "timeupdate" );
} else if ( currentTime === options.youtubeObject.getCurrentTime() ) {
seeking = false;
media.dispatchEvent( "seeked" );
media.dispatchEvent( "timeupdate" );
} else {
// keep trying the seek until it is right.
options.youtubeObject.seekTo( currentTime );
}
setTimeout( timeUpdate, 250 );
};
options.controls = +options.controls === 0 || +options.controls === 1 ? options.controls : 1;
options.annotations = +options.annotations === 1 || +options.annotations === 3 ? options.annotations : 1;
flashvars = {
playerapiid: container.id
};
params = {
wmode: "transparent",
allowScriptAccess: "always"
};
src = /^.*(?:\/|v=)(.{11})/.exec( media.src )[ 1 ];
query = ( media.src.split( "?" )[ 1 ] || "" )
@ -323,29 +205,126 @@ Popcorn.player( "youtube", {
minutes = minutes | 0; // bit-wise OR
seconds = seconds | 0; // bit-wise OR
return "&start=" + ( +seconds + ( minutes * 60 ) );
fragmentStart = ( +seconds + ( minutes * 60 ) );
return "";
});
query = query.replace( /&start=(\d+)?/, function( all, seconds ) {
// Make sure we have real zeros
seconds = seconds | 0; // bit-wise OR
fragmentStart = seconds;
return "";
});
autoPlay = ( /autoplay=1/.test( query ) );
// 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";
// setting youtube player's height and width, min 640 x 390,
// anything smaller, and the player reports incorrect states.
height = media.style.height && media.offsetHeight >= 390 ? "" + media.offsetHeight : "390";
width = media.style.width && media.offsetWidth >= 640 ? "" + media.offsetWidth : "640";
attributes = {
id: container.id,
"data-youtube-player": "//www.youtube.com/e/" + src + "?" + query + "&enablejsapi=1&playerapiid=" + container.id + "&version=3"
options.youtubeObject = new YT.Player( container.id, {
height: height,
width: width,
videoId: src,
events: {
"onReady": function(){
// pulling initial volume states form baseplayer
lastVolume = media.volume;
lastMuted = media.muted;
media.duration = options.youtubeObject.getDuration();
media.dispatchEvent( "durationchange" );
volumeupdate();
// pulling initial paused state from autoplay or the baseplayer
// also need to explicitly set to paused otherwise.
if ( autoPlay || !media.paused ) {
paused = false;
}
createProperties();
options.youtubeObject.playVideo();
if ( paused ) {
options.youtubeObject.pauseVideo();
}
media.currentTime = fragmentStart;
media.dispatchEvent( "loadedmetadata" );
media.dispatchEvent( "loadeddata" );
media.readyState = 4;
timeUpdate();
media.dispatchEvent( "canplaythrough" );
},
"onStateChange": function( state ){
if ( options.destroyed || state.data === -1 ) {
return;
}
// state.data === 2 is for pause events
// state.data === 1 is for play events
if ( state.data === 2 ) {
paused = true;
media.dispatchEvent( "pause" );
playerQueue.next();
} else if ( state.data === 1 ) {
paused = false;
media.dispatchEvent( "play" );
media.dispatchEvent( "playing" );
playerQueue.next();
} else if ( state.data === 0 ) {
media.dispatchEvent( "ended" );
}
},
"onError": function( error ) {
if ( [ 2, 100, 101, 150 ].indexOf( error.data ) !== -1 ) {
media.error = {
customCode: error.data
};
media.dispatchEvent( "error" );
}
}
}
});
var volumeupdate = function() {
if ( options.destroyed ) {
return;
}
if ( lastMuted !== options.youtubeObject.isMuted() ) {
lastMuted = options.youtubeObject.isMuted();
media.dispatchEvent( "volumechange" );
}
if ( lastVolume !== options.youtubeObject.getVolume() ) {
lastVolume = options.youtubeObject.getVolume();
media.dispatchEvent( "volumechange" );
}
setTimeout( volumeupdate, 250 );
};
swfobject.embedSWF( attributes[ "data-youtube-player" ], container.id, width, height, "8", undefined, flashvars, params, attributes );
};
if ( !window.swfobject ) {
Popcorn.getScript( "//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js", youtubeInit );
} else {
if ( onYouTubePlayerAPIReady.ready ) {
youtubeInit();
} else {
onYouTubePlayerAPIReady.waiting.push( youtubeInit );
}
},
_teardown: function( options ) {

Просмотреть файл

@ -215,13 +215,13 @@ asyncTest("Update Timer", function () {
});
p2.exec( 3, function() {
p2.play();
});
var ready = function() {
p2.off( "canplaythrough", ready );
p2.volume( 0 ).currentTime(3);
p2.volume( 0 ).currentTime( 3 );
};
if ( p2.readyState() >= 4 ) {
@ -364,8 +364,10 @@ asyncTest( "Popcorn YouTube Plugin Url and Duration Tests", function() {
expect( expects );
equal( popcorn.media.id, 'video2', 'Video id set' );
plus();
popcorn.on( "canplaythrough", function() {
equal( popcorn.media.id, 'video2', 'Video id set' );
plus();
});
popcorn.listen( "durationchange", function() {
@ -436,71 +438,6 @@ asyncTest( "Popcorn YouTube Plugin Url Regex Test", function() {
});
});
asyncTest( "Controls and Annotations toggling", function() {
var count = 0,
expects = 6,
testTarget = "",
targetDiv;
function plus(){
if ( ++count == expects ) {
start();
}
}
expect( expects );
var popcorn1 = Popcorn.youtube( "#video", "http://www.youtube.com/watch?v=nfGV32RNkhw" );
popcorn1.listen( "loadeddata", function() {
targetDiv = document.getElementById( "video" );
testTarget = targetDiv.querySelector( "object" ).getAttribute( "data-youtube-player" );
popcorn1.volume( 0 );
ok( !/controls/.test( testTarget ), "controls are defaulted to 1 ( displayed )" );
plus();
ok( !/iv_load_policy/.test( testTarget ), "annotations ( iv_load_policy ) are defaulted to ( enabled )" );
plus();
popcorn1.destroy();
var popcorn2 = Popcorn.youtube( "#video", "http://www.youtube.com/watch?v=nfGV32RNkhw&controls=1&iv_load_policy=1" );
popcorn2.listen( "loadeddata", function() {
targetDiv = document.getElementById( "video" );
testTarget = targetDiv.querySelector( "object" ).getAttribute( "data-youtube-player" );
popcorn2.volume( 0 );
ok( /controls=1/.test( testTarget ), "controls is set to 1 ( displayed )" );
plus();
ok( /iv_load_policy=1/.test( testTarget ), "annotations ( iv_load_policy ) is set to 1 ( enabled )" );
plus();
popcorn2.destroy();
var popcorn3 = Popcorn.youtube( "#video", "http://www.youtube.com/watch?v=nfGV32RNkhw&controls=0&iv_load_policy=3" );
popcorn3.listen( "loadeddata", function() {
targetDiv = document.getElementById( "video" );
testTarget = targetDiv.querySelector( "object" ).getAttribute( "data-youtube-player" );
popcorn3.volume( 0 );
ok( /controls=0/.test( testTarget ), "controls is set to 0 ( hidden )" );
plus();
ok( /iv_load_policy=3/.test( testTarget ), "annotations ( iv_load_policy ) is set to 3 ( hidden )" );
plus();
popcorn3.destroy();
});
});
});
});
asyncTest( "Player height and width", function() {
expect( 4 );
@ -514,11 +451,11 @@ asyncTest( "Player height and width", function() {
setTimeout( readyStatePoll, 10 );
} else {
equal( popcorn1.media.children[ 0 ].width, 560, "Youtube player default width is 560" );
equal( popcorn1.media.children[ 0 ].height, 315, "Youtube player default height is 315" );
equal( popcorn1.media.children[ 0 ].width, 640, "Youtube player default width is 560" );
equal( popcorn1.media.children[ 0 ].height, 390, "Youtube player default height is 315" );
equal( popcorn2.media.children[ 0 ].getAttribute( "width" ), 1, "Youtube player explicit width is 1" );
equal( popcorn2.media.children[ 0 ].getAttribute( "height" ), 1, "Youtube player explicit height is 1" );
equal( popcorn2.media.children[ 0 ].getAttribute( "width" ), 640, "Youtube player min width is 640" );
equal( popcorn2.media.children[ 0 ].getAttribute( "height" ), 390, "Youtube player min height is 390" );
popcorn1.destroy();
popcorn2.destroy();
@ -532,41 +469,6 @@ asyncTest( "Player height and width", function() {
readyStatePoll();
});
asyncTest( "Popcorn Youtube Plugin offsetHeight && offsetWidth Test", function() {
var popped,
elem,
expects = 2,
count = 0;
expect( expects );
function plus() {
if ( ++count === expects ) {
popped.destroy();
start();
}
}
popped = Popcorn.youtube( "#video6", "http://www.youtube.com/watch?v=nfGV32RNkhw" );
var runner = function() {
popped.volume( 0 );
elem = document.querySelector( "div#video6 object" );
equal( elem.height, popped.media.offsetHeight, "The media object is reporting the correct offsetHeight" );
plus();
equal( elem.width, popped.media.offsetWidth, "The media object is reporting the correct offsetWidth" );
plus();
};
if ( popped.readyState >= 2 ) {
runner();
} else {
popped.listen( "loadeddata", runner);
}
});
asyncTest( "Player Errors", function() {
expect( 2 );
@ -676,7 +578,9 @@ asyncTest( "Youtube ready state events", function() {
asyncTest( "Youtube media start time fragment", function() {
var popcorn1, popcorn2, popcorn3, popcorn4,
count = 0, expects = 4;
count = 0, expects = 4,
// Youtube's fragment can be off by give or take a second.
epsilon = 1;
expect( expects );
@ -694,25 +598,25 @@ asyncTest( "Youtube media start time fragment", function() {
var firstTest = function() {
popcorn1.off( "loadeddata", firstTest );
equal( Math.floor( popcorn1.currentTime() ), 130, "youtube fragment works with &start=130" );
ok( Math.ceil( popcorn1.currentTime() ) + epsilon >= 130, "youtube fragment works with &start=130" );
plus();
},
secondTest = function() {
popcorn2.off( "loadeddata", secondTest );
equal( Math.floor( popcorn2.currentTime() ), 130, "youtube fragment works with &t=2m10s" );
ok( Math.ceil( popcorn2.currentTime() ) + epsilon >= 130, "youtube fragment works with &t=2m10s" );
plus();
},
thirdTest = function() {
popcorn3.off( "loadeddata", thirdTest );
equal( Math.floor( popcorn3.currentTime() ), 120, "youtube fragment works with &t=2m" );
ok( Math.ceil( popcorn3.currentTime() ) + epsilon >= 120, "youtube fragment works with &t=2m" );
plus();
},
fourthTest = function() {
popcorn4.off( "loadeddata", fourthTest );
equal( Math.floor( popcorn4.currentTime() ), 10, "youtube fragment works with &t=10s" );
ok( Math.ceil( popcorn4.currentTime() )+ epsilon >= 10, "youtube fragment works with &t=10s" );
plus();
};