From 1cdbaffab94499200663f2760a2f77a3638bebb9 Mon Sep 17 00:00:00 2001 From: StefanBruens Date: Sat, 27 Oct 2012 19:07:01 +0300 Subject: [PATCH 001/218] Add opus codec for ogg, add flac official mime type for opus is audio/ogg, codec=opus flac native bitstream is unregistered and uses x-flac --- jquery.jplayer/jquery.jplayer.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 871b2c99..437fa6b7 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -447,7 +447,12 @@ media: 'audio' }, oga: { // OGG - codec: 'audio/ogg; codecs="vorbis"', + codec: 'audio/ogg; codecs="vorbis, opus"', + flashCanPlay: false, + media: 'audio' + }, + flac: { // FLAC + codec: 'audio/x-flac', flashCanPlay: false, media: 'audio' }, From a638a2d8f26186861e3a0a4e6ae4c144dcf009a3 Mon Sep 17 00:00:00 2001 From: Rick van der Zwet Date: Thu, 7 Feb 2013 09:42:27 +0100 Subject: [PATCH 002/218] Support for Apple HLS - HTTP Live Streaming format. http://tools.ietf.org/html/draft-pantos-http-live-streaming-10 Tested on iPad3 --- jquery.jplayer/jquery.jplayer.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 5b5ff0f0..3d83408a 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -702,6 +702,11 @@ flashCanPlay: true, media: 'video' }, + m3u8: { // H.264 / MP4 / Apple HLS + codec: 'application/vnd.apple.mpegurl; codecs="avc1.42E01E, mp4a.40.2"', + flashCanPlay: false, + media: 'video' + }, ogv: { // OGG codec: 'video/ogg; codecs="theora, vorbis"', flashCanPlay: false, From c30b049fd0a8d8a5a704d6cd47c2c02e4aa7cddd Mon Sep 17 00:00:00 2001 From: Sterling Hirsh Date: Mon, 25 Mar 2013 11:23:04 -0400 Subject: [PATCH 003/218] Automatically destroy removed instances With multiple instances of jplayer, if one got removed from the dom without being destroyed, the others would cause a javascript error on play. This was caused by keeping a list of instances ($.jPlayer.prototype.instances) that would get out of sync with the page. With this patch, jPlayer clears the list of any nonexistent instances before iterating over the list. The error was triggered from pauseOthers() and $.jPlayer.pause(). --- jquery.jplayer/jquery.jplayer.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 3088d02c..1e10d168 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -160,6 +160,7 @@ ]; $.jPlayer.pause = function() { + $.jPlayer.prototype.destroyRemoved(); $.each($.jPlayer.prototype.instances, function(i, element) { if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. element.jPlayer("pause"); @@ -1113,6 +1114,17 @@ delete this.instances[this.internal.instance]; // Clear the instance on the static instance object }, + destroyRemoved: function() { // Destroy any instances that have gone away. + var self = this; + $.each(this.instances, function(i, element) { + if(self.element !== element) { // Do not destroy this instance. + if(!element.data("jPlayer")) { // Check that element is a real jPlayer. + element.jPlayer("destroy"); + delete self.instances[i]; + } + } + }); + }, enable: function() { // Plan to implement // options.disabled = false }, @@ -1724,6 +1736,7 @@ }, pauseOthers: function() { var self = this; + $.jPlayer.prototype.destroyRemoved(); $.each(this.instances, function(i, element) { if(self.element !== element) { // Do not this instance. if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. From 526da543798fdd982da4085483019e7945391fcb Mon Sep 17 00:00:00 2001 From: iking0980 Date: Fri, 10 May 2013 11:09:02 +0300 Subject: [PATCH 004/218] Update JplayerRtmp.as Fix problem with connection Amazon cloudfront signeture url --- actionscript/happyworm/jPlayer/JplayerRtmp.as | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/actionscript/happyworm/jPlayer/JplayerRtmp.as b/actionscript/happyworm/jPlayer/JplayerRtmp.as index b25b9045..ef3d6d5b 100644 --- a/actionscript/happyworm/jPlayer/JplayerRtmp.as +++ b/actionscript/happyworm/jPlayer/JplayerRtmp.as @@ -513,7 +513,13 @@ package happyworm.jPlayer { appName = rtmpSrc.substring(endHost,rtmpSrc.indexOf("mp3:")); streamFileName = rtmpSrc.substr(rtmpSrc.indexOf("mp3:")); - streamFileName = streamFileName.substr(0,streamFileName.length - 4); + if ( streamFileName.indexOf("?") ) + { + var tmp:String = streamFileName.substring(streamFileName.indexOf("?")) ; + streamFileName = streamFileName.substr(0,streamFileName.indexOf("?")) + encodeURI(tmp) ; + } + else + streamFileName = streamFileName.substr(0,streamFileName.length - 4); } // rtmp://cp83813.edgefcs.net/ondemand/rob_hall/bruce_campbell_oldspice.flv @@ -522,7 +528,13 @@ package happyworm.jPlayer { appName = rtmpSrc.substring(endHost,rtmpSrc.indexOf("mp4:")); streamFileName = rtmpSrc.substr(rtmpSrc.indexOf("mp4:")); - streamFileName = streamFileName.substr(0,streamFileName.length - 4); + if ( streamFileName.indexOf("?") ) + { + var tmpV:String = streamFileName.substring(streamFileName.indexOf("?")) ; + streamFileName = streamFileName.substr(0,streamFileName.indexOf("?")) + encodeURI(tmpV) ; + } + else + streamFileName = streamFileName.substr(0,streamFileName.length - 4); } // .f4v streams with standard appname/no instance name, .flv extension @@ -981,4 +993,4 @@ package happyworm.jPlayer } } } -} \ No newline at end of file +} From 382eeb3aad216559acbfbb02f4840216ac0f14f7 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Wed, 5 Jun 2013 18:43:10 +0100 Subject: [PATCH 005/218] Updated version to 2.4.0 and revised license to MIT. --- actionscript/Jplayer.as | 11 +++++------ .../happyworm/jPlayer/ConnectManager.as | 5 ++--- .../happyworm/jPlayer/JplayerEvent.as | 5 ++--- actionscript/happyworm/jPlayer/JplayerMp3.as | 5 ++--- actionscript/happyworm/jPlayer/JplayerMp4.as | 5 ++--- actionscript/happyworm/jPlayer/JplayerRtmp.as | 5 ++--- .../happyworm/jPlayer/JplayerStatus.as | 9 ++++----- actionscript/happyworm/jPlayer/TraceOut.as | 5 ++--- add-on/jplayer.playlist.js | 5 ++--- add-on/jquery.jplayer.inspector.js | 5 ++--- jplayer.jquery.json | 2 +- jquery.jplayer/Jplayer.swf | Bin 14084 -> 14085 bytes jquery.jplayer/jquery.jplayer.js | 13 ++++++------- package.json | 8 ++------ popcorn/player/popcorn.jplayer.js | 17 ++++++++--------- 15 files changed, 42 insertions(+), 58 deletions(-) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index ff2af5a1..ab6940e3 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -3,19 +3,18 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT. + * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.3.5 - * Date: 29th May 2013 + * Version: 2.4.0 + * Date: 5th June 2013 * * FlashVars expected: (AS3 property of: loaderInfo.parameters) * id: (URL Encoded: String) Id of jPlayer instance * vol: (Number) Sets the initial volume * muted: (Boolean in a String) Sets the initial muted state - * jQuery: (URL Encoded: String) Sets the jQuery var name. Used with: someVar = jQuery.noConflict(true); + * jQuery: (URL Encoded: String) Sets the jQuery var name. Used with: someVar = jQuery.noConflict(true); The someVar name must contain jQuery in it. * * Compiled using: Adobe Flex Compiler (mxmlc) Version 4.5.1 build 21328 */ diff --git a/actionscript/happyworm/jPlayer/ConnectManager.as b/actionscript/happyworm/jPlayer/ConnectManager.as index 7cf65967..f8020544 100644 --- a/actionscript/happyworm/jPlayer/ConnectManager.as +++ b/actionscript/happyworm/jPlayer/ConnectManager.as @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://opensource.org/licenses/MIT * * Author: Robert M. Hall * Date: 7th August 2012 diff --git a/actionscript/happyworm/jPlayer/JplayerEvent.as b/actionscript/happyworm/jPlayer/JplayerEvent.as index 903f41c1..56ae7633 100644 --- a/actionscript/happyworm/jPlayer/JplayerEvent.as +++ b/actionscript/happyworm/jPlayer/JplayerEvent.as @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston * Date: 20th May 2013 diff --git a/actionscript/happyworm/jPlayer/JplayerMp3.as b/actionscript/happyworm/jPlayer/JplayerMp3.as index f32a8096..648951e5 100644 --- a/actionscript/happyworm/jPlayer/JplayerMp3.as +++ b/actionscript/happyworm/jPlayer/JplayerMp3.as @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston * Date: 28th May 2013 diff --git a/actionscript/happyworm/jPlayer/JplayerMp4.as b/actionscript/happyworm/jPlayer/JplayerMp4.as index f1b31c35..c3fffd3c 100644 --- a/actionscript/happyworm/jPlayer/JplayerMp4.as +++ b/actionscript/happyworm/jPlayer/JplayerMp4.as @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston * Date: 29th January 2013 diff --git a/actionscript/happyworm/jPlayer/JplayerRtmp.as b/actionscript/happyworm/jPlayer/JplayerRtmp.as index b25b9045..2725d24a 100644 --- a/actionscript/happyworm/jPlayer/JplayerRtmp.as +++ b/actionscript/happyworm/jPlayer/JplayerRtmp.as @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://opensource.org/licenses/MIT * * Author: Robert M. Hall * Date: 29th January 2013 diff --git a/actionscript/happyworm/jPlayer/JplayerStatus.as b/actionscript/happyworm/jPlayer/JplayerStatus.as index 1f439c51..4c620d9a 100644 --- a/actionscript/happyworm/jPlayer/JplayerStatus.as +++ b/actionscript/happyworm/jPlayer/JplayerStatus.as @@ -3,18 +3,17 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 29th May 2013 + * Date: 5th June 2013 */ package happyworm.jPlayer { public class JplayerStatus { - public static const VERSION:String = "2.3.5"; // The version of the Flash jPlayer entity. + public static const VERSION:String = "2.4.0"; // The version of the Flash jPlayer entity. public var volume:Number = 0.5; // Not affected by reset() public var muted:Boolean = false; // Not affected by reset() diff --git a/actionscript/happyworm/jPlayer/TraceOut.as b/actionscript/happyworm/jPlayer/TraceOut.as index 7404c170..b0d56a6f 100644 --- a/actionscript/happyworm/jPlayer/TraceOut.as +++ b/actionscript/happyworm/jPlayer/TraceOut.as @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://opensource.org/licenses/MIT * * Author: Robert M. Hall * Date: 7th August 2012 diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index b8b208b6..60d48736 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston * Version: 2.3.0 diff --git a/add-on/jquery.jplayer.inspector.js b/add-on/jquery.jplayer.inspector.js index d8f59140..2962b44f 100644 --- a/add-on/jquery.jplayer.inspector.js +++ b/add-on/jquery.jplayer.inspector.js @@ -3,9 +3,8 @@ * http://www.jplayer.org * * Copyright (c) 2009 - 2013 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. - * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html + * Licensed under the MIT license. + * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston * Version: 1.0.4 diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 0cf5f543..3b7b4376 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.3.10", + "version": "2.4.0", "author": { "name": "Mark J Panaghiston", "url": "http://happyworm.com/" diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index 4cf70be769e263e5c016b16d3bcaa695f4aae7ce..85c0ba38eede8cabc9b85603c2239082a548f549 100644 GIT binary patch delta 14010 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 B!`1)* delta 13991 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 Date: Fri, 21 Jun 2013 17:02:20 +0100 Subject: [PATCH 006/218] Bug Fix: The SWF failed 8+ instances on OSX with Firefox and Safari. --- actionscript/Jplayer.as | 16 ++++++++-------- .../happyworm/jPlayer/JplayerStatus.as | 4 ++-- actionscript/happyworm/jPlayer/TraceOut.as | 2 ++ jplayer.jquery.json | 2 +- jquery.jplayer/Jplayer.swf | Bin 14085 -> 14076 bytes jquery.jplayer/jquery.jplayer.js | 8 ++++---- package.json | 2 +- 7 files changed, 18 insertions(+), 16 deletions(-) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index ab6940e3..8fb8225d 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.4.0 - * Date: 5th June 2013 + * Version: 2.4.1 + * Date: 21st June 2013 * * FlashVars expected: (AS3 property of: loaderInfo.parameters) * id: (URL Encoded: String) Id of jPlayer instance @@ -76,12 +76,11 @@ package { private var debug:Boolean = false; // Set debug to false for release compile! private var localAIRDebug:Boolean = false; // This is autodetermined by AIR app - leave false! - private var traceOut:TraceOut; + private var traceOut:TraceOut; // This class was found to cause problems on OSX with Firefox and Safari where more than 8 instances of the SWF are on a page. public function Jplayer() { flash.system.Security.allowDomain("*"); - traceOut = new TraceOut(); // Fix to the security exploit reported by Jason Calvert http://appsec.ws/ checkFlashVars(loaderInfo.parameters); @@ -155,6 +154,8 @@ package { myMp3Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler); myMp4Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler); myRtmpPlayer.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler); + + traceOut = new TraceOut(); // Instance it only when in debug mode. See comment above at var declaration. } } @@ -379,7 +380,6 @@ package { } } private function fl_setAudio_rtmp(src:String):Boolean { - tracer("SET RTMP: "+src); if (src != null) { log("fl_setAudio_rtmp: "+src); switchType("rtmpa"); @@ -394,7 +394,6 @@ package { } private function fl_setVideo_rtmp(src:String):Boolean { - tracer("SET RTMP: "+src); if (src != null) { log("fl_setVideo_rtmp: "+src); switchType("rtmpv"); @@ -498,14 +497,15 @@ package { } private function jPlayerFlashEvent(e:JplayerEvent):void { log("jPlayer Flash Event: " + e.type + ": " + e.target); - //tracer("jPlayer Flash Event: " + e.type + ": " + e.target); if(ExternalInterface.available && !securityIssue) { ExternalInterface.call(jQuery, "jPlayerFlashEvent", e.type, extractStatusData(e.data)); } } private function tracer(msg:String):void { - traceOut.tracer(msg); + if(debug) { + traceOut.tracer(msg); + } } private function extractStatusData(data:JplayerStatus):Object { diff --git a/actionscript/happyworm/jPlayer/JplayerStatus.as b/actionscript/happyworm/jPlayer/JplayerStatus.as index 4c620d9a..4460201d 100644 --- a/actionscript/happyworm/jPlayer/JplayerStatus.as +++ b/actionscript/happyworm/jPlayer/JplayerStatus.as @@ -7,13 +7,13 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 5th June 2013 + * Date: 21st June 2013 */ package happyworm.jPlayer { public class JplayerStatus { - public static const VERSION:String = "2.4.0"; // The version of the Flash jPlayer entity. + public static const VERSION:String = "2.4.1"; // The version of the Flash jPlayer entity. public var volume:Number = 0.5; // Not affected by reset() public var muted:Boolean = false; // Not affected by reset() diff --git a/actionscript/happyworm/jPlayer/TraceOut.as b/actionscript/happyworm/jPlayer/TraceOut.as index b0d56a6f..956e3a20 100644 --- a/actionscript/happyworm/jPlayer/TraceOut.as +++ b/actionscript/happyworm/jPlayer/TraceOut.as @@ -10,6 +10,8 @@ * Date: 7th August 2012 */ +// This class was found to cause problems on OSX with Firefox and Safari where more than 8 instances of the SWF are on a page. + package happyworm.jPlayer { import flash.net.LocalConnection; diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 3b7b4376..935d407a 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.4.0", + "version": "2.4.1", "author": { "name": "Mark J Panaghiston", "url": "http://happyworm.com/" diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index 85c0ba38eede8cabc9b85603c2239082a548f549..066307980e02a2bdd990a2246a28030bd4b62eb4 100644 GIT binary patch delta 14033 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 DX7Sy# delta 14001 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 P9yEoYATSKE1=9ZkB1E=C diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index d52aca0f..bbcdb9e1 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.4.0 - * Date: 5th June 2013 + * Version: 2.4.1 + * Date: 21st June 2013 */ /* Code verified using http://www.jshint.com/ */ @@ -468,8 +468,8 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.4.0", - needFlash: "2.4.0", + script: "2.4.1", + needFlash: "2.4.1", flash: "unknown" }, options: { // Instanced in $.jPlayer() constructor diff --git a/package.json b/package.json index 70656c2b..e44615fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.4.0", + "version": "2.4.1", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 8a41f337e00cb95792bfe7fc6be10b69820feecb Mon Sep 17 00:00:00 2001 From: Happyworm Date: Wed, 30 Oct 2013 20:28:43 +0000 Subject: [PATCH 007/218] Implemented PR #173 by @adamwaite - The consoleAlerts option --- jquery.jplayer/jquery.jplayer.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index bbcdb9e1..852d3129 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -603,6 +603,7 @@ idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \ noConflict: "jQuery", emulateHtml: false, // Emulates the HTML5 Media element on the jPlayer element. + consoleAlerts: true, // Alerts are sent to the console.log() instead of alert(). errorAlerts: false, warningAlerts: false }, @@ -2718,17 +2719,22 @@ _error: function(error) { this._trigger($.jPlayer.event.error, error); if(this.options.errorAlerts) { - this._alert("Error!" + (error.message ? "\n\n" + error.message : "") + (error.hint ? "\n\n" + error.hint : "") + "\n\nContext: " + error.context); + this._alert("Error!" + (error.message ? "\n" + error.message : "") + (error.hint ? "\n" + error.hint : "") + "\nContext: " + error.context); } }, _warning: function(warning) { this._trigger($.jPlayer.event.warning, undefined, warning); if(this.options.warningAlerts) { - this._alert("Warning!" + (warning.message ? "\n\n" + warning.message : "") + (warning.hint ? "\n\n" + warning.hint : "") + "\n\nContext: " + warning.context); + this._alert("Warning!" + (warning.message ? "\n" + warning.message : "") + (warning.hint ? "\n" + warning.hint : "") + "\nContext: " + warning.context); } }, _alert: function(message) { - alert("jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message); + var msg = "jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message; + if(!this.options.consoleAlerts) { + alert(msg); + } else if(console && console.log) { + console.log(msg); + } }, _emulateHtmlBridge: function() { var self = this; From 8abab8f55bc107adec6d1991538c20cad30ebff2 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Thu, 31 Oct 2013 22:57:45 +0000 Subject: [PATCH 008/218] Fix: All media URLs converted to absolute. Fixes Flash m4a/m4v relative url issue. --- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 29 ++++++++++++++++++++++++----- package.json | 2 +- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 935d407a..ac65fbdc 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.4.1", + "version": "2.4.2", "author": { "name": "Mark J Panaghiston", "url": "http://happyworm.com/" diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index bbcdb9e1..f4a4984b 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.4.1 - * Date: 21st June 2013 + * Version: 2.4.2 + * Date: 31st October 2013 */ /* Code verified using http://www.jshint.com/ */ @@ -468,7 +468,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.4.1", + script: "2.4.2", needFlash: "2.4.1", flash: "unknown" }, @@ -1582,12 +1582,28 @@ this.html.active = false; this.flash.active = false; }, + _escapeHtml: function(s) { + return s.split('&').join('&').split('<').join('<').split('>').join('>').split('"').join('"'); + }, + _qualifyURL: function(url) { + var el = document.createElement('div'); + el.innerHTML= 'x'; + return el.firstChild.href; + }, + _absoluteMediaUrls: function(media) { + var self = this; + $.each(media, function(type, url) { + if(self.format[type]) { + media[type] = self._qualifyURL(url); + } + }); + return media; + }, setMedia: function(media) { /* media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats. * media.poster = String: Video poster URL. - * media.subtitles = String: * NOT IMPLEMENTED * URL of subtitles SRT file - * media.chapters = String: * NOT IMPLEMENTED * URL of chapters SRT file + * media.track = Array: Of objects defining the track element: kind, src, srclang, label, def. * media.stream = Boolean: * NOT IMPLEMENTED * Designating actual media streams. ie., "false/undefined" for files. Plan to refresh the flash every so often. */ @@ -1599,6 +1615,9 @@ this._resetGate(); this._resetActive(); + // Convert all media URLs to absolute URLs. + media = this._absoluteMediaUrls(media); + $.each(this.formats, function(formatPriority, format) { var isVideo = self.format[format].media === 'video'; $.each(self.solutions, function(solutionPriority, solution) { diff --git a/package.json b/package.json index e44615fb..d9b28164 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.4.1", + "version": "2.4.2", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From a28a8fbe3c4bbd635b023ad3c5bd3e18e2fc1aee Mon Sep 17 00:00:00 2001 From: Happyworm Date: Fri, 1 Nov 2013 18:48:41 +0000 Subject: [PATCH 009/218] Made Audio and Video versions of PR #142 by @rickvanderzwet --- jquery.jplayer/jquery.jplayer.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index f87f37f7..4f1a2aa9 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -688,6 +688,11 @@ flashCanPlay: true, media: 'audio' }, + m3u8a: { // AAC / MP4 / Apple HLS + codec: 'application/vnd.apple.mpegurl; codecs="mp4a.40.2"', + flashCanPlay: false, + media: 'audio' + }, oga: { // OGG codec: 'audio/ogg; codecs="vorbis"', flashCanPlay: false, @@ -718,7 +723,7 @@ flashCanPlay: true, media: 'video' }, - m3u8: { // H.264 / MP4 / Apple HLS + m3u8v: { // H.264 / AAC / MP4 / Apple HLS codec: 'application/vnd.apple.mpegurl; codecs="avc1.42E01E, mp4a.40.2"', flashCanPlay: false, media: 'video' From ce902e663dc5bdec9d0d26c0952ca7db3f908e02 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Fri, 1 Nov 2013 19:02:07 +0000 Subject: [PATCH 010/218] Added M3U audio/video support, like #142 --- jquery.jplayer/jquery.jplayer.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 4f1a2aa9..afa93f7c 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -693,6 +693,11 @@ flashCanPlay: false, media: 'audio' }, + m3ua: { // M3U + codec: 'audio/mpegurl', + flashCanPlay: false, + media: 'audio' + }, oga: { // OGG codec: 'audio/ogg; codecs="vorbis"', flashCanPlay: false, @@ -728,6 +733,11 @@ flashCanPlay: false, media: 'video' }, + m3uv: { // M3U + codec: 'audio/mpegurl', + flashCanPlay: false, + media: 'video' + }, ogv: { // OGG codec: 'video/ogg; codecs="theora, vorbis"', flashCanPlay: false, From d083b286eb48e3e5666cdf6ab3a8f5347133de9a Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 3 Nov 2013 00:24:04 +0000 Subject: [PATCH 011/218] Added tellOthers() and param to pauseOthers(time) #139 --- jquery.jplayer/jquery.jplayer.js | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 992a1fed..bfb68110 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -1787,16 +1787,33 @@ this._urlNotSetError("pause"); } }, - pauseOthers: function() { - var self = this; - $.each(this.instances, function(i, element) { - if(self.element !== element) { // Do not this instance. - if(element.data("jPlayer").status.srcSet) { // Check that media is set otherwise would cause error event. - element.jPlayer("pause"); + tellOthers: function(command, conditions) { + var self = this, + hasConditions = typeof conditions === 'function', + args = Array.prototype.slice.call(arguments); // Convert arguments to an Array. + + if(typeof command !== 'string') { // Ignore, since no command. + return; // Return undefined to maintain chaining. + } + if(hasConditions) { + args.splice(1, 1); // Remove the conditions from the arguments + } + + $.each(this.instances, function() { + // Remember that "this" is the instance's "element" in the $.each() loop. + if(self.element !== this) { // Do not tell my instance. + if(!hasConditions || conditions.call(this.data("jPlayer"), self)) { + this.jPlayer.apply(this, args); } } }); }, + pauseOthers: function(time) { + this.tellOthers("pause", function() { + // In the conditions function, the "this" context is the other instance's jPlayer object. + return this.status.srcSet; + }, time); + }, stop: function() { if(this.status.srcSet) { if(this.html.active) { From 49bd12e49d99a51266942ef00161980fb8255783 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 3 Nov 2013 01:41:17 +0000 Subject: [PATCH 012/218] Added globalVolume option --- jquery.jplayer/jquery.jplayer.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index bfb68110..bb081632 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -598,7 +598,7 @@ } }, verticalVolume: false, // Calculate volume from the bottom of the volume bar. Default is from the left. Also volume affects either width or height. - // globalVolume: false, // Not implemented: Set to make volume changes affect all jPlayer instances + globalVolume: false, // Set to make volume changes affect all jPlayer instances // globalMute: false, // Not implemented: Set to make mute changes affect all jPlayer instances idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \ noConflict: "jQuery", @@ -1879,6 +1879,15 @@ } }, volume: function(v) { + this.volumeWorker(v); + if(this.options.globalVolume) { + this.tellOthers("volumeWorker", function() { + // Check the other instance has global volume enabled. + return this.options.globalVolume; + }, v); + } + }, + volumeWorker: function(v) { v = this._limitValue(v, 0, 1); this.options.volume = v; From e614d1f8334f23f66d10159ce049818a8697fb0f Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 3 Nov 2013 02:20:46 +0000 Subject: [PATCH 013/218] globalVolume option now affect muted --- jquery.jplayer/jquery.jplayer.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index bb081632..9887f169 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -598,8 +598,7 @@ } }, verticalVolume: false, // Calculate volume from the bottom of the volume bar. Default is from the left. Also volume affects either width or height. - globalVolume: false, // Set to make volume changes affect all jPlayer instances - // globalMute: false, // Not implemented: Set to make mute changes affect all jPlayer instances + globalVolume: false, // Set to make volume and muted changes affect all jPlayer instances with this option enabled idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \ noConflict: "jQuery", emulateHtml: false, // Emulates the HTML5 Media element on the jPlayer element. @@ -1838,6 +1837,15 @@ } }, _muted: function(muted) { + this.mutedWorker(muted); + if(this.options.globalVolume) { + this.tellOthers("mutedWorker", function() { + // Check the other instance has global volume enabled. + return this.options.globalVolume; + }, muted); + } + }, + mutedWorker: function(muted) { this.options.muted = muted; if(this.html.used) { this._html_mute(muted); From 1345a74581801b4670f14311cb4a1a4062c8498a Mon Sep 17 00:00:00 2001 From: Gao Yingkai Date: Tue, 29 Jan 2013 23:33:02 +0800 Subject: [PATCH 014/218] bower component.json --- component.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 component.json diff --git a/component.json b/component.json new file mode 100644 index 00000000..cde3d26c --- /dev/null +++ b/component.json @@ -0,0 +1,8 @@ +{ + "name": "jPlayer", + "version": "2.2.0", + "main": ["./jquery.jplayer/jquery.jplayer.js","./skin/pink.flag/jplayer.pink.flag.css"], + "dependencies": { + "jquery": "~1.7.2" + } +} \ No newline at end of file From a1f04cf9a7717d62054b2fcef781488e6ee26289 Mon Sep 17 00:00:00 2001 From: Gao Yingkai Date: Tue, 29 Jan 2013 23:43:16 +0800 Subject: [PATCH 015/218] semantic version for jquery --- component.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/component.json b/component.json index cde3d26c..408b79c1 100644 --- a/component.json +++ b/component.json @@ -3,6 +3,6 @@ "version": "2.2.0", "main": ["./jquery.jplayer/jquery.jplayer.js","./skin/pink.flag/jplayer.pink.flag.css"], "dependencies": { - "jquery": "~1.7.2" + "jquery": ">=1.7.2" } -} \ No newline at end of file +} From f25814556a5674882bbb48763878b6b256986187 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 3 Nov 2013 18:48:07 +0000 Subject: [PATCH 016/218] Renamed and edited version of bower.json #132 --- bower.json | 11 +++++++++++ component.json | 8 -------- 2 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 bower.json delete mode 100644 component.json diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..6867d425 --- /dev/null +++ b/bower.json @@ -0,0 +1,11 @@ +{ + "name": "jPlayer", + "version": "2.4.2", + "main": [ + "./jquery.jplayer/jquery.jplayer.js", + "./skin/pink.flag/jplayer.pink.flag.css" + ], + "dependencies": { + "jquery": ">=1.7.2" + } +} diff --git a/component.json b/component.json deleted file mode 100644 index 408b79c1..00000000 --- a/component.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "jPlayer", - "version": "2.2.0", - "main": ["./jquery.jplayer/jquery.jplayer.js","./skin/pink.flag/jplayer.pink.flag.css"], - "dependencies": { - "jquery": ">=1.7.2" - } -} From 377c4a8916bad17795cef3de72b80d6754927025 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 3 Nov 2013 19:17:44 +0000 Subject: [PATCH 017/218] Merged insecure domain rule #130 by @prekageo --- actionscript/Jplayer.as | 1 + jquery.jplayer/Jplayer.swf | Bin 14076 -> 14091 bytes 2 files changed, 1 insertion(+) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index 8fb8225d..ea114d07 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -81,6 +81,7 @@ package { public function Jplayer() { flash.system.Security.allowDomain("*"); + flash.system.Security.allowInsecureDomain("*"); // Fix to the security exploit reported by Jason Calvert http://appsec.ws/ checkFlashVars(loaderInfo.parameters); diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index 066307980e02a2bdd990a2246a28030bd4b62eb4..f36aa50da352789c875c50856f982c1ddb46a558 100644 GIT binary patch delta 12516 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 EA1z(5-~a#s From 5ca8187be50cbadf19297c4040f44a9d758e8858 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 3 Nov 2013 20:15:07 +0000 Subject: [PATCH 018/218] Fixed logic errors in #161 and cleaned code styling. --- actionscript/happyworm/jPlayer/JplayerRtmp.as | 36 ++++++++---------- jquery.jplayer/Jplayer.swf | Bin 14091 -> 14147 bytes 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/actionscript/happyworm/jPlayer/JplayerRtmp.as b/actionscript/happyworm/jPlayer/JplayerRtmp.as index 14f402bb..5e9d65e8 100644 --- a/actionscript/happyworm/jPlayer/JplayerRtmp.as +++ b/actionscript/happyworm/jPlayer/JplayerRtmp.as @@ -7,7 +7,7 @@ * http://opensource.org/licenses/MIT * * Author: Robert M. Hall - * Date: 29th January 2013 + * Date: 3rd November 2013 * Based on JplayerMp4.as with modifications for rtmp */ @@ -508,32 +508,28 @@ package happyworm.jPlayer } // Mp3 streams with standard appname/no instance name, mp3: prefix - if (rtmpSrc.indexOf(".mp3") != -1) - { + if (rtmpSrc.indexOf("mp3:") != -1) { appName = rtmpSrc.substring(endHost,rtmpSrc.indexOf("mp3:")); streamFileName = rtmpSrc.substr(rtmpSrc.indexOf("mp3:")); - if ( streamFileName.indexOf("?") ) - { - var tmp:String = streamFileName.substring(streamFileName.indexOf("?")) ; - streamFileName = streamFileName.substr(0,streamFileName.indexOf("?")) + encodeURI(tmp) ; - } - else - streamFileName = streamFileName.substr(0,streamFileName.length - 4); + if ( streamFileName.indexOf("?") != -1 ) { + var tmp:String = streamFileName.substring(streamFileName.indexOf("?")) ; + streamFileName = streamFileName.substr(0,streamFileName.indexOf("?")) + encodeURI(tmp) ; + } else { + streamFileName = streamFileName.substr(0,streamFileName.length - 4); + } } // rtmp://cp83813.edgefcs.net/ondemand/rob_hall/bruce_campbell_oldspice.flv // Mp4 streams with standard appname/no instance name, mp4: prefix - if (rtmpSrc.indexOf("mp4:") != -1) - { + if (rtmpSrc.indexOf("mp4:") != -1) { appName = rtmpSrc.substring(endHost,rtmpSrc.indexOf("mp4:")); streamFileName = rtmpSrc.substr(rtmpSrc.indexOf("mp4:")); - if ( streamFileName.indexOf("?") ) - { - var tmpV:String = streamFileName.substring(streamFileName.indexOf("?")) ; - streamFileName = streamFileName.substr(0,streamFileName.indexOf("?")) + encodeURI(tmpV) ; - } - else - streamFileName = streamFileName.substr(0,streamFileName.length - 4); + if ( streamFileName.indexOf("?") != -1 ) { + var tmpV:String = streamFileName.substring(streamFileName.indexOf("?")) ; + streamFileName = streamFileName.substr(0,streamFileName.indexOf("?")) + encodeURI(tmpV) ; + } else { + streamFileName = streamFileName.substr(0,streamFileName.length - 4); + } } // .f4v streams with standard appname/no instance name, .flv extension @@ -992,4 +988,4 @@ package happyworm.jPlayer } } } -} +} diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index f36aa50da352789c875c50856f982c1ddb46a558..ecc01e2c12f1e65a6519c10cfde2e33eea3208f3 100644 GIT binary patch literal 14147 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 literal 14091 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 Date: Tue, 5 Nov 2013 00:10:02 +0000 Subject: [PATCH 019/218] Added playbackRate options and support for its GUI control --- jquery.jplayer/jquery.jplayer.js | 127 ++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 2 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 9887f169..b699b734 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -479,6 +479,10 @@ preload: 'metadata', // HTML5 Spec values: none, metadata, auto. volume: 0.8, // The volume. Number 0 to 1. muted: false, + playbackRate: 1, + defaultPlaybackRate: 1, + minPlaybackRate: 0.5, + maxPlaybackRate: 4, wmode: "opaque", // Valid wmode: window, transparent, opaque, direct, gpu. backgroundColor: "#000000", // To define the jPlayer div and Flash background color. cssSelectorAncestor: "#jp_container_1", @@ -494,6 +498,8 @@ volumeBar: ".jp-volume-bar", volumeBarValue: ".jp-volume-bar-value", volumeMax: ".jp-volume-max", + playbackRateBar: ".jp-playback-rate-bar", + playbackRateBarValue: ".jp-playback-rate-bar-value", currentTime: ".jp-current-time", duration: ".jp-duration", fullScreen: ".jp-full-screen", // * @@ -650,7 +656,7 @@ videoHeight: 0, // Intrinsic height of the video in pixels. readyState: 0, networkState: 0, - playbackRate: 1, + playbackRate: 1, // Warning - Now both an option and a status property ended: 0 /* Persistant status properties created dynamically at _init(): @@ -660,6 +666,7 @@ nativeVideoControls noFullWindow noVolume + playbackRateEnabled // Warning - Technically, we can have both Flash and HTML, so this might not be correct if the Flash is active. That is a niche case. */ }, @@ -1057,7 +1064,17 @@ this.element.append(htmlObj); this.internal.flash.jq = $(htmlObj); } - + + // Setup playbackRate ability before using _addHtmlEventListeners() + if(this.html.used && !this.flash.used) { // If only HTML + // Using the audio element capabilities for playbackRate. ie., Assuming video element is the same. + this.status.playbackRateEnabled = this._testPlaybackRate('audio'); + } else { + this.status.playbackRateEnabled = false; + } + + this._updatePlaybackRate(); + // Add the HTML solution if being used. if(this.html.used) { @@ -1165,6 +1182,23 @@ return false; } }, + _testPlaybackRate: function(type) { + // type: String 'audio' or 'video' + var el, rate = 0.5; + type = typeof type === 'string' ? type : 'audio'; + el = document.createElement(type); + // Wrapping in a try/catch, just in case older HTML5 browsers throw and error. + try { + if('playbackRate' in el) { + el.playbackRate = rate; + return el.playbackRate === rate; + } else { + return false; + } + } catch(err) { + return false; + } + }, _uaBlocklist: function(list) { // list : object with properties that are all regular expressions. Property names are irrelevant. // Returns true if the user agent is matched in list. @@ -1210,6 +1244,11 @@ mediaElement.muted = this.options.muted; mediaElement.volume = this.options.volume; + if(this.status.playbackRateEnabled) { + mediaElement.defaultPlaybackRate = this.options.defaultPlaybackRate; + mediaElement.playbackRate = this.options.playbackRate; + } + // Create the event listeners // Only want the active entity to affect jPlayer and bubble events. // Using entity.gate so that object is referenced and gate property always current @@ -2058,6 +2097,51 @@ playBar: function() { // Handles clicks on the playBar // The seekBar handles this event as the event propagates up the DOM. }, + playbackRate: function(pbr) { + this._setOption("playbackRate", pbr); + }, + playbackRateBar: function(e) { // Handles clicks on the playbackRateBar + if(this.css.jq.playbackRateBar.length) { + // Using $(e.currentTarget) to enable multiple playbackRate bars + var $bar = $(e.currentTarget), + offset = $bar.offset(), + x = e.pageX - offset.left, + w = $bar.width(), + y = $bar.height() - e.pageY + offset.top, + h = $bar.height(), + ratio, pbr; + if(this.options.verticalPlaybackRate) { + ratio = y/h; + } else { + ratio = x/w; + } + pbr = ratio * (this.options.maxPlaybackRate - this.options.minPlaybackRate) + this.options.minPlaybackRate; + this.playbackRate(pbr); + } + }, + playbackRateBarValue: function() { // Handles clicks on the playbackRateBarValue + // The playbackRateBar handles this event as the event propagates up the DOM. + }, + _updatePlaybackRate: function() { + var pbr = this.options.playbackRate, + ratio = (pbr - this.options.minPlaybackRate) / (this.options.maxPlaybackRate - this.options.minPlaybackRate); + if(this.status.playbackRateEnabled) { + if(this.css.jq.playbackRateBar.length) { + this.css.jq.playbackRateBar.show(); + } + if(this.css.jq.playbackRateBarValue.length) { + this.css.jq.playbackRateBarValue.show(); + this.css.jq.playbackRateBarValue[this.options.verticalPlaybackRate ? "height" : "width"]((ratio*100)+"%"); + } + } else { + if(this.css.jq.playbackRateBar.length) { + this.css.jq.playbackRateBar.hide(); + } + if(this.css.jq.playbackRateBarValue.length) { + this.css.jq.playbackRateBarValue.hide(); + } + } + }, repeat: function() { // Handle clicks on the repeat button this._loop(true); }, @@ -2170,6 +2254,28 @@ self._cssSelector(fn, cssSel); // NB: The option is set inside this function, after further validity checks. }); break; + case "playbackRate" : + this.options[key] = value = this._limitValue(value, this.options.minPlaybackRate, this.options.maxPlaybackRate); + if(this.html.used) { + this._html_playbackRate(value); + } + this._updatePlaybackRate(); + break; + case "defaultPlaybackRate" : + this.options[key] = value = this._limitValue(value, this.options.minPlaybackRate, this.options.maxPlaybackRate); + if(this.html.used) { + this._html_defaultPlaybackRate(value); + } + this._updatePlaybackRate(); + break; + case "minPlaybackRate" : + this.options[key] = value = this._limitValue(value, 0.1, this.options.maxPlaybackRate - 0.1); + this._updatePlaybackRate(); + break; + case "maxPlaybackRate" : + this.options[key] = value = this._limitValue(value, this.options.minPlaybackRate + 0.1, 16); + this._updatePlaybackRate(); + break; case "fullScreen" : if(this.options[key] !== value) { // if changed var wkv = $.jPlayer.nativeFeatures.fullscreen.used.webkitVideo; @@ -2589,6 +2695,23 @@ } } }, + // These (next 4) html media property methods could have a generic function to set them. ie., Duplicate (functional) code. + _html_defaultPlaybackRate: function(dpbr) { + if(this.html.audio.available) { + this.htmlElement.audio.defaultPlaybackRate = dpbr; + } + if(this.html.video.available) { + this.htmlElement.video.defaultPlaybackRate = dpbr; + } + }, + _html_playbackRate: function(pbr) { + if(this.html.audio.available) { + this.htmlElement.audio.playbackRate = pbr; + } + if(this.html.video.available) { + this.htmlElement.video.playbackRate = pbr; + } + }, _html_volume: function(v) { if(this.html.audio.available) { this.htmlElement.audio.volume = v; From 142afbf86fb280010f2d5f080eb6eef079988352 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Tue, 5 Nov 2013 16:09:04 +0000 Subject: [PATCH 020/218] Added ratechange event handler to update GUI --- jquery.jplayer/jquery.jplayer.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index b699b734..37341cb6 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -163,12 +163,12 @@ // "waiting", // jPlayer uses internally before bubbling. // "playing", // jPlayer uses internally before bubbling. "canplay", - "canplaythrough", + "canplaythrough" // "seeking", // jPlayer uses internally before bubbling. // "seeked", // jPlayer uses internally before bubbling. // "timeupdate", // jPlayer uses internally before bubbling. // "ended", // jPlayer uses internally before bubbling. - "ratechange" + // "ratechange" // jPlayer uses internally before bubbling. // "durationchange" // jPlayer uses internally before bubbling. // "volumechange" // jPlayer uses internally before bubbling. ]; @@ -1326,6 +1326,14 @@ self._trigger($.jPlayer.event.volumechange); } }, false); + mediaElement.addEventListener("ratechange", function() { + if(entity.gate) { + self.options.defaultPlaybackRate = mediaElement.defaultPlaybackRate; + self.options.playbackRate = mediaElement.playbackRate; + self._updatePlaybackRate(); + self._trigger($.jPlayer.event.ratechange); + } + }, false); mediaElement.addEventListener("suspend", function() { // Seems to be the only way of capturing that the iOS4 browser did not actually play the media from the page code. ie., It needs a user gesture. if(entity.gate) { self._seeked(); From 1b7b6e94f6ce391c6aeaaafa1e50f85bfee00be3 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Tue, 5 Nov 2013 16:51:42 +0000 Subject: [PATCH 021/218] Refactored html media property setting code --- jquery.jplayer/jquery.jplayer.js | 39 ++++++-------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 37341cb6..232e3c7e 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -1895,7 +1895,7 @@ mutedWorker: function(muted) { this.options.muted = muted; if(this.html.used) { - this._html_mute(muted); + this._html_setProperty('muted', muted); } if(this.flash.used) { this._flash_mute(muted); @@ -1947,7 +1947,7 @@ this.options.volume = v; if(this.html.used) { - this._html_volume(v); + this._html_setProperty('volume', v); } if(this.flash.used) { this._flash_volume(v); @@ -2265,14 +2265,14 @@ case "playbackRate" : this.options[key] = value = this._limitValue(value, this.options.minPlaybackRate, this.options.maxPlaybackRate); if(this.html.used) { - this._html_playbackRate(value); + this._html_setProperty('playbackRate', value); } this._updatePlaybackRate(); break; case "defaultPlaybackRate" : this.options[key] = value = this._limitValue(value, this.options.minPlaybackRate, this.options.maxPlaybackRate); if(this.html.used) { - this._html_defaultPlaybackRate(value); + this._html_setProperty('defaultPlaybackRate', value); } this._updatePlaybackRate(); break; @@ -2703,37 +2703,12 @@ } } }, - // These (next 4) html media property methods could have a generic function to set them. ie., Duplicate (functional) code. - _html_defaultPlaybackRate: function(dpbr) { + _html_setProperty: function(property, value) { if(this.html.audio.available) { - this.htmlElement.audio.defaultPlaybackRate = dpbr; + this.htmlElement.audio[property] = value; } if(this.html.video.available) { - this.htmlElement.video.defaultPlaybackRate = dpbr; - } - }, - _html_playbackRate: function(pbr) { - if(this.html.audio.available) { - this.htmlElement.audio.playbackRate = pbr; - } - if(this.html.video.available) { - this.htmlElement.video.playbackRate = pbr; - } - }, - _html_volume: function(v) { - if(this.html.audio.available) { - this.htmlElement.audio.volume = v; - } - if(this.html.video.available) { - this.htmlElement.video.volume = v; - } - }, - _html_mute: function(m) { - if(this.html.audio.available) { - this.htmlElement.audio.muted = m; - } - if(this.html.video.available) { - this.htmlElement.video.muted = m; + this.htmlElement.video[property] = value; } }, _flash_setAudio: function(media) { From c695b39bac4ab8da9449aca097e541410c8d67be Mon Sep 17 00:00:00 2001 From: Happyworm Date: Wed, 6 Nov 2013 01:48:09 +0000 Subject: [PATCH 022/218] Fix flashreset volume #52 by @marcn --- jquery.jplayer/jquery.jplayer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 232e3c7e..c05b5ab0 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -1478,6 +1478,7 @@ paused = this.status.paused; this.setMedia(this.status.media); + this.volumeWorker(this.options.volume); if(currentTime > 0) { if(paused) { this.pause(currentTime); From 8b7f268da9d6604007d5e386918e50640f10e91f Mon Sep 17 00:00:00 2001 From: Happyworm Date: Wed, 6 Nov 2013 15:14:41 +0000 Subject: [PATCH 023/218] Added default for vertical playbackRate GUI --- jquery.jplayer/jquery.jplayer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index c05b5ab0..8b0d965c 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -604,6 +604,7 @@ } }, verticalVolume: false, // Calculate volume from the bottom of the volume bar. Default is from the left. Also volume affects either width or height. + verticalPlaybackRate: false, globalVolume: false, // Set to make volume and muted changes affect all jPlayer instances with this option enabled idPrefix: "jp", // Prefix for the ids of html elements created by jPlayer. For flash, this must not include characters: . - + * / \ noConflict: "jQuery", From e9275549e78bebaa981a29d95928b38a01fb0db3 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Wed, 6 Nov 2013 17:41:47 +0000 Subject: [PATCH 024/218] enabled globalVolume option to be changed --- jquery.jplayer/jquery.jplayer.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 8b0d965c..63b5ed35 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -2256,6 +2256,9 @@ case "muted" : this._muted(value); break; + case "globalVolume" : + this.options[key] = value; + break; case "cssSelectorAncestor" : this._cssSelectorAncestor(value); // Set and refresh all associations for the new ancestor. break; From eef9658e674a01cdc0750a6486b7c7b9e80f4385 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Fri, 8 Nov 2013 00:07:15 +0000 Subject: [PATCH 025/218] Updated plugin version to 2.5.0 --- actionscript/Jplayer.as | 4 ++-- .../happyworm/jPlayer/JplayerStatus.as | 4 ++-- jquery.jplayer/Jplayer.swf | Bin 14147 -> 14148 bytes jquery.jplayer/jquery.jplayer.js | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index ea114d07..aa32ffea 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.4.1 - * Date: 21st June 2013 + * Version: 2.5.0 + * Date: 7th November 2013 * * FlashVars expected: (AS3 property of: loaderInfo.parameters) * id: (URL Encoded: String) Id of jPlayer instance diff --git a/actionscript/happyworm/jPlayer/JplayerStatus.as b/actionscript/happyworm/jPlayer/JplayerStatus.as index 4460201d..df2c8238 100644 --- a/actionscript/happyworm/jPlayer/JplayerStatus.as +++ b/actionscript/happyworm/jPlayer/JplayerStatus.as @@ -7,13 +7,13 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 21st June 2013 + * Date: 7th November 2013 */ package happyworm.jPlayer { public class JplayerStatus { - public static const VERSION:String = "2.4.1"; // The version of the Flash jPlayer entity. + public static const VERSION:String = "2.5.0"; // The version of the Flash jPlayer entity. public var volume:Number = 0.5; // Not affected by reset() public var muted:Boolean = false; // Not affected by reset() diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index ecc01e2c12f1e65a6519c10cfde2e33eea3208f3..2121715c8fa1314942889291905cd6da37c7c2ca 100644 GIT binary patch delta 13982 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 Yf9Ozn(Bo$QF7__Y|M&*MFa~-3U$J4nIsgCw delta 13982 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 diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 63b5ed35..3a552e05 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.4.2 - * Date: 31st October 2013 + * Version: 2.5.0 + * Date: 7th November 2013 */ /* Code verified using http://www.jshint.com/ */ @@ -468,8 +468,8 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.4.2", - needFlash: "2.4.1", + script: "2.5.0", + needFlash: "2.5.0", flash: "unknown" }, options: { // Instanced in $.jPlayer() constructor From 7075ca33cb56fa32c754c727afc8d9a32399220e Mon Sep 17 00:00:00 2001 From: Happyworm Date: Fri, 8 Nov 2013 00:07:44 +0000 Subject: [PATCH 026/218] Updated popcorn plugin to use 2.5.0 --- popcorn/player/popcorn.jplayer.js | 43 ++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/popcorn/player/popcorn.jplayer.js b/popcorn/player/popcorn.jplayer.js index fb57ac60..0c916c77 100644 --- a/popcorn/player/popcorn.jplayer.js +++ b/popcorn/player/popcorn.jplayer.js @@ -7,12 +7,12 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 1.1.1 - * Date: 5th June 2013 + * Version: 1.1.2 + * Date: 7th November 2013 * * For Popcorn Version: 1.3 - * For jPlayer Version: 2.4.0 - * Requires: jQuery 1.3.2+ + * For jPlayer Version: 2.5.0 + * Requires: jQuery 1.7+ * Note: jQuery dependancy cannot be removed since jPlayer 2 is a jQuery plugin. Use of jQuery will be kept to a minimum. */ @@ -22,14 +22,14 @@ (function(Popcorn) { - var JQUERY_SCRIPT = 'http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js', // Used if jQuery not already present. - JPLAYER_SCRIPT = 'http://www.jplayer.org/2.4.0/js/jquery.jplayer.min.js', // Used if jPlayer not already present. - JPLAYER_SWFPATH = 'http://www.jplayer.org/2.4.0/js/Jplayer.swf', // Used if not specified in jPlayer options via SRC Object. + var JQUERY_SCRIPT = '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', // Used if jQuery not already present. + JPLAYER_SCRIPT = '//www.jplayer.org/2.5.0/js/jquery.jplayer.min.js', // Used if jPlayer not already present. + JPLAYER_SWFPATH = '//www.jplayer.org/2.5.0/js/Jplayer.swf', // Used if not specified in jPlayer options via SRC Object. SOLUTION = 'html,flash', // The default solution option. DEBUG = false, // Decided to leave the debugging option and console output in for the time being. Overhead is trivial. jQueryDownloading = false, // Flag to stop multiple instances from each pulling in jQuery, thus corrupting it. jPlayerDownloading = false, // Flag to stop multiple instances from each pulling in jPlayer, thus corrupting it. - format = { // Duplicate of jPlayer 2.4.0 object, to avoid always requiring jQuery and jPlayer to be loaded before performing the _canPlayType() test. + format = { // Duplicate of jPlayer 2.5.0 object, to avoid always requiring jQuery and jPlayer to be loaded before performing the _canPlayType() test. mp3: { codec: 'audio/mpeg; codecs="mp3"', flashCanPlay: true, @@ -40,8 +40,23 @@ flashCanPlay: true, media: 'audio' }, + m3u8a: { // AAC / MP4 / Apple HLS + codec: 'application/vnd.apple.mpegurl; codecs="mp4a.40.2"', + flashCanPlay: false, + media: 'audio' + }, + m3ua: { // M3U + codec: 'audio/mpegurl', + flashCanPlay: false, + media: 'audio' + }, oga: { // OGG - codec: 'audio/ogg; codecs="vorbis"', + codec: 'audio/ogg; codecs="vorbis, opus"', + flashCanPlay: false, + media: 'audio' + }, + flac: { // FLAC + codec: 'audio/x-flac', flashCanPlay: false, media: 'audio' }, @@ -70,6 +85,16 @@ flashCanPlay: true, media: 'video' }, + m3u8v: { // H.264 / AAC / MP4 / Apple HLS + codec: 'application/vnd.apple.mpegurl; codecs="avc1.42E01E, mp4a.40.2"', + flashCanPlay: false, + media: 'video' + }, + m3uv: { // M3U + codec: 'audio/mpegurl', + flashCanPlay: false, + media: 'video' + }, ogv: { // OGG codec: 'video/ogg; codecs="theora, vorbis"', flashCanPlay: false, From 67ce6a42aaa9e40065443d35789af035181a29e6 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Fri, 8 Nov 2013 00:08:16 +0000 Subject: [PATCH 027/218] Updated package and plugin JSON files to 2.5.0 --- bower.json | 2 +- jplayer.jquery.json | 3 ++- package.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/bower.json b/bower.json index 6867d425..471df042 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.4.2", + "version": "2.5.0", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index ac65fbdc..c31bd430 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,9 +11,10 @@ "html5", "streaming" ], - "version": "2.4.2", + "version": "2.5.0", "author": { "name": "Mark J Panaghiston", + "email": "markp@happyworm.com", "url": "http://happyworm.com/" }, "licenses": [ diff --git a/package.json b/package.json index d9b28164..4e15abfb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.4.2", + "version": "2.5.0", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From b7b7dad7398de791ba4ca0b265a6be132122ec48 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 8 Dec 2013 12:26:17 +0000 Subject: [PATCH 028/218] Added comments WRT iOS full screen events --- jquery.jplayer/jquery.jplayer.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 3a552e05..99df9359 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -343,6 +343,8 @@ '' ], // http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/HTMLVideoElementClassReference/HTMLVideoElement/HTMLVideoElement.html + // https://developer.apple.com/library/safari/samplecode/HTML5VideoEventFlow/Listings/events_js.html#//apple_ref/doc/uid/DTS40010085-events_js-DontLinkElementID_5 + // Events: 'webkitbeginfullscreen' and 'webkitendfullscreen' webkitVideo: [ 'webkitSupportsFullscreen', 'webkitDisplayingFullscreen', From 182f6f7477e20645f62d23f723cab0d78f16edd1 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 8 Dec 2013 13:23:05 +0000 Subject: [PATCH 029/218] The cssSelectors no longer need an empty function. Also fixes #179 --- jquery.jplayer/jquery.jplayer.js | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 99df9359..96d7a2d5 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -1982,9 +1982,6 @@ this._muted(false); } }, - volumeBarValue: function() { // Handles clicks on the volumeBarValue - // The volumeBar handles this event as the event propagates up the DOM. - }, _updateVolume: function(v) { if(v === undefined) { v = this.options.volume; @@ -2061,7 +2058,7 @@ this.css.jq[fn] = []; // To comply with the css.jq[fn].length check before its use. As of jQuery 1.4 could have used $() for an empty set. } - if(this.css.jq[fn].length) { + if(this.css.jq[fn].length && this[fn]) { var handler = function(e) { e.preventDefault(); self[fn](e); @@ -2106,9 +2103,6 @@ this.playHead(p); } }, - playBar: function() { // Handles clicks on the playBar - // The seekBar handles this event as the event propagates up the DOM. - }, playbackRate: function(pbr) { this._setOption("playbackRate", pbr); }, @@ -2131,9 +2125,6 @@ this.playbackRate(pbr); } }, - playbackRateBarValue: function() { // Handles clicks on the playbackRateBarValue - // The playbackRateBar handles this event as the event propagates up the DOM. - }, _updatePlaybackRate: function() { var pbr = this.options.playbackRate, ratio = (pbr - this.options.minPlaybackRate) / (this.options.maxPlaybackRate - this.options.minPlaybackRate); @@ -2168,21 +2159,6 @@ } }, - // Plan to review the cssSelector method to cope with missing associated functions accordingly. - - currentTime: function() { // Handles clicks on the text - // Added to avoid errors using cssSelector system for the text - }, - duration: function() { // Handles clicks on the text - // Added to avoid errors using cssSelector system for the text - }, - gui: function() { // Handles clicks on the gui - // Added to avoid errors using cssSelector system for the gui - }, - noSolution: function() { // Handles clicks on the error message - // Added to avoid errors using cssSelector system for no-solution - }, - // Options code adapted from ui.widget.js (1.8.7). Made changes so the key can use dot notation. To match previous getData solution in jPlayer 1. option: function(key, value) { var options = key; From 36a80ff9ea4416a54f8d64f23bceaddd72905103 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 8 Dec 2013 13:56:49 +0000 Subject: [PATCH 030/218] Updated version for release of #179 bug fix --- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 6 +++--- package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bower.json b/bower.json index 471df042..21f2e95c 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.5.0", + "version": "2.5.1", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index c31bd430..8ff45a4f 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.5.0", + "version": "2.5.1", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 96d7a2d5..49215de7 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.0 - * Date: 7th November 2013 + * Version: 2.5.1 + * Date: 8th December 2013 */ /* Code verified using http://www.jshint.com/ */ @@ -470,7 +470,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.5.0", + script: "2.5.1", needFlash: "2.5.0", flash: "unknown" }, diff --git a/package.json b/package.json index 4e15abfb..5d042d99 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.5.0", + "version": "2.5.1", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From b767e2696d36faf5817b55536e4722b57a6375e6 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 15 Dec 2013 18:07:31 +0000 Subject: [PATCH 031/218] Fix: Added loadedmetadata and durationchange events to Flash MP3. --- actionscript/Jplayer.as | 10 ++++++++-- .../happyworm/jPlayer/JplayerEvent.as | 6 +++--- actionscript/happyworm/jPlayer/JplayerMp3.as | 4 +++- .../happyworm/jPlayer/JplayerStatus.as | 4 ++-- jquery.jplayer/Jplayer.swf | Bin 14148 -> 14162 bytes jquery.jplayer/jquery.jplayer.js | 8 ++++---- 6 files changed, 20 insertions(+), 12 deletions(-) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index aa32ffea..1a0bd7ef 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.0 - * Date: 7th November 2013 + * Version: 2.5.2 + * Date: 15th December 2013 * * FlashVars expected: (AS3 property of: loaderInfo.parameters) * id: (URL Encoded: String) Id of jPlayer instance @@ -279,6 +279,9 @@ package { myMp3Player.addEventListener(JplayerEvent.JPLAYER_CANPLAY, jPlayerFlashEvent); // only MP3 atm myMp3Player.addEventListener(JplayerEvent.JPLAYER_CANPLAYTHROUGH, jPlayerFlashEvent); // only MP3 atm + + myMp3Player.addEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerFlashEvent); + myMp3Player.addEventListener(JplayerEvent.JPLAYER_DURATIONCHANGE, jPlayerFlashEvent); // only MP3 atm } else { myMp3Player.removeEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent); myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent); @@ -297,6 +300,9 @@ package { myMp3Player.removeEventListener(JplayerEvent.JPLAYER_CANPLAY, jPlayerFlashEvent); // only MP3 atm myMp3Player.removeEventListener(JplayerEvent.JPLAYER_CANPLAYTHROUGH, jPlayerFlashEvent); // only MP3 atm + + myMp3Player.removeEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerFlashEvent); + myMp3Player.removeEventListener(JplayerEvent.JPLAYER_DURATIONCHANGE, jPlayerFlashEvent); // only MP3 atm } } private function listenToMp4(active:Boolean):void { diff --git a/actionscript/happyworm/jPlayer/JplayerEvent.as b/actionscript/happyworm/jPlayer/JplayerEvent.as index 56ae7633..57eb696b 100644 --- a/actionscript/happyworm/jPlayer/JplayerEvent.as +++ b/actionscript/happyworm/jPlayer/JplayerEvent.as @@ -7,7 +7,7 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 20th May 2013 + * Date: 15th December 2013 */ package happyworm.jPlayer { @@ -33,7 +33,7 @@ package happyworm.jPlayer { public static const JPLAYER_STALLED:String = "jPlayer_stalled"; // Not implemented public static const JPLAYER_PLAY:String = "jPlayer_play"; public static const JPLAYER_PAUSE:String = "jPlayer_pause"; - public static const JPLAYER_LOADEDMETADATA:String = "jPlayer_loadedmetadata"; // MP3 has no equivilent + public static const JPLAYER_LOADEDMETADATA:String = "jPlayer_loadedmetadata"; public static const JPLAYER_LOADEDDATA:String = "jPlayer_loadeddata"; // Not implemented public static const JPLAYER_WAITING:String = "jPlayer_waiting"; // Not implemented (Done in: MP3) public static const JPLAYER_PLAYING:String = "jPlayer_playing"; // Not implemented (Done in: MP3) @@ -44,7 +44,7 @@ package happyworm.jPlayer { public static const JPLAYER_TIMEUPDATE:String = "jPlayer_timeupdate"; public static const JPLAYER_ENDED:String = "jPlayer_ended"; public static const JPLAYER_RATECHANGE:String = "jPlayer_ratechange"; // Not implemented - public static const JPLAYER_DURATIONCHANGE:String = "jPlayer_durationchange"; // Not implemented + public static const JPLAYER_DURATIONCHANGE:String = "jPlayer_durationchange"; // Not implemented (Done in: MP3) public static const JPLAYER_VOLUMECHANGE:String = "jPlayer_volumechange"; // See JavaScript // Events used internal to jPlayer's Flash. diff --git a/actionscript/happyworm/jPlayer/JplayerMp3.as b/actionscript/happyworm/jPlayer/JplayerMp3.as index 648951e5..cf8f9c90 100644 --- a/actionscript/happyworm/jPlayer/JplayerMp3.as +++ b/actionscript/happyworm/jPlayer/JplayerMp3.as @@ -7,7 +7,7 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 28th May 2013 + * Date: 15th December 2013 */ package happyworm.jPlayer { @@ -100,6 +100,8 @@ package happyworm.jPlayer { myStatus.loaded(); progressUpdates(false); progressEvent(); + this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_LOADEDMETADATA, myStatus)); + this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_DURATIONCHANGE, myStatus)); this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_CANPLAYTHROUGH, myStatus)); } private function soundCompleteHandler(e:Event):void { diff --git a/actionscript/happyworm/jPlayer/JplayerStatus.as b/actionscript/happyworm/jPlayer/JplayerStatus.as index df2c8238..c31f055e 100644 --- a/actionscript/happyworm/jPlayer/JplayerStatus.as +++ b/actionscript/happyworm/jPlayer/JplayerStatus.as @@ -7,13 +7,13 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 7th November 2013 + * Date: 15th Devember 2013 */ package happyworm.jPlayer { public class JplayerStatus { - public static const VERSION:String = "2.5.0"; // The version of the Flash jPlayer entity. + public static const VERSION:String = "2.5.2"; // The version of the Flash jPlayer entity. public var volume:Number = 0.5; // Not affected by reset() public var muted:Boolean = false; // Not affected by reset() diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index 2121715c8fa1314942889291905cd6da37c7c2ca..9561b94c921468ff27ec43304284f42cb1686109 100644 GIT binary patch literal 14162 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͌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 diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 49215de7..69dd8d89 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.1 - * Date: 8th December 2013 + * Version: 2.5.2 + * Date: 15th December 2013 */ /* Code verified using http://www.jshint.com/ */ @@ -470,8 +470,8 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.5.1", - needFlash: "2.5.0", + script: "2.5.2", + needFlash: "2.5.2", flash: "unknown" }, options: { // Instanced in $.jPlayer() constructor From 7731ec5d6f3f40323bad414bec5455eac237ae3e Mon Sep 17 00:00:00 2001 From: Happyworm Date: Sun, 15 Dec 2013 18:10:15 +0000 Subject: [PATCH 032/218] Updated package version json to 2.5.2 --- bower.json | 2 +- jplayer.jquery.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bower.json b/bower.json index 21f2e95c..a646ef49 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.5.1", + "version": "2.5.2", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 8ff45a4f..e8b327ef 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.5.1", + "version": "2.5.2", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/package.json b/package.json index 5d042d99..eeb3b917 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.5.1", + "version": "2.5.2", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From dd68b8d700f856d867e556e6c671226667d786f2 Mon Sep 17 00:00:00 2001 From: Simon Owen Design Date: Mon, 23 Dec 2013 12:43:55 +0000 Subject: [PATCH 033/218] Add bower install instructions --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index a1b30116..e674e58b 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,10 @@ Support for [Zepto](http://zeptojs.com/) 1.0+ compiled with the data module. _(*) Optional counterpart formats to increase HTML5 cross-browser support._ +## Bower Install +* simple install using `bower install jplayer` +* see for more information. + ## License [jPlayer](http://jplayer.org/) is licensed under the [MIT license](http://opensource.org/licenses/MIT). From 985b8d700fba7672074c78ebb05b7cc7786d8ffe Mon Sep 17 00:00:00 2001 From: Happyworm Date: Mon, 30 Dec 2013 15:10:49 +0000 Subject: [PATCH 034/218] Bug fixed the console feature checking. --- jquery.jplayer/jquery.jplayer.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 69dd8d89..ed01bfa2 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.2 - * Date: 15th December 2013 + * Version: 2.5.3 + * Date: 30th December 2013 */ /* Code verified using http://www.jshint.com/ */ @@ -470,7 +470,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.5.2", + script: "2.5.3", needFlash: "2.5.2", flash: "unknown" }, @@ -2899,8 +2899,8 @@ var msg = "jPlayer " + this.version.script + " : id='" + this.internal.self.id +"' : " + message; if(!this.options.consoleAlerts) { alert(msg); - } else if(console && console.log) { - console.log(msg); + } else if(window.console && window.console.log) { + window.console.log(msg); } }, _emulateHtmlBridge: function() { From f06e8f730e1d957df500164d407e7c8a12ce880c Mon Sep 17 00:00:00 2001 From: Happyworm Date: Mon, 30 Dec 2013 15:13:29 +0000 Subject: [PATCH 035/218] Updated the bloody JSON versions to 2.5.3 --- bower.json | 2 +- jplayer.jquery.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bower.json b/bower.json index a646ef49..f001c79f 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.5.2", + "version": "2.5.3", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index e8b327ef..d5480437 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.5.2", + "version": "2.5.3", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/package.json b/package.json index eeb3b917..41c133f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.5.2", + "version": "2.5.3", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 26e245584b69103043ce8cbd4eb7f702037df565 Mon Sep 17 00:00:00 2001 From: Happyworm Date: Thu, 9 Jan 2014 12:59:26 +0000 Subject: [PATCH 036/218] Fix: setMedia media URLs must be truethy before abs url. --- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 10 +++++----- package.json | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bower.json b/bower.json index f001c79f..22735e8d 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.5.3", + "version": "2.5.4", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index d5480437..5db67082 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.5.3", + "version": "2.5.4", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index ed01bfa2..68440d3d 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -2,13 +2,13 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.3 - * Date: 30th December 2013 + * Version: 2.5.4 + * Date: 9th January 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -470,7 +470,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.5.3", + script: "2.5.4", needFlash: "2.5.2", flash: "unknown" }, @@ -1669,7 +1669,7 @@ _absoluteMediaUrls: function(media) { var self = this; $.each(media, function(type, url) { - if(self.format[type]) { + if(url && self.format[type]) { media[type] = self._qualifyURL(url); } }); diff --git a/package.json b/package.json index 41c133f6..eba875c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.5.3", + "version": "2.5.4", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 3c9abf5527dc0f8f5e6179e79c4d51155afc107c Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Sat, 8 Mar 2014 17:03:32 +0000 Subject: [PATCH 037/218] Fix: For Android when changing audio and immediately playing. --- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 58 ++++++++++++++++++++++++++++---- package.json | 2 +- 4 files changed, 55 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index 22735e8d..e1ca2e87 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.5.4", + "version": "2.5.5", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 5db67082..c7bf3d90 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.5.4", + "version": "2.5.5", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 68440d3d..876a9da6 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.4 - * Date: 9th January 2014 + * Version: 2.5.5 + * Date: 8th March 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -470,7 +470,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.5.4", + script: "2.5.5", needFlash: "2.5.2", flash: "unknown" }, @@ -794,6 +794,17 @@ $.jPlayer.focus = this; } + // A fix for Android where older (2.3) and even some 4.x devices fail to work when changing the *audio* SRC and then playing immediately. + this.androidFix = { + setMedia: false, // True when media set + play: false, // True when a progress event will instruct the media to play + pause: false, // True when a progress event will instruct the media to pause at a time. + time: NaN // The play(time) parameter + }; + if($.jPlayer.platform.android) { + this.options.preload = this.options.preload !== 'auto' ? 'metadata' : 'auto'; // Default to metadata, but allow auto. + } + this.formats = []; // Array based on supplied string option. Order defines priority. this.solutions = []; // Array based on solution string option. Order defines priority. this.require = {}; // Which media types are required: video, audio. @@ -1261,6 +1272,15 @@ if(self.internal.cmdsIgnored && this.readyState > 0) { // Detect iOS executed the command self.internal.cmdsIgnored = false; } + self.androidFix.setMedia = false; // Disable the fix after the first progress event. + if(self.androidFix.play) { // Play Android audio - performing the fix. + self.androidFix.play = false; + self.play(self.androidFix.time); + } + if(self.androidFix.pause) { // Pause Android audio at time - performing the fix. + self.androidFix.pause = false; + self.pause(self.androidFix.time); + } self._getHtmlStatus(mediaElement); self._updateInterface(); self._trigger($.jPlayer.event.progress); @@ -1691,6 +1711,11 @@ this._resetGate(); this._resetActive(); + // Clear the Android Fix. + this.androidFix.setMedia = false; + this.androidFix.play = false; + this.androidFix.pause = false; + // Convert all media URLs to absolute URLs. media = this._absoluteMediaUrls(media); @@ -1719,6 +1744,11 @@ self.html.audio.gate = true; self._html_setAudio(media); self.html.active = true; + + // Setup the Android Fix - Only for HTML audio. + if($.jPlayer.platform.android) { + self.androidFix.setMedia = true; + } } else { self.flash.gate = true; self._flash_setAudio(media); @@ -2590,9 +2620,16 @@ var self = this, media = this.htmlElement.media; + this.androidFix.pause = false; // Cancel the pause fix. + this._html_load(); // Loads if required and clears any delayed commands. - if(!isNaN(time)) { + // Setup the Android Fix. + if(this.androidFix.setMedia) { + this.androidFix.play = true; + this.androidFix.time = time; + + } else if(!isNaN(time)) { // Attempt to play it, since iOS has been ignoring commands if(this.internal.cmdsIgnored) { @@ -2622,7 +2659,9 @@ _html_pause: function(time) { var self = this, media = this.htmlElement.media; - + + this.androidFix.play = false; // Cancel the play fix. + if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation. this._html_load(); // Loads if required and clears any delayed commands. } else { @@ -2632,7 +2671,12 @@ // Order of these commands is important for Safari (Win) and IE9. Pause then change currentTime. media.pause(); - if(!isNaN(time)) { + // Setup the Android Fix. + if(this.androidFix.setMedia) { + this.androidFix.pause = true; + this.androidFix.time = time; + + } else if(!isNaN(time)) { try { if(!media.seekable || typeof media.seekable === "object" && media.seekable.length > 0) { media.currentTime = time; @@ -2656,6 +2700,8 @@ this._html_load(); // Loads if required and clears any delayed commands. + // This playHead() method needs a refactor to apply the android fix. + try { if(typeof media.seekable === "object" && media.seekable.length > 0) { media.currentTime = percent * media.seekable.end(media.seekable.length-1) / 100; diff --git a/package.json b/package.json index eba875c2..91cba22c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.5.4", + "version": "2.5.5", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 07b4cca0f83d664da9b8e7c303241a4de91d9725 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 02:42:06 +0100 Subject: [PATCH 038/218] The media.title property of the setMedia object is now written to the jp-title class of the instance. --- jquery.jplayer/jquery.jplayer.js | 12 ++++++++++++ skin/blue.monday/jplayer.blue.monday.css | 21 ++++++++++----------- skin/pink.flag/jplayer.pink.flag.css | 17 ++++++++--------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 876a9da6..c0f62923 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -504,6 +504,7 @@ playbackRateBarValue: ".jp-playback-rate-bar-value", currentTime: ".jp-current-time", duration: ".jp-duration", + title: ".jp-title", fullScreen: ".jp-full-screen", // * restoreScreen: ".jp-restore-screen", // * repeat: ".jp-repeat", @@ -1782,6 +1783,17 @@ } } } + if(this.css.jq.title.length) { + if(typeof media.title === 'string') { + this.css.jq.title.html(media.title); + if(this.htmlElement.audio) { + this.htmlElement.audio.setAttribute('title', media.title); + } + if(this.htmlElement.video) { + this.htmlElement.video.setAttribute('title', media.title); + } + } + } this.status.srcSet = true; this.status.media = $.extend({}, media); this._updateButtons(false); diff --git a/skin/blue.monday/jplayer.blue.monday.css b/skin/blue.monday/jplayer.blue.monday.css index fa07bc51..ebe6ffb5 100644 --- a/skin/blue.monday/jplayer.blue.monday.css +++ b/skin/blue.monday/jplayer.blue.monday.css @@ -4,14 +4,13 @@ * * Skin Name: Blue Monday * - * Copyright (c) 2010-2012 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. + * Copyright (c) 2010-2014 Happyworm Ltd + * Licensed under the MIT license. * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html * * Author: Silvia Benvenuti - * Skin Version: 4.3 (jPlayer 2.2.0) - * Date: 19th November 2012 + * Skin Version: 4.4 (jPlayer 2.6.0) + * Date: 1st April 2014 */ div.jp-audio, @@ -378,23 +377,23 @@ div.jp-video div.jp-duration { /* @group playlist */ -div.jp-title { +div.jp-details { font-weight:bold; text-align:center; } -div.jp-title, +div.jp-details, div.jp-playlist { width:100%; background-color:#ccc; border-top:1px solid #009be3; } -div.jp-type-single div.jp-title, -div.jp-type-playlist div.jp-title, +div.jp-type-single div.jp-details, +div.jp-type-playlist div.jp-details, div.jp-type-single div.jp-playlist { border-top:none; } -div.jp-title ul, +div.jp-details ul, div.jp-playlist ul { list-style-type:none; margin:0; @@ -402,7 +401,7 @@ div.jp-playlist ul { font-size:.72em; } -div.jp-title li { +div.jp-details li { padding:5px 0; font-weight:bold; } diff --git a/skin/pink.flag/jplayer.pink.flag.css b/skin/pink.flag/jplayer.pink.flag.css index bafe3ff8..64cfd2a4 100644 --- a/skin/pink.flag/jplayer.pink.flag.css +++ b/skin/pink.flag/jplayer.pink.flag.css @@ -4,14 +4,13 @@ * * Skin Name: Pink Flag * - * Copyright (c) 2012 Happyworm Ltd - * Dual licensed under the MIT and GPL licenses. + * Copyright (c) 2012 - 2014 Happyworm Ltd + * Licensed under the MIT license. * - http://www.opensource.org/licenses/mit-license.php - * - http://www.gnu.org/copyleft/gpl.html * * Author: Silvia Benvenuti - * Skin Version: 1.2 (jPlayer 2.2.0) - * Date: 22nd October 2012 + * Skin Version: 1.3 (jPlayer 2.6.0) + * Date: 1st April 2014 */ div.jp-audio, @@ -499,7 +498,7 @@ div.jp-video .jp-volume-bar { /* @group playlist */ -.jp-title ul, +.jp-details ul, .jp-playlist ul { list-style-type:none; font-size:.7em; @@ -507,7 +506,7 @@ div.jp-video .jp-volume-bar { padding: 0; } -.jp-video .jp-title ul { +.jp-video .jp-details ul { margin: 0 20px 10px; } @@ -515,7 +514,7 @@ div.jp-video .jp-volume-bar { margin: 0 20px; } -.jp-title li, +.jp-details li, .jp-playlist li { position: relative; padding: 2px 0; @@ -524,7 +523,7 @@ div.jp-video .jp-volume-bar { overflow: hidden; } -.jp-title li{ +.jp-details li{ border-bottom:none; border-top:none; padding:0; From ce54455da533399bbae303872d7bbf435f0c02bc Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 07:57:18 +0100 Subject: [PATCH 039/218] Fixing pink flag css CRLF. pt1 --- skin/pink.flag/jplayer.pink.flag.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skin/pink.flag/jplayer.pink.flag.css b/skin/pink.flag/jplayer.pink.flag.css index 64cfd2a4..9396d4cb 100644 --- a/skin/pink.flag/jplayer.pink.flag.css +++ b/skin/pink.flag/jplayer.pink.flag.css @@ -9,7 +9,7 @@ * - http://www.opensource.org/licenses/mit-license.php * * Author: Silvia Benvenuti - * Skin Version: 1.3 (jPlayer 2.6.0) + * Skin Version: 1.3 (jPlayer 2.6.0) - force * Date: 1st April 2014 */ From 3461207e993acf78414cec2d3b82577eee09000f Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 07:57:34 +0100 Subject: [PATCH 040/218] Fixing pink flag css CRLF. pt2 --- skin/pink.flag/jplayer.pink.flag.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skin/pink.flag/jplayer.pink.flag.css b/skin/pink.flag/jplayer.pink.flag.css index 9396d4cb..64cfd2a4 100644 --- a/skin/pink.flag/jplayer.pink.flag.css +++ b/skin/pink.flag/jplayer.pink.flag.css @@ -9,7 +9,7 @@ * - http://www.opensource.org/licenses/mit-license.php * * Author: Silvia Benvenuti - * Skin Version: 1.3 (jPlayer 2.6.0) - force + * Skin Version: 1.3 (jPlayer 2.6.0) * Date: 1st April 2014 */ From 29c7d3b636a4025d0bd905d17966236bda67d982 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 09:08:40 +0100 Subject: [PATCH 041/218] Added the remainingDuration and toggleDuration options and implemented the features. --- jquery.jplayer/jquery.jplayer.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index c0f62923..91b7e21f 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -481,6 +481,8 @@ preload: 'metadata', // HTML5 Spec values: none, metadata, auto. volume: 0.8, // The volume. Number 0 to 1. muted: false, + remainingDuration: false, // When true, the remaining time is shown in the duration GUI element. + toggleDuration: false, // When true, clicks on the duration toggle between the duration and remaining display. playbackRate: 1, defaultPlaybackRate: 1, minPlaybackRate: 0.5, @@ -656,6 +658,7 @@ currentPercentAbsolute: 0, currentTime: 0, duration: 0, + remaining: 0, videoWidth: 0, // Intrinsic width of the video in pixels. videoHeight: 0, // Intrinsic height of the video in pixels. readyState: 0, @@ -1443,6 +1446,8 @@ this.status.currentPercentAbsolute = cpa; this.status.currentTime = ct; + this.status.remaining = this.status.duration - this.status.currentTime; + this.status.videoWidth = media.videoWidth; this.status.videoHeight = media.videoHeight; @@ -1592,6 +1597,7 @@ this.status.currentPercentAbsolute = status.currentPercentAbsolute; this.status.currentTime = status.currentTime; this.status.duration = status.duration; + this.status.remaining = status.duration - status.currentTime; this.status.videoWidth = status.videoWidth; this.status.videoHeight = status.videoHeight; @@ -1656,7 +1662,11 @@ this.css.jq.currentTime.text(this._convertTime(this.status.currentTime)); } if(this.css.jq.duration.length) { - this.css.jq.duration.text(this._convertTime(this.status.duration)); + if(this.options.remainingDuration) { + this.css.jq.duration.text((this.status.remaining > 0 ? '-' : '') + this._convertTime(this.status.remaining)); + } else { + this.css.jq.duration.text(this._convertTime(this.status.duration)); + } } }, _convertTime: ConvertTime.prototype.time, @@ -2134,6 +2144,11 @@ }); } }, + duration: function(e) { + if(this.options.toggleDuration) { + this._setOption("remainingDuration", !this.options.remainingDuration); + } + }, seekBar: function(e) { // Handles clicks on the seekBar if(this.css.jq.seekBar.length) { // Using $(e.currentTarget) to enable multiple seek bars @@ -2355,6 +2370,13 @@ case "loop" : this._loop(value); break; + case "remainingDuration" : + this.options[key] = value; + this._updateInterface(); + break; + case "toggleDuration" : + this.options[key] = value; + break; case "nativeVideoControls" : this.options[key] = $.extend({}, this.options[key], value); // store a merged copy of it, incase not all properties changed. this.status.nativeVideoControls = this._uaBlocklist(this.options.nativeVideoControls); From 2ae3fac1a007696a9db87dd35465edf9146c76ee Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 09:27:47 +0100 Subject: [PATCH 042/218] Added a new setmedia event, when setMedia is used. --- add-on/jquery.jplayer.inspector.js | 11 ++++++----- jquery.jplayer/jquery.jplayer.js | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/add-on/jquery.jplayer.inspector.js b/add-on/jquery.jplayer.inspector.js index 2962b44f..e7a6cf89 100644 --- a/add-on/jquery.jplayer.inspector.js +++ b/add-on/jquery.jplayer.inspector.js @@ -2,15 +2,15 @@ * jPlayerInspector Plugin for jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 1.0.4 - * Date: 29th January 2013 + * Version: 1.0.5 + * Date: 1st April 2014 * - * For use with jPlayer Version: 2.2.19+ + * For use with jPlayer Version: 2.6.0+ * * Note: Declare inspector instances after jPlayer instances. ie., Otherwise the jPlayer instance is nonsense. */ @@ -70,17 +70,18 @@ // MJP: Doing it longhand so order and layout easier to control. structure += '
' + + '
' + '
' + '
' + '
' + '
' - + '
' + '
' + '
' + '
' + '
' + '
' + + '
' + '
' + '
' diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 91b7e21f..7636db67 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -113,6 +113,7 @@ $.each( [ 'ready', + 'setmedia', // Fires when the media is set 'flashreset', // Similar to the ready event if the Flash solution is set to display:none and then shown again or if it's reloaded for another reason by the browser. For example, using CSS position:fixed on Firefox for the full screen feature. 'resize', // Occurs when the size changes through a full/restore screen operation or if the size/sizeFull options are changed. 'repeat', // Occurs when the repeat status changes. Usually through clicks on the repeat button of the interface. @@ -1808,6 +1809,7 @@ this.status.media = $.extend({}, media); this._updateButtons(false); this._updateInterface(); + this._trigger($.jPlayer.event.setmedia); } else { // jPlayer cannot support any formats provided in this browser // Send an error event this._error( { From 95fb73542f9f00a870e7fcb649f3afe827227864 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 09:57:41 +0100 Subject: [PATCH 043/218] The currentTime and duration only update the GUI when they change. --- jquery.jplayer/jquery.jplayer.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 7636db67..969d0eae 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -1659,14 +1659,22 @@ this.css.jq.playBar.width(this.status.currentPercentRelative+"%"); } } + var currentTimeText = ''; if(this.css.jq.currentTime.length) { - this.css.jq.currentTime.text(this._convertTime(this.status.currentTime)); + currentTimeText = this._convertTime(this.status.currentTime); + if(currentTimeText !== this.css.jq.currentTime.text()) { + this.css.jq.currentTime.text(this._convertTime(this.status.currentTime)); + } } + var durationText = ''; if(this.css.jq.duration.length) { if(this.options.remainingDuration) { - this.css.jq.duration.text((this.status.remaining > 0 ? '-' : '') + this._convertTime(this.status.remaining)); + durationText = (this.status.remaining > 0 ? '-' : '') + this._convertTime(this.status.remaining); } else { - this.css.jq.duration.text(this._convertTime(this.status.duration)); + durationText = this._convertTime(this.status.duration); + } + if(durationText !== this.css.jq.duration.text()) { + this.css.jq.duration.text(durationText); } } }, From 3c74f753b6a44013d0d3dd64727b7d1a567a67b0 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 10:29:05 +0100 Subject: [PATCH 044/218] The media.duration property of the setMedia object is now used when displaying the jp-duration. --- jquery.jplayer/jquery.jplayer.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 969d0eae..1af4b2e2 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -1666,12 +1666,22 @@ this.css.jq.currentTime.text(this._convertTime(this.status.currentTime)); } } - var durationText = ''; + var durationText = '', + duration = this.status.duration, + remaining = this.status.remaining; if(this.css.jq.duration.length) { - if(this.options.remainingDuration) { - durationText = (this.status.remaining > 0 ? '-' : '') + this._convertTime(this.status.remaining); + if(typeof this.status.media.duration === 'string') { + durationText = this.status.media.duration; } else { - durationText = this._convertTime(this.status.duration); + if(typeof this.status.media.duration === 'number') { + duration = this.status.media.duration; + remaining = duration - this.status.currentTime; + } + if(this.options.remainingDuration) { + durationText = (remaining > 0 ? '-' : '') + this._convertTime(remaining); + } else { + durationText = this._convertTime(duration); + } } if(durationText !== this.css.jq.duration.text()) { this.css.jq.duration.text(durationText); From 49dc5c4009b90d2809d13b32cdf991fc8a233bb5 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 1 Apr 2014 14:16:16 +0100 Subject: [PATCH 045/218] Fix: Destroy now removes full screen event listeners. --- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 8 ++++---- package.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bower.json b/bower.json index e1ca2e87..bc6eb809 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.5.5", + "version": "2.5.6", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index c7bf3d90..af6e1558 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.5.5", + "version": "2.5.6", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 876a9da6..b91cb4d9 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.5 - * Date: 8th March 2014 + * Version: 2.5.6 + * Date: 1st April 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -470,7 +470,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.5.5", + script: "2.5.6", needFlash: "2.5.2", flash: "unknown" }, @@ -2504,7 +2504,7 @@ _fullscreenRemoveEventListeners: function() { var fs = $.jPlayer.nativeFeatures.fullscreen; if(this.internal.fullscreenchangeHandler) { - document.addEventListener(fs.event.fullscreenchange, this.internal.fullscreenchangeHandler, false); + document.removeEventListener(fs.event.fullscreenchange, this.internal.fullscreenchangeHandler, false); } }, _fullscreenchange: function() { diff --git a/package.json b/package.json index 91cba22c..c91805d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.5.5", + "version": "2.5.6", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 47ca9d9c7358f70f301180092dcc9ff8cabbb325 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Wed, 2 Apr 2014 13:16:05 +0100 Subject: [PATCH 046/218] Updated Unchanged AS files for year. --- actionscript/happyworm/jPlayer/ConnectManager.as | 2 +- actionscript/happyworm/jPlayer/JplayerEvent.as | 2 +- actionscript/happyworm/jPlayer/JplayerMp3.as | 2 +- actionscript/happyworm/jPlayer/JplayerMp4.as | 2 +- actionscript/happyworm/jPlayer/JplayerRtmp.as | 2 +- actionscript/happyworm/jPlayer/TraceOut.as | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/actionscript/happyworm/jPlayer/ConnectManager.as b/actionscript/happyworm/jPlayer/ConnectManager.as index f8020544..ae16b7d0 100644 --- a/actionscript/happyworm/jPlayer/ConnectManager.as +++ b/actionscript/happyworm/jPlayer/ConnectManager.as @@ -2,7 +2,7 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * diff --git a/actionscript/happyworm/jPlayer/JplayerEvent.as b/actionscript/happyworm/jPlayer/JplayerEvent.as index 57eb696b..13b0971f 100644 --- a/actionscript/happyworm/jPlayer/JplayerEvent.as +++ b/actionscript/happyworm/jPlayer/JplayerEvent.as @@ -2,7 +2,7 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * diff --git a/actionscript/happyworm/jPlayer/JplayerMp3.as b/actionscript/happyworm/jPlayer/JplayerMp3.as index cf8f9c90..1e6cf162 100644 --- a/actionscript/happyworm/jPlayer/JplayerMp3.as +++ b/actionscript/happyworm/jPlayer/JplayerMp3.as @@ -2,7 +2,7 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * diff --git a/actionscript/happyworm/jPlayer/JplayerMp4.as b/actionscript/happyworm/jPlayer/JplayerMp4.as index c3fffd3c..63bcfb66 100644 --- a/actionscript/happyworm/jPlayer/JplayerMp4.as +++ b/actionscript/happyworm/jPlayer/JplayerMp4.as @@ -2,7 +2,7 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * diff --git a/actionscript/happyworm/jPlayer/JplayerRtmp.as b/actionscript/happyworm/jPlayer/JplayerRtmp.as index 5e9d65e8..1f8505aa 100644 --- a/actionscript/happyworm/jPlayer/JplayerRtmp.as +++ b/actionscript/happyworm/jPlayer/JplayerRtmp.as @@ -2,7 +2,7 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * diff --git a/actionscript/happyworm/jPlayer/TraceOut.as b/actionscript/happyworm/jPlayer/TraceOut.as index 956e3a20..a66cca5b 100644 --- a/actionscript/happyworm/jPlayer/TraceOut.as +++ b/actionscript/happyworm/jPlayer/TraceOut.as @@ -2,7 +2,7 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * From 3d3fe2d70345069f73da063ad9e2757587513796 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Wed, 2 Apr 2014 13:28:37 +0100 Subject: [PATCH 047/218] Updated versioning to jPlayer 2.6.0 --- actionscript/Jplayer.as | 8 ++++---- .../happyworm/jPlayer/JplayerStatus.as | 6 +++--- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/Jplayer.swf | Bin 14162 -> 14163 bytes jquery.jplayer/jquery.jplayer.js | 8 ++++---- package.json | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index 1a0bd7ef..f07b1296 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -2,13 +2,13 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd - * Licensed under the MIT. + * Copyright (c) 2009 - 2014 Happyworm Ltd + * Licensed under the MIT license. * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.5.2 - * Date: 15th December 2013 + * Version: 2.6.0 + * Date: 2nd April 2014 * * FlashVars expected: (AS3 property of: loaderInfo.parameters) * id: (URL Encoded: String) Id of jPlayer instance diff --git a/actionscript/happyworm/jPlayer/JplayerStatus.as b/actionscript/happyworm/jPlayer/JplayerStatus.as index c31f055e..909816a7 100644 --- a/actionscript/happyworm/jPlayer/JplayerStatus.as +++ b/actionscript/happyworm/jPlayer/JplayerStatus.as @@ -2,18 +2,18 @@ * jPlayer Plugin for jQuery JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 15th Devember 2013 + * Date: 2nd April 2014 */ package happyworm.jPlayer { public class JplayerStatus { - public static const VERSION:String = "2.5.2"; // The version of the Flash jPlayer entity. + public static const VERSION:String = "2.6.0"; // The version of the Flash jPlayer entity. public var volume:Number = 0.5; // Not affected by reset() public var muted:Boolean = false; // Not affected by reset() diff --git a/bower.json b/bower.json index bc6eb809..f3454511 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.5.6", + "version": "2.6.0", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index af6e1558..2657baac 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.5.6", + "version": "2.6.0", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index 9561b94c921468ff27ec43304284f42cb1686109..cf7a4f4bafee840725d860e1b374ecd7c9ab5582 100644 GIT binary patch literal 14163 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͌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 z Date: Wed, 2 Apr 2014 17:22:26 +0100 Subject: [PATCH 048/218] Updated popcorn player for 2.6.0 --- popcorn/player/popcorn.jplayer.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/popcorn/player/popcorn.jplayer.js b/popcorn/player/popcorn.jplayer.js index 0c916c77..154e1909 100644 --- a/popcorn/player/popcorn.jplayer.js +++ b/popcorn/player/popcorn.jplayer.js @@ -2,16 +2,16 @@ * jPlayer Player Plugin for Popcorn JavaScript Library * http://www.jplayer.org * - * Copyright (c) 2013 Happyworm Ltd + * Copyright (c) 2012 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 1.1.2 - * Date: 7th November 2013 + * Version: 1.1.3 + * Date: 2nd April 2014 * * For Popcorn Version: 1.3 - * For jPlayer Version: 2.5.0 + * For jPlayer Version: 2.6.0 * Requires: jQuery 1.7+ * Note: jQuery dependancy cannot be removed since jPlayer 2 is a jQuery plugin. Use of jQuery will be kept to a minimum. */ @@ -22,9 +22,9 @@ (function(Popcorn) { - var JQUERY_SCRIPT = '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', // Used if jQuery not already present. - JPLAYER_SCRIPT = '//www.jplayer.org/2.5.0/js/jquery.jplayer.min.js', // Used if jPlayer not already present. - JPLAYER_SWFPATH = '//www.jplayer.org/2.5.0/js/Jplayer.swf', // Used if not specified in jPlayer options via SRC Object. + var JQUERY_SCRIPT = '//code.jquery.com/jquery-1.11.0.min.js', // Used if jQuery not already present. + JPLAYER_SCRIPT = '//www.jplayer.org/2.6.0/js/jquery.jplayer.min.js', // Used if jPlayer not already present. + JPLAYER_SWFPATH = '//www.jplayer.org/2.6.0/js/Jplayer.swf', // Used if not specified in jPlayer options via SRC Object. SOLUTION = 'html,flash', // The default solution option. DEBUG = false, // Decided to leave the debugging option and console output in for the time being. Overhead is trivial. jQueryDownloading = false, // Flag to stop multiple instances from each pulling in jQuery, thus corrupting it. From 7a2ebbb04185a3fe38bc6b47d6596467b79ab454 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Wed, 2 Apr 2014 17:55:46 +0100 Subject: [PATCH 049/218] Corrected date in Flash menu --- actionscript/Jplayer.as | 2 +- jquery.jplayer/Jplayer.swf | Bin 14163 -> 14162 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index f07b1296..c621aace 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -122,7 +122,7 @@ package { var myContextMenu:ContextMenu = new ContextMenu(); myContextMenu.hideBuiltInItems(); var menuItem_jPlayer:ContextMenuItem = new ContextMenuItem("jPlayer " + JplayerStatus.VERSION); - var menuItem_happyworm:ContextMenuItem = new ContextMenuItem("© 2009-2013 Happyworm Ltd", true); + var menuItem_happyworm:ContextMenuItem = new ContextMenuItem("© 2009-2014 Happyworm Ltd", true); menuItem_jPlayer.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuSelectHandler_jPlayer); menuItem_happyworm.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuSelectHandler_happyworm); myContextMenu.customItems.push(menuItem_jPlayer, menuItem_happyworm); diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index cf7a4f4bafee840725d860e1b374ecd7c9ab5582..3012248067e63a1b0a9da3d2185d271de1fb8188 100644 GIT binary patch literal 14162 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 Uf>`J>z8Cw{RlfqfFUgPp2hU0Sp8x;= literal 14163 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 Date: Thu, 3 Apr 2014 21:57:30 +0100 Subject: [PATCH 050/218] Fix: Added captureDuration option to capture clicks on the duration. --- jquery.jplayer/jquery.jplayer.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 2214019a..facb17a4 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.6.0 - * Date: 2nd April 2014 + * Version: 2.6.1 + * Date: 3rd April 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -471,7 +471,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.6.0", + script: "2.6.1", needFlash: "2.6.0", flash: "unknown" }, @@ -484,6 +484,7 @@ muted: false, remainingDuration: false, // When true, the remaining time is shown in the duration GUI element. toggleDuration: false, // When true, clicks on the duration toggle between the duration and remaining display. + captureDuration: true, // When true, clicks on the duration are captured and no longer propagate up the DOM. playbackRate: 1, defaultPlaybackRate: 1, minPlaybackRate: 0.5, @@ -2166,6 +2167,9 @@ }, duration: function(e) { if(this.options.toggleDuration) { + if(this.options.captureDuration) { + e.stopPropagation(); + } this._setOption("remainingDuration", !this.options.remainingDuration); } }, From aca237f4f6873c4fe952064636e8fd54926e0682 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Thu, 3 Apr 2014 21:59:05 +0100 Subject: [PATCH 051/218] Updated the versioning --- bower.json | 2 +- jplayer.jquery.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bower.json b/bower.json index f3454511..44acc064 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.6.0", + "version": "2.6.1", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 2657baac..05f5f00b 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.6.0", + "version": "2.6.1", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/package.json b/package.json index 59a70c36..de73ef5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.6.0", + "version": "2.6.1", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 0810db8c46d8362f24b368a5537523495502ef0f Mon Sep 17 00:00:00 2001 From: Matt Fawcett Date: Wed, 23 Apr 2014 13:09:39 +0100 Subject: [PATCH 052/218] Update the android_phone fullscreen support useragent detection regex so that it allows fullscreen on android phones using the Chrome browser. Chrome on android has supported full screen since it's release: http://www.brighthand.com/default.asp?newsID=20141 --- jquery.jplayer/jquery.jplayer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index facb17a4..9c365187 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -546,7 +546,7 @@ iphone: /iphone/, ipod: /ipod/, android_pad: /android [0-3]\.(?!.*?mobile)/, - android_phone: /android.*?mobile/, + android_phone: /(?=.*android)(?!.*chrome)(?=.*mobile)/, blackberry: /blackberry/, windows_ce: /windows ce/, iemobile: /iemobile/, From 16e8c38f031f43a703be8200407164c4d284c29c Mon Sep 17 00:00:00 2001 From: Matt Fawcett Date: Fri, 2 May 2014 09:04:39 +0100 Subject: [PATCH 053/218] Add support for native fullscreen api in Internet explorer. Currenly works in IE11 (the latest) using the ms prefix. --- jquery.jplayer/jquery.jplayer.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index facb17a4..8f737fea 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -353,13 +353,22 @@ 'webkitExitFullscreen', '', '' + ], + ms: [ + '', + 'msFullscreenElement', + 'msRequestFullscreen', + 'msExitFullscreen', + 'MSFullscreenChange', + 'MSFullscreenError' ] }, specOrder = [ 'w3c', 'moz', 'webkit', - 'webkitVideo' + 'webkitVideo', + 'ms' ], fs, i, il; @@ -368,7 +377,8 @@ w3c: !!d[spec.w3c[0]], moz: !!d[spec.moz[0]], webkit: typeof d[spec.webkit[3]] === 'function', - webkitVideo: typeof v[spec.webkitVideo[2]] === 'function' + webkitVideo: typeof v[spec.webkitVideo[2]] === 'function', + ms: typeof v[spec.ms[2]] === 'function' }, used: {} }; From bd311f02050be5fb5456863be39974d47cf9ed49 Mon Sep 17 00:00:00 2001 From: Giorgio Consorti Date: Sun, 18 May 2014 19:34:32 +0200 Subject: [PATCH 054/218] fix for wrong mousemove event on Chrome browser --- jquery.jplayer/jquery.jplayer.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index facb17a4..17fbed7a 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -685,6 +685,7 @@ // domNode: undefined // htmlDlyCmdId: undefined // autohideId: undefined + // lastMousePosition: undefined // cmdsIgnored }, solution: { // Static Object: Defines the solutions built in jPlayer. @@ -2501,13 +2502,30 @@ event = "mousemove.jPlayer", namespace = ".jPlayerAutohide", eventType = event + namespace, - handler = function() { + handler = function(sourceEvent) { + var mouseMoved = false; + if (self.internal.lastMousePosition != undefined) { + //get the change from last position to this position + var deltaX = self.internal.lastMousePosition.x - sourceEvent.clientX, + deltaY = self.internal.lastMousePosition.y - sourceEvent.clientY; + mouseMoved = (Math.abs(deltaX)>0) || (Math.abs(deltaY)>0); + } else { + mouseMoved = true; + } + // store current position for next method execution + self.internal.lastMousePosition = { + x : sourceEvent.clientX, + y : sourceEvent.clientY + }; + // if mouse has been actually moved, do the gui fadeIn/fadeOut + if (mouseMoved) { self.css.jq.gui.fadeIn(self.options.autohide.fadeIn, function() { clearTimeout(self.internal.autohideId); self.internal.autohideId = setTimeout( function() { self.css.jq.gui.fadeOut(self.options.autohide.fadeOut); }, self.options.autohide.hold); }); + } }; if(this.css.jq.gui.length) { @@ -2518,6 +2536,8 @@ // Removes the fadeOut operation from the fadeIn callback. clearTimeout(this.internal.autohideId); + // undefine lastMousePosition + delete this.internal.lastMousePosition; this.element.unbind(namespace); this.css.jq.gui.unbind(namespace); From 0b82804315de6f315fea2139f54d3360cadc95c9 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Fri, 30 May 2014 19:15:16 +0100 Subject: [PATCH 055/218] Fixed #206 jPlayer breaks links for keyboard users. --- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 28 ++++++++++++++++++---------- package.json | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/bower.json b/bower.json index 44acc064..466bc075 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.6.1", + "version": "2.6.2", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 05f5f00b..10ab58c7 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.6.1", + "version": "2.6.2", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index facb17a4..c0a21c6a 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.6.1 - * Date: 3rd April 2014 + * Version: 2.6.2 + * Date: 30th May 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -423,25 +423,33 @@ // The current jPlayer instance in focus. $.jPlayer.focus = null; - // The list of element node names to ignore with key controls. - $.jPlayer.keyIgnoreElementNames = "INPUT TEXTAREA"; + // (fallback) The list of element node names to ignore with key controls. + $.jPlayer.keyIgnoreElementNames = "A INPUT TEXTAREA SELECT BUTTON"; // The function that deals with key presses. var keyBindings = function(event) { var f = $.jPlayer.focus, + pageFocus = document.activeElement, ignoreKey; // A jPlayer instance must be in focus. ie., keyEnabled and the last one played. if(f) { // What generated the key press? - $.each( $.jPlayer.keyIgnoreElementNames.split(/\s+/g), function(i, name) { - // The strings should already be uppercase. - if(event.target.nodeName.toUpperCase() === name.toUpperCase()) { + if(typeof pageFocus !== 'undefined') { + if(typeof pageFocus !== 'null' && pageFocus.nodeName.toUpperCase() !== "BODY") { ignoreKey = true; - return false; // exit each. } - }); + } else { + // Fallback for no document.activeElement support. + $.each( $.jPlayer.keyIgnoreElementNames.split(/\s+/g), function(i, name) { + // The strings should already be uppercase. + if(event.target.nodeName.toUpperCase() === name.toUpperCase()) { + ignoreKey = true; + return false; // exit each. + } + }); + } if(!ignoreKey) { // See if the key pressed matches any of the bindings. $.each(f.options.keyBindings, function(action, binding) { @@ -471,7 +479,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.6.1", + script: "2.6.2", needFlash: "2.6.0", flash: "unknown" }, diff --git a/package.json b/package.json index de73ef5f..5aed5dd0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.6.1", + "version": "2.6.2", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From d0762d83ea9863e7eae30256a26d2c4071359301 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Fri, 30 May 2014 20:36:33 +0100 Subject: [PATCH 056/218] Added autoBlur option to control blur after user action. --- jquery.jplayer/jquery.jplayer.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index c0a21c6a..3cc36975 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -524,6 +524,7 @@ gui: ".jp-gui", // The interface used with autohide feature. noSolution: ".jp-no-solution" // For error feedback when jPlayer cannot find a solution. }, + autoBlur: true, // GUI control handlers will drop focus after clicks. smoothPlayBar: false, // Smooths the play bar transitions, which affects clicks and short media with big changes per second. fullScreen: false, // Native Full Screen fullWindow: false, @@ -2143,7 +2144,9 @@ var handler = function(e) { e.preventDefault(); self[fn](e); - $(this).blur(); + if(self.options.autoBlur) { + $(this).blur(); + } }; this.css.jq[fn].bind("click.jPlayer", handler); // Using jPlayer namespace } @@ -2453,6 +2456,9 @@ case "audioFullScreen" : this.options[key] = value; break; + case "autoBlur" : + this.options[key] = value; + break; } return this; From 2cb72ad56e7cdf09d3b1bb94e647750fc609942c Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Fri, 30 May 2014 20:51:10 +0100 Subject: [PATCH 057/218] Fixed syntax of null test for #206 fix --- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 6 +++--- package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bower.json b/bower.json index 466bc075..1e846133 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.6.2", + "version": "2.6.3", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 10ab58c7..f049b577 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.6.2", + "version": "2.6.3", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index c0a21c6a..59deac41 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,7 +7,7 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.6.2 + * Version: 2.6.3 * Date: 30th May 2014 */ @@ -437,7 +437,7 @@ if(f) { // What generated the key press? if(typeof pageFocus !== 'undefined') { - if(typeof pageFocus !== 'null' && pageFocus.nodeName.toUpperCase() !== "BODY") { + if(pageFocus !== null && pageFocus.nodeName.toUpperCase() !== "BODY") { ignoreKey = true; } } else { @@ -479,7 +479,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.6.2", + script: "2.6.3", needFlash: "2.6.0", flash: "unknown" }, diff --git a/package.json b/package.json index 5aed5dd0..3dc487e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.6.2", + "version": "2.6.3", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From b2389b0de13cd7cc5105f284f224401e4aafc33d Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Sun, 8 Jun 2014 21:12:22 +0100 Subject: [PATCH 058/218] New Feature: Added useStateClassSkin option etc to enable ARIA skins --- jquery.jplayer/jquery.jplayer.js | 92 ++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 15 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 298b132f..34a6e810 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -524,6 +524,14 @@ gui: ".jp-gui", // The interface used with autohide feature. noSolution: ".jp-no-solution" // For error feedback when jPlayer cannot find a solution. }, + stateClass: { // Classes added to the cssSelectorAncestor to indicate the state. + playing: "jp-state-playing", + seeking: "jp-state-seeking", + muted: "jp-state-muted", + looped: "jp-state-looped", + fullScreen: "jp-state-full-screen" + }, + useStateClassSkin: false, // A state class skin relies on the state classes to change the visual appearance. The single control toggles the effect, for example: play then pause, mute then unmute. autoBlur: true, // GUI control handlers will drop focus after clicks. smoothPlayBar: false, // Smooths the play bar transitions, which affects clicks and short media with big changes per second. fullScreen: false, // Native Full Screen @@ -1625,6 +1633,23 @@ } else { this.status.paused = !playing; } + // Apply the state classes. (For the useStateClassSkin:true option) + if(playing) { + this.addStateClass('playing'); + } else { + this.removeStateClass('playing'); + } + if(!this.status.noFullWindow && this.options.fullWindow) { + this.addStateClass('fullScreen'); + } else { + this.removeStateClass('fullScreen'); + } + if(this.options.loop) { + this.addStateClass('looped'); + } else { + this.removeStateClass('looped'); + } + // Toggle the GUI element pairs. (For the useStateClassSkin:false option) if(this.css.jq.play.length && this.css.jq.pause.length) { if(playing) { this.css.jq.play.hide(); @@ -1703,11 +1728,13 @@ if(this.css.jq.seekBar.length) { this.css.jq.seekBar.addClass("jp-seeking-bg"); } + this.addStateClass('seeking'); }, _seeked: function() { if(this.css.jq.seekBar.length) { this.css.jq.seekBar.removeClass("jp-seeking-bg"); } + this.removeStateClass('seeking'); }, _resetGate: function() { this.html.audio.gate = false; @@ -1735,6 +1762,16 @@ }); return media; }, + addStateClass: function(state) { + if(this.ancestorJq.length) { + this.ancestorJq.addClass(this.options.stateClass[state]); + } + }, + removeStateClass: function(state) { + if(this.ancestorJq.length) { + this.ancestorJq.removeClass(this.options.stateClass[state]); + } + }, setMedia: function(media) { /* media[format] = String: URL of format. Must contain all of the supplied option's video or audio formats. @@ -1892,16 +1929,21 @@ } }, play: function(time) { - time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler - if(this.status.srcSet) { - this.focus(); - if(this.html.active) { - this._html_play(time); - } else if(this.flash.active) { - this._flash_play(time); - } + var guiAction = typeof time === "object"; // Flags GUI click events so we know this was not a direct command, but an action taken by the user on the GUI. + if(guiAction && this.options.useStateClassSkin && !this.status.paused) { + this.pause(time); // The time would be the click event, but passing it over so info is not lost. } else { - this._urlNotSetError("play"); + time = (typeof time === "number") ? time : NaN; // Remove jQuery event from click handler + if(this.status.srcSet) { + this.focus(); + if(this.html.active) { + this._html_play(time); + } else if(this.flash.active) { + this._flash_play(time); + } + } else { + this._urlNotSetError("play"); + } } }, videoPlay: function() { // Handles clicks on the play button over the video poster @@ -1995,8 +2037,13 @@ } }, mute: function(mute) { // mute is either: undefined (true), an event object (true) or a boolean (muted). - mute = mute === undefined ? true : !!mute; - this._muted(mute); + var guiAction = typeof mute === "object"; // Flags GUI click events so we know this was not a direct command, but an action taken by the user on the GUI. + if(guiAction && this.options.useStateClassSkin && this.options.muted) { + this._muted(false); + } else { + mute = mute === undefined ? true : !!mute; + this._muted(mute); + } }, unmute: function(unmute) { // unmute is either: undefined (true), an event object (true) or a boolean (!muted). unmute = unmute === undefined ? true : !!unmute; @@ -2006,6 +2053,11 @@ if(mute === undefined) { mute = this.options.muted; } + if(mute) { + this.addStateClass('muted'); + } else { + this.removeStateClass('muted'); + } if(this.css.jq.mute.length && this.css.jq.unmute.length) { if(this.status.noVolume) { this.css.jq.mute.hide(); @@ -2237,8 +2289,13 @@ } } }, - repeat: function() { // Handle clicks on the repeat button - this._loop(true); + repeat: function(event) { // Handle clicks on the repeat button + var guiAction = typeof event === "object"; // Flags GUI click events so we know this was not a direct command, but an action taken by the user on the GUI. + if(guiAction && this.options.useStateClassSkin && this.options.loop) { + this._loop(false); + } else { + this._loop(true); + } }, repeatOff: function() { // Handle clicks on the repeatOff button this._loop(false); @@ -2549,8 +2606,13 @@ } } }, - fullScreen: function() { - this._setOption("fullScreen", true); + fullScreen: function(event) { + var guiAction = typeof event === "object"; // Flags GUI click events so we know this was not a direct command, but an action taken by the user on the GUI. + if(guiAction && this.options.useStateClassSkin && this.options.fullScreen) { + this._setOption("fullScreen", false); + } else { + this._setOption("fullScreen", true); + } }, restoreScreen: function() { this._setOption("fullScreen", false); From 48c478deb386cd3a4ccbc01e46bcaa06811aaf13 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Sun, 8 Jun 2014 21:54:41 +0100 Subject: [PATCH 059/218] Cleaned up the Playlist add-on code now that jPlayer deals with the title --- add-on/jplayer.playlist.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index 60d48736..48e5cd0f 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -2,17 +2,17 @@ * Playlist Object for the jPlayer Plugin * http://www.jplayer.org * - * Copyright (c) 2009 - 2013 Happyworm Ltd + * Copyright (c) 2009 - 2014 Happyworm Ltd * Licensed under the MIT license. * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.3.0 - * Date: 20th April 2013 + * Version: 2.3.1 + * Date: 8th June 2014 * * Requires: * - jQuery 1.7.0+ - * - jPlayer 2.3.0+ + * - jPlayer 2.7.0+ */ /* Code verified using http://www.jshint.com/ */ @@ -53,7 +53,7 @@ this._initPlaylist(playlist); // Copies playlist to this.original. Then mirrors this.original to this.playlist. Creating two arrays, where the element pointers match. (Enables pointer comparison.) // Setup the css selectors for the extra interface items used by the playlist. - this.cssSelector.title = this.cssSelector.cssSelectorAncestor + " .jp-title"; // Note that the text is written to the decendant li node. + this.cssSelector.details = this.cssSelector.cssSelectorAncestor + " .jp-details"; // Note that jPlayer controls the text in the title element. this.cssSelector.playlist = this.cssSelector.cssSelectorAncestor + " .jp-playlist"; this.cssSelector.next = this.cssSelector.cssSelectorAncestor + " .jp-next"; this.cssSelector.previous = this.cssSelector.cssSelectorAncestor + " .jp-previous"; @@ -86,9 +86,9 @@ // Create a resize event handler to show the title in full screen mode. $(this.cssSelector.jPlayer).bind($.jPlayer.event.resize, function(event) { if(event.jPlayer.options.fullScreen) { - $(self.cssSelector.title).show(); + $(self.cssSelector.details).show(); } else { - $(self.cssSelector.title).hide(); + $(self.cssSelector.details).hide(); } }); @@ -116,7 +116,7 @@ // Put the title in its initial display state if(!this.options.fullScreen) { - $(this.cssSelector.title).hide(); + $(this.cssSelector.details).hide(); } // Remove the empty "; return listItem; From 05266019b6310544eee45b86133a3d1c19920d28 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Mon, 9 Jun 2014 18:26:21 +0100 Subject: [PATCH 064/218] Playlist - Fixed free DL link's tabindex to -1 to remove it from order. --- add-on/jplayer.playlist.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index 057f3eae..e5ea0ba2 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -261,7 +261,7 @@ } else { listItem += " | "; } - listItem += "" + property + ""; + listItem += "" + property + ""; } }); listItem += ")"; From 4fe69b22fc2f2fe195fe7423609d906f89ada94b Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Fri, 1 Aug 2014 16:59:26 +0100 Subject: [PATCH 065/218] Fixed HTML canPlayType test for MP3. Only use audio/mpeg. No codecs. --- bower.json | 2 +- jplayer.jquery.json | 2 +- jquery.jplayer/jquery.jplayer.js | 8 ++++---- package.json | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bower.json b/bower.json index 1e846133..94030381 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.6.3", + "version": "2.6.4", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index f049b577..7028450b 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.6.3", + "version": "2.6.4", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 59deac41..aff47731 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.6.3 - * Date: 30th May 2014 + * Version: 2.6.4 + * Date: 1st August 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -479,7 +479,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.6.3", + script: "2.6.4", needFlash: "2.6.0", flash: "unknown" }, @@ -702,7 +702,7 @@ // 'MPEG-4 support' : canPlayType('video/mp4; codecs="mp4v.20.8"') format: { // Static Object mp3: { - codec: 'audio/mpeg; codecs="mp3"', + codec: 'audio/mpeg', flashCanPlay: true, media: 'audio' }, diff --git a/package.json b/package.json index 3dc487e9..428e5f01 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.6.3", + "version": "2.6.4", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 4a90991bb68336663a85e98788fec83edeb5e723 Mon Sep 17 00:00:00 2001 From: Pascal Thormeier Date: Thu, 28 Aug 2014 22:34:25 +0200 Subject: [PATCH 066/218] Add composer.json --- composer.json | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..1b7d18e7 --- /dev/null +++ b/composer.json @@ -0,0 +1,21 @@ +{ + "name": "happyworm/jPlayer", + "type": "component", + "require": { + "robloach/component-installer": "*", + "components/jquery": ">=1.9" + }, + "extra": { + "component": { + "scripts": [ + "jquery.jplayer/jquery.jplayer.js" + ], + "files": [ + "jquery.jplayer/Jplayer.swf", + "add-on/*.js", + "popcorn/player/*.js", + "skin/*" + ] + } + } +} \ No newline at end of file From 0dfc8f507a13bf643c6998c7bb87288bd835cc8a Mon Sep 17 00:00:00 2001 From: Pascal Thormeier Date: Thu, 28 Aug 2014 22:53:07 +0200 Subject: [PATCH 067/218] Add support for delivered skins and update README --- README.md | 29 +++++++++++++++++++++++++++++ composer.json | 3 ++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e674e58b..8eb40179 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,35 @@ _(*) Optional counterpart formats to increase HTML5 cross-browser support._ * simple install using `bower install jplayer` * see for more information. +## Composer install + +Install jPlayer via composer by adding the following lines to your `composer.json` in your project: + + // ... + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/happyworm/jPlayer" + } + ] + // ... + "require": { + // ... + "happyworm/jPlayer": "2.*" + // ... + } + // ... + "config": { + "component-dir": "your/desired/asset/path" + }, + // ... + +Then execute the following: + + php composer.phar update + +Composer will now download all components and install the needed files into `your/desired/asset/path`, ready to use. + ## License [jPlayer](http://jplayer.org/) is licensed under the [MIT license](http://opensource.org/licenses/MIT). diff --git a/composer.json b/composer.json index 1b7d18e7..a8fb7238 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,8 @@ "jquery.jplayer/Jplayer.swf", "add-on/*.js", "popcorn/player/*.js", - "skin/*" + "skin/blue.monday/*", + "skin/pink.flag/*" ] } } From 94e3c7a838a6124c779e7bdb1efc16454a0383e9 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Mon, 1 Sep 2014 19:07:54 +0100 Subject: [PATCH 068/218] Updated versioning to 2.7.0 --- actionscript/Jplayer.as | 7 ++++--- .../happyworm/jPlayer/JplayerStatus.as | 4 ++-- add-on/jplayer.playlist.js | 4 ++-- jquery.jplayer/Jplayer.swf | Bin 14162 -> 14170 bytes jquery.jplayer/jquery.jplayer.js | 8 ++++---- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index c621aace..7af76180 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.6.0 - * Date: 2nd April 2014 + * Version: 2.7.0 + * Date: 1st September 2014 * * FlashVars expected: (AS3 property of: loaderInfo.parameters) * id: (URL Encoded: String) Id of jPlayer instance @@ -16,7 +16,8 @@ * muted: (Boolean in a String) Sets the initial muted state * jQuery: (URL Encoded: String) Sets the jQuery var name. Used with: someVar = jQuery.noConflict(true); The someVar name must contain jQuery in it. * - * Compiled using: Adobe Flex Compiler (mxmlc) Version 4.5.1 build 21328 + * Compiled using: Adobe Flex Compiler (mxmlc) Version 4.6 + * mxmlc Jplayer.as -static-link-runtime-shared-libraries=true */ package { diff --git a/actionscript/happyworm/jPlayer/JplayerStatus.as b/actionscript/happyworm/jPlayer/JplayerStatus.as index 909816a7..6fc20678 100644 --- a/actionscript/happyworm/jPlayer/JplayerStatus.as +++ b/actionscript/happyworm/jPlayer/JplayerStatus.as @@ -7,13 +7,13 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Date: 2nd April 2014 + * Date: 1st September 2014 */ package happyworm.jPlayer { public class JplayerStatus { - public static const VERSION:String = "2.6.0"; // The version of the Flash jPlayer entity. + public static const VERSION:String = "2.7.0"; // The version of the Flash jPlayer entity. public var volume:Number = 0.5; // Not affected by reset() public var muted:Boolean = false; // Not affected by reset() diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index e5ea0ba2..4609f66d 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -7,8 +7,8 @@ * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.3.4 - * Date: 9th June 2014 + * Version: 2.4.0 + * Date: 1st September 2014 * * Requires: * - jQuery 1.7.0+ diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index 3012248067e63a1b0a9da3d2185d271de1fb8188..103a729071893d9d6e94d583103d2f0cccc0ebb4 100644 GIT binary patch literal 14170 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 z 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 T>B;x}&)h$EU(kA}RDS;-56>)h literal 14162 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 Uf>`J>z8Cw{RlfqfFUgPp2hU0Sp8x;= diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 479bdb3a..779d7f3c 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.6.4 - * Date: 1st August 2014 + * Version: 2.7.0 + * Date: 1st September 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -479,8 +479,8 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.6.4", - needFlash: "2.6.0", + script: "2.7.0", + needFlash: "2.7.0", flash: "unknown" }, options: { // Instanced in $.jPlayer() constructor From e83d1dd92ceba41215fce41583d32a535a477a40 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Mon, 1 Sep 2014 19:13:59 +0100 Subject: [PATCH 069/218] Updated popcorn player plugin versioning and mp3 codec fix. --- popcorn/player/popcorn.jplayer.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/popcorn/player/popcorn.jplayer.js b/popcorn/player/popcorn.jplayer.js index 154e1909..31fead47 100644 --- a/popcorn/player/popcorn.jplayer.js +++ b/popcorn/player/popcorn.jplayer.js @@ -7,11 +7,11 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 1.1.3 - * Date: 2nd April 2014 + * Version: 1.1.4 + * Date: 1st September 2014 * * For Popcorn Version: 1.3 - * For jPlayer Version: 2.6.0 + * For jPlayer Version: 2.7.0 * Requires: jQuery 1.7+ * Note: jQuery dependancy cannot be removed since jPlayer 2 is a jQuery plugin. Use of jQuery will be kept to a minimum. */ @@ -22,16 +22,16 @@ (function(Popcorn) { - var JQUERY_SCRIPT = '//code.jquery.com/jquery-1.11.0.min.js', // Used if jQuery not already present. - JPLAYER_SCRIPT = '//www.jplayer.org/2.6.0/js/jquery.jplayer.min.js', // Used if jPlayer not already present. - JPLAYER_SWFPATH = '//www.jplayer.org/2.6.0/js/Jplayer.swf', // Used if not specified in jPlayer options via SRC Object. + var JQUERY_SCRIPT = '//code.jquery.com/jquery-1.11.1.min.js', // Used if jQuery not already present. + JPLAYER_SCRIPT = '//www.jplayer.org/2.7.0/js/jquery.jplayer.min.js', // Used if jPlayer not already present. + JPLAYER_SWFPATH = '//www.jplayer.org/2.7.0/js/Jplayer.swf', // Used if not specified in jPlayer options via SRC Object. SOLUTION = 'html,flash', // The default solution option. DEBUG = false, // Decided to leave the debugging option and console output in for the time being. Overhead is trivial. jQueryDownloading = false, // Flag to stop multiple instances from each pulling in jQuery, thus corrupting it. jPlayerDownloading = false, // Flag to stop multiple instances from each pulling in jPlayer, thus corrupting it. format = { // Duplicate of jPlayer 2.5.0 object, to avoid always requiring jQuery and jPlayer to be loaded before performing the _canPlayType() test. mp3: { - codec: 'audio/mpeg; codecs="mp3"', + codec: 'audio/mpeg;', flashCanPlay: true, media: 'audio' }, From 05cb6145eaabe6dc01a2c312fd5815875bc67eae Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Mon, 1 Sep 2014 19:16:01 +0100 Subject: [PATCH 070/218] Updated package file versioning --- bower.json | 2 +- jplayer.jquery.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bower.json b/bower.json index 94030381..a4ed80cd 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.6.4", + "version": "2.7.0", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index 7028450b..a729d14b 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.6.4", + "version": "2.7.0", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/package.json b/package.json index 428e5f01..9c874398 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.6.4", + "version": "2.7.0", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From b2c841fb72edad738082cd07ec8b1b9d116e1b24 Mon Sep 17 00:00:00 2001 From: smidgen Date: Fri, 5 Sep 2014 16:59:02 -0400 Subject: [PATCH 071/218] Browser-compatibility fix for data URI scheme. Since MSIE cuts off URL's validated in this way at 5120 bytes, data URI's should not be qualified this way. This bugfix allows you to use base64-encoded data URI's for audio data. --- jquery.jplayer/jquery.jplayer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 779d7f3c..dcd94c98 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -1756,7 +1756,7 @@ _absoluteMediaUrls: function(media) { var self = this; $.each(media, function(type, url) { - if(url && self.format[type]) { + if(url && self.format[type] && url.substr(0, 5) != 'data:') { media[type] = self._qualifyURL(url); } }); From f2c9f81545f81af80eb9338e8b3fb5ea130cdf62 Mon Sep 17 00:00:00 2001 From: smidgen Date: Fri, 12 Sep 2014 14:51:01 -0400 Subject: [PATCH 072/218] Bugfix for Chrome 37 As of Chrome version 37, the Android bugfix appears to be no longer needed, and in fact breaks jPlayer. This is the fix. --- jquery.jplayer/jquery.jplayer.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index dcd94c98..6dee8edd 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -243,7 +243,16 @@ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) || []; - return { browser: match[1] || "", version: match[2] || "0" }; + var oRet = { browser: match[1] || "", version: match[2] || "0" }; + + var rchrome = /(chrome)[ \/]([\w.]+)/; + var matchChrome = rchrome.exec(ua) || []; + + if (matchChrome[1]) { + oRet.chromeVersion = matchChrome[2]; + } + + return oRet; }; // Platform sniffer for detecting mobile devices @@ -277,6 +286,9 @@ if ( browserMatch.browser ) { $.jPlayer.browser[ browserMatch.browser ] = true; $.jPlayer.browser.version = browserMatch.version; + if (typeof(browserMatch.chromeVersion) != 'undefined') { + $.jPlayer.browser.chromeVersion = browserMatch.chromeVersion; + } } var platformMatch = $.jPlayer.uaPlatform(navigator.userAgent); if ( platformMatch.platform ) { @@ -1822,8 +1834,8 @@ self._html_setAudio(media); self.html.active = true; - // Setup the Android Fix - Only for HTML audio. - if($.jPlayer.platform.android) { + // Setup the Android Fix - Only for HTML audio. And it's not needed not for Chrome 37+. + if ( $.jPlayer.platform.android && !(typeof($.jPlayer.browser.chromeVersion) != 'undefined' && parseInt($.jPlayer.browser.chromeVersion) >= 37) ) { self.androidFix.setMedia = true; } } else { From 7ddf198cbacbe9ba5cb6287a4ddf8967f47e1a24 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Fri, 19 Sep 2014 16:34:58 +0100 Subject: [PATCH 073/218] Fixed legacy Android fix to work with current Android. --- jquery.jplayer/jquery.jplayer.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/jquery.jplayer/jquery.jplayer.js b/jquery.jplayer/jquery.jplayer.js index 779d7f3c..0aea04da 100644 --- a/jquery.jplayer/jquery.jplayer.js +++ b/jquery.jplayer/jquery.jplayer.js @@ -7,8 +7,8 @@ * http://opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.7.0 - * Date: 1st September 2014 + * Version: 2.7.1 + * Date: 19th September 2014 */ /* Code verified using http://www.jshint.com/ */ @@ -160,7 +160,7 @@ // "play", // jPlayer uses internally before bubbling. // "pause", // jPlayer uses internally before bubbling. "loadedmetadata", - "loadeddata", + // "loadeddata", // jPlayer uses internally before bubbling. // "waiting", // jPlayer uses internally before bubbling. // "playing", // jPlayer uses internally before bubbling. "canplay", @@ -479,7 +479,7 @@ $.jPlayer.prototype = { count: 0, // Static Variable: Change it via prototype. version: { // Static Object - script: "2.7.0", + script: "2.7.1", needFlash: "2.7.0", flash: "unknown" }, @@ -1295,6 +1295,13 @@ if(self.internal.cmdsIgnored && this.readyState > 0) { // Detect iOS executed the command self.internal.cmdsIgnored = false; } + self._getHtmlStatus(mediaElement); + self._updateInterface(); + self._trigger($.jPlayer.event.progress); + } + }, false); + mediaElement.addEventListener("loadeddata", function() { + if(entity.gate) { self.androidFix.setMedia = false; // Disable the fix after the first progress event. if(self.androidFix.play) { // Play Android audio - performing the fix. self.androidFix.play = false; @@ -1304,9 +1311,7 @@ self.androidFix.pause = false; self.pause(self.androidFix.time); } - self._getHtmlStatus(mediaElement); - self._updateInterface(); - self._trigger($.jPlayer.event.progress); + self._trigger($.jPlayer.event.loadeddata); } }, false); mediaElement.addEventListener("timeupdate", function() { From 5ebbd76b4e37145a20c28542b39ca7b8f2cac47a Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Fri, 19 Sep 2014 16:36:53 +0100 Subject: [PATCH 074/218] Updated package file versioning. --- bower.json | 2 +- jplayer.jquery.json | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bower.json b/bower.json index a4ed80cd..78d72c1f 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jPlayer", - "version": "2.7.0", + "version": "2.7.1", "main": [ "./jquery.jplayer/jquery.jplayer.js", "./skin/pink.flag/jplayer.pink.flag.css" diff --git a/jplayer.jquery.json b/jplayer.jquery.json index a729d14b..abcdd66d 100644 --- a/jplayer.jquery.json +++ b/jplayer.jquery.json @@ -11,7 +11,7 @@ "html5", "streaming" ], - "version": "2.7.0", + "version": "2.7.1", "author": { "name": "Mark J Panaghiston", "email": "markp@happyworm.com", diff --git a/package.json b/package.json index 9c874398..27fa35be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jplayer", - "version": "2.7.0", + "version": "2.7.1", "description": "The jQuery HTML5 Audio / Video Library", "homepage": "http://www.jplayer.org/", "keywords": [ From 4032921cf82adb771e959ebb1a1bca8bc200c8d8 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Wed, 24 Sep 2014 19:02:01 +0100 Subject: [PATCH 075/218] Code Clean: Removed Flash TraceOut.as class and code. --- actionscript/Jplayer.as | 19 +----- actionscript/happyworm/jPlayer/TraceOut.as | 64 --------------------- jquery.jplayer/Jplayer.swf | Bin 14170 -> 13693 bytes 3 files changed, 1 insertion(+), 82 deletions(-) delete mode 100644 actionscript/happyworm/jPlayer/TraceOut.as diff --git a/actionscript/Jplayer.as b/actionscript/Jplayer.as index 7af76180..93727a7e 100644 --- a/actionscript/Jplayer.as +++ b/actionscript/Jplayer.as @@ -75,9 +75,6 @@ package { private var txLog:TextField; private var debug:Boolean = false; // Set debug to false for release compile! - private var localAIRDebug:Boolean = false; // This is autodetermined by AIR app - leave false! - - private var traceOut:TraceOut; // This class was found to cause problems on OSX with Firefox and Safari where more than 8 instances of the SWF are on a page. public function Jplayer() { @@ -156,8 +153,6 @@ package { myMp3Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler); myMp4Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler); myRtmpPlayer.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler); - - traceOut = new TraceOut(); // Instance it only when in debug mode. See comment above at var declaration. } } @@ -510,12 +505,6 @@ package { } } - private function tracer(msg:String):void { - if(debug) { - traceOut.tracer(msg); - } - } - private function extractStatusData(data:JplayerStatus):Object { var myStatus:Object = { version: JplayerStatus.VERSION, @@ -604,22 +593,16 @@ package { jPlayerFlashEvent(new JplayerEvent(JplayerEvent.JPLAYER_CLICK, myMp4Player.myStatus, "click")) } } - // This event is never called. See comments in class constructor. + // Handlers for context menu private function menuSelectHandler_jPlayer(e:ContextMenuEvent):void { navigateToURL(new URLRequest("http://jplayer.org/"), "_blank"); } - // This event is never called. See comments in class constructor. private function menuSelectHandler_happyworm(e:ContextMenuEvent):void { navigateToURL(new URLRequest("http://happyworm.com/"), "_blank"); } private function log(t:String):void { if(debug) { txLog.text = t + "\n" + txLog.text; - localAIRDebug = traceOut.localAIRDebug(); - if(localAIRDebug) { - tracer(t); - } - if(ExternalInterface.available && !securityIssue) { ExternalInterface.call("console.log", t); } diff --git a/actionscript/happyworm/jPlayer/TraceOut.as b/actionscript/happyworm/jPlayer/TraceOut.as deleted file mode 100644 index a66cca5b..00000000 --- a/actionscript/happyworm/jPlayer/TraceOut.as +++ /dev/null @@ -1,64 +0,0 @@ -/* - * jPlayer Plugin for jQuery JavaScript Library - * http://www.jplayer.org - * - * Copyright (c) 2009 - 2014 Happyworm Ltd - * Licensed under the MIT license. - * http://opensource.org/licenses/MIT - * - * Author: Robert M. Hall - * Date: 7th August 2012 - */ - -// This class was found to cause problems on OSX with Firefox and Safari where more than 8 instances of the SWF are on a page. - -package happyworm.jPlayer -{ - import flash.net.LocalConnection; - import flash.events.StatusEvent; - import flash.system.Capabilities; - import flash.utils.getTimer; - - public class TraceOut - { - - private var outgoing_lc:LocalConnection = new LocalConnection (); - private var firstEvent:Boolean = true; - private var _localAIRDebug:Boolean = false; - - public function TraceOut() - { - outgoing_lc.addEventListener(StatusEvent.STATUS, lcListener); - outgoing_lc.send("_log_output","startLogging",""); - } - - private function lcListener(event:StatusEvent):void - { - // Must have this listener to avoid errors - if (event.level == "error") - { - _localAIRDebug = false; - } - else if(event.level =="status" && firstEvent==true) - { - firstEvent = false; - tracer("<< Successful Connection To Event Logger >>"); - tracer("DEBUG INFO: \n<"+Capabilities.serverString + ">\nFlash Player Version: " + Capabilities.version + "\n"); - _localAIRDebug = true; - } - } - - public function localAIRDebug():Boolean - { - return _localAIRDebug; - } - - public function tracer(msg:String):void - { - trace(msg); - var outMsg:String = "[" + getTimer() + "ms] " + msg; - outgoing_lc.send("_log_output","displayMsg",outMsg); - - } - } -} diff --git a/jquery.jplayer/Jplayer.swf b/jquery.jplayer/Jplayer.swf index 103a729071893d9d6e94d583103d2f0cccc0ebb4..5862266538a37bda02b72bba03bbaba6d8c8878a 100644 GIT binary patch literal 13693 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 literal 14170 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 z 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 T>B;x}&)h$EU(kA}RDS;-56>)h From 564edf4aea312d15e31087e71fbe468bfb6e4cf5 Mon Sep 17 00:00:00 2001 From: Afterster Date: Thu, 12 Dec 2013 18:53:27 +0100 Subject: [PATCH 076/218] Return good ratio in Flash players when file loaded but no total length --- actionscript/happyworm/jPlayer/JplayerMp3.as | 2 ++ actionscript/happyworm/jPlayer/JplayerMp4.as | 2 ++ actionscript/happyworm/jPlayer/JplayerRtmp.as | 7 ++++--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/actionscript/happyworm/jPlayer/JplayerMp3.as b/actionscript/happyworm/jPlayer/JplayerMp3.as index 1e6cf162..57a02781 100644 --- a/actionscript/happyworm/jPlayer/JplayerMp3.as +++ b/actionscript/happyworm/jPlayer/JplayerMp3.as @@ -337,6 +337,8 @@ package happyworm.jPlayer { public function getLoadRatio():Number { if((myStatus.isLoading || myStatus.isLoaded) && mySound.bytesTotal > 0) { return mySound.bytesLoaded / mySound.bytesTotal; + } else if (myStatus.isLoaded && mySound.bytesLoaded > 0) { + return 1; } else { return 0; } diff --git a/actionscript/happyworm/jPlayer/JplayerMp4.as b/actionscript/happyworm/jPlayer/JplayerMp4.as index 63bcfb66..b293dfaa 100644 --- a/actionscript/happyworm/jPlayer/JplayerMp4.as +++ b/actionscript/happyworm/jPlayer/JplayerMp4.as @@ -343,6 +343,8 @@ package happyworm.jPlayer { public function getLoadRatio():Number { if((myStatus.isLoading || myStatus.isLoaded) && myStream.bytesTotal > 0) { return myStream.bytesLoaded / myStream.bytesTotal; + } else if (myStatus.isLoaded && myStream.bytesLoaded > 0) { + return 1; } else { return 0; } diff --git a/actionscript/happyworm/jPlayer/JplayerRtmp.as b/actionscript/happyworm/jPlayer/JplayerRtmp.as index 1f8505aa..ed4b1031 100644 --- a/actionscript/happyworm/jPlayer/JplayerRtmp.as +++ b/actionscript/happyworm/jPlayer/JplayerRtmp.as @@ -871,10 +871,11 @@ package happyworm.jPlayer return 1; /*trace("LoadRatio:"+myStream.bytesLoaded, myStream.bytesTotal); if((myStatus.isLoading || myStatus.isLoaded) && myStream.bytesTotal > 0) { - - return myStream.bytesLoaded / myStream.bytesTotal; + return myStream.bytesLoaded / myStream.bytesTotal; + } else if (myStatus.isLoaded && myStream.bytesLoaded > 0) { + return 1; } else { - return 0; + return 0; } */ From 1e4adf6daa5eff33458ff53c122b3a0bc5d2ed51 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 14 Oct 2014 19:35:19 +0100 Subject: [PATCH 077/218] Moved existing files into new repo structure. --- {jquery.jplayer => js/jplayer}/Jplayer.swf | Bin {actionscript => src/actionscript}/Jplayer.as | 0 {actionscript => src/actionscript}/Jplayer.fla | Bin .../happyworm/jPlayer/ConnectManager.as | 0 .../actionscript}/happyworm/jPlayer/JplayerEvent.as | 0 .../actionscript}/happyworm/jPlayer/JplayerMp3.as | 0 .../actionscript}/happyworm/jPlayer/JplayerMp4.as | 0 .../actionscript}/happyworm/jPlayer/JplayerRtmp.as | 0 .../happyworm/jPlayer/JplayerStatus.as | 0 {add-on => src/javascript}/jplayer.playlist.js | 0 .../javascript}/jquery.jplayer.inspector.js | 0 .../javascript}/jquery.jplayer.js | 0 .../player => src/javascript}/popcorn.jplayer.js | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename {jquery.jplayer => js/jplayer}/Jplayer.swf (100%) rename {actionscript => src/actionscript}/Jplayer.as (100%) rename {actionscript => src/actionscript}/Jplayer.fla (100%) rename {actionscript => src/actionscript}/happyworm/jPlayer/ConnectManager.as (100%) rename {actionscript => src/actionscript}/happyworm/jPlayer/JplayerEvent.as (100%) rename {actionscript => src/actionscript}/happyworm/jPlayer/JplayerMp3.as (100%) rename {actionscript => src/actionscript}/happyworm/jPlayer/JplayerMp4.as (100%) rename {actionscript => src/actionscript}/happyworm/jPlayer/JplayerRtmp.as (100%) rename {actionscript => src/actionscript}/happyworm/jPlayer/JplayerStatus.as (100%) rename {add-on => src/javascript}/jplayer.playlist.js (100%) rename {add-on => src/javascript}/jquery.jplayer.inspector.js (100%) rename {jquery.jplayer => src/javascript}/jquery.jplayer.js (100%) rename {popcorn/player => src/javascript}/popcorn.jplayer.js (100%) diff --git a/jquery.jplayer/Jplayer.swf b/js/jplayer/Jplayer.swf similarity index 100% rename from jquery.jplayer/Jplayer.swf rename to js/jplayer/Jplayer.swf diff --git a/actionscript/Jplayer.as b/src/actionscript/Jplayer.as similarity index 100% rename from actionscript/Jplayer.as rename to src/actionscript/Jplayer.as diff --git a/actionscript/Jplayer.fla b/src/actionscript/Jplayer.fla similarity index 100% rename from actionscript/Jplayer.fla rename to src/actionscript/Jplayer.fla diff --git a/actionscript/happyworm/jPlayer/ConnectManager.as b/src/actionscript/happyworm/jPlayer/ConnectManager.as similarity index 100% rename from actionscript/happyworm/jPlayer/ConnectManager.as rename to src/actionscript/happyworm/jPlayer/ConnectManager.as diff --git a/actionscript/happyworm/jPlayer/JplayerEvent.as b/src/actionscript/happyworm/jPlayer/JplayerEvent.as similarity index 100% rename from actionscript/happyworm/jPlayer/JplayerEvent.as rename to src/actionscript/happyworm/jPlayer/JplayerEvent.as diff --git a/actionscript/happyworm/jPlayer/JplayerMp3.as b/src/actionscript/happyworm/jPlayer/JplayerMp3.as similarity index 100% rename from actionscript/happyworm/jPlayer/JplayerMp3.as rename to src/actionscript/happyworm/jPlayer/JplayerMp3.as diff --git a/actionscript/happyworm/jPlayer/JplayerMp4.as b/src/actionscript/happyworm/jPlayer/JplayerMp4.as similarity index 100% rename from actionscript/happyworm/jPlayer/JplayerMp4.as rename to src/actionscript/happyworm/jPlayer/JplayerMp4.as diff --git a/actionscript/happyworm/jPlayer/JplayerRtmp.as b/src/actionscript/happyworm/jPlayer/JplayerRtmp.as similarity index 100% rename from actionscript/happyworm/jPlayer/JplayerRtmp.as rename to src/actionscript/happyworm/jPlayer/JplayerRtmp.as diff --git a/actionscript/happyworm/jPlayer/JplayerStatus.as b/src/actionscript/happyworm/jPlayer/JplayerStatus.as similarity index 100% rename from actionscript/happyworm/jPlayer/JplayerStatus.as rename to src/actionscript/happyworm/jPlayer/JplayerStatus.as diff --git a/add-on/jplayer.playlist.js b/src/javascript/jplayer.playlist.js similarity index 100% rename from add-on/jplayer.playlist.js rename to src/javascript/jplayer.playlist.js diff --git a/add-on/jquery.jplayer.inspector.js b/src/javascript/jquery.jplayer.inspector.js similarity index 100% rename from add-on/jquery.jplayer.inspector.js rename to src/javascript/jquery.jplayer.inspector.js diff --git a/jquery.jplayer/jquery.jplayer.js b/src/javascript/jquery.jplayer.js similarity index 100% rename from jquery.jplayer/jquery.jplayer.js rename to src/javascript/jquery.jplayer.js diff --git a/popcorn/player/popcorn.jplayer.js b/src/javascript/popcorn.jplayer.js similarity index 100% rename from popcorn/player/popcorn.jplayer.js rename to src/javascript/popcorn.jplayer.js From ee1c24f6178f0747609461e7cb928927f3b534cd Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Tue, 14 Oct 2014 20:27:20 +0100 Subject: [PATCH 078/218] Added any remote libraries to the lib folder. --- lib/circle.player.js | 243 +++ lib/jquery.grab.js | 201 +++ lib/jquery.transform2d.js | 551 +++++++ lib/mod.csstransforms.min.js | 2 + lib/popcorn.ie8.js | 450 ++++++ lib/popcorn.js | 2690 ++++++++++++++++++++++++++++++++++ lib/popcorn.player.js | 437 ++++++ lib/popcorn.subtitle.js | 143 ++ 8 files changed, 4717 insertions(+) create mode 100644 lib/circle.player.js create mode 100644 lib/jquery.grab.js create mode 100644 lib/jquery.transform2d.js create mode 100644 lib/mod.csstransforms.min.js create mode 100644 lib/popcorn.ie8.js create mode 100644 lib/popcorn.js create mode 100644 lib/popcorn.player.js create mode 100644 lib/popcorn.subtitle.js diff --git a/lib/circle.player.js b/lib/circle.player.js new file mode 100644 index 00000000..c19b0b87 --- /dev/null +++ b/lib/circle.player.js @@ -0,0 +1,243 @@ +/* + * CirclePlayer for the jPlayer Plugin (jQuery) + * http://www.jplayer.org + * + * Copyright (c) 2009 - 2012 Happyworm Ltd + * Dual licensed under the MIT and GPL licenses. + * - http://www.opensource.org/licenses/mit-license.php + * - http://www.gnu.org/copyleft/gpl.html + * + * Version: 1.0.1 (jPlayer 2.1.0+) + * Date: 30th May 2011 + * + * Author: Mark J Panaghiston @thepag + * + * CirclePlayer prototype developed by: + * Mark Boas @maboa + * Silvia Benvenuti @aulentina + * Jussi Kalliokoski @quinirill + * + * Inspired by : + * Neway @imneway http://imneway.net/ http://forrst.com/posts/Untitled-CPt + * and + * Liam McKay @liammckay http://dribbble.com/shots/50882-Purple-Play-Pause + * + * Standing on the shoulders of : + * John Resig @jresig + * Mark Panaghiston @thepag + * Louis-Rémi Babé @Louis_Remi + */ + + +var CirclePlayer = function(jPlayerSelector, media, options) { + var self = this, + + defaults = { + // solution: "flash, html", // For testing Flash with CSS3 + supplied: "m4a, oga", + // Android 2.3 corrupts media element if preload:"none" is used. + // preload: "none", // No point preloading metadata since no times are displayed. It helps keep the buffer state correct too. + cssSelectorAncestor: "#cp_container_1", + cssSelector: { + play: ".cp-play", + pause: ".cp-pause" + } + }, + + cssSelector = { + bufferHolder: ".cp-buffer-holder", + buffer1: ".cp-buffer-1", + buffer2: ".cp-buffer-2", + progressHolder: ".cp-progress-holder", + progress1: ".cp-progress-1", + progress2: ".cp-progress-2", + circleControl: ".cp-circle-control" + }; + + this.cssClass = { + gt50: "cp-gt50", + fallback: "cp-fallback" + }; + + this.spritePitch = 104; + this.spriteRatio = 0.24; // Number of steps / 100 + + this.player = $(jPlayerSelector); + this.media = $.extend({}, media); + this.options = $.extend(true, {}, defaults, options); // Deep copy + + this.cssTransforms = Modernizr.csstransforms; + this.audio = {}; + this.dragging = false; // Indicates if the progressbar is being 'dragged'. + + this.eventNamespace = ".CirclePlayer"; // So the events can easily be removed in destroy. + + this.jq = {}; + $.each(cssSelector, function(entity, cssSel) { + self.jq[entity] = $(self.options.cssSelectorAncestor + " " + cssSel); + }); + + this._initSolution(); + this._initPlayer(); +}; + +CirclePlayer.prototype = { + _createHtml: function() { + }, + _initPlayer: function() { + var self = this; + this.player.jPlayer(this.options); + + this.player.bind($.jPlayer.event.ready + this.eventNamespace, function(event) { + if(event.jPlayer.html.used && event.jPlayer.html.audio.available) { + self.audio = $(this).data("jPlayer").htmlElement.audio; + } + $(this).jPlayer("setMedia", self.media); + self._initCircleControl(); + }); + + this.player.bind($.jPlayer.event.play + this.eventNamespace, function(event) { + $(this).jPlayer("pauseOthers"); + }); + + // This event fired as play time increments + this.player.bind($.jPlayer.event.timeupdate + this.eventNamespace, function(event) { + if (!self.dragging) { + self._timeupdate(event.jPlayer.status.currentPercentAbsolute); + } + }); + + // This event fired as buffered time increments + this.player.bind($.jPlayer.event.progress + this.eventNamespace, function(event) { + var percent = 0; + if((typeof self.audio.buffered === "object") && (self.audio.buffered.length > 0)) { + if(self.audio.duration > 0) { + var bufferTime = 0; + for(var i = 0; i < self.audio.buffered.length; i++) { + bufferTime += self.audio.buffered.end(i) - self.audio.buffered.start(i); + // console.log(i + " | start = " + self.audio.buffered.start(i) + " | end = " + self.audio.buffered.end(i) + " | bufferTime = " + bufferTime + " | duration = " + self.audio.duration); + } + percent = 100 * bufferTime / self.audio.duration; + } // else the Metadata has not been read yet. + // console.log("percent = " + percent); + } else { // Fallback if buffered not supported + // percent = event.jPlayer.status.seekPercent; + percent = 0; // Cleans up the inital conditions on all browsers, since seekPercent defaults to 100 when object is undefined. + } + self._progress(percent); // Problem here at initial condition. Due to the Opera clause above of buffered.length > 0 above... Removing it means Opera's white buffer ring never shows like with polyfill. + // Firefox 4 does not always give the final progress event when buffered = 100% + }); + + this.player.bind($.jPlayer.event.ended + this.eventNamespace, function(event) { + self._resetSolution(); + }); + }, + _initSolution: function() { + if (this.cssTransforms) { + this.jq.progressHolder.show(); + this.jq.bufferHolder.show(); + } + else { + this.jq.progressHolder.addClass(this.cssClass.gt50).show(); + this.jq.progress1.addClass(this.cssClass.fallback); + this.jq.progress2.hide(); + this.jq.bufferHolder.hide(); + } + this._resetSolution(); + }, + _resetSolution: function() { + if (this.cssTransforms) { + this.jq.progressHolder.removeClass(this.cssClass.gt50); + this.jq.progress1.css({'transform': 'rotate(0deg)'}); + this.jq.progress2.css({'transform': 'rotate(0deg)'}).hide(); + } + else { + this.jq.progress1.css('background-position', '0 ' + this.spritePitch + 'px'); + } + }, + _initCircleControl: function() { + var self = this; + this.jq.circleControl.grab({ + onstart: function(){ + self.dragging = true; + }, onmove: function(event){ + var pc = self._getArcPercent(event.position.x, event.position.y); + self.player.jPlayer("playHead", pc).jPlayer("play"); + self._timeupdate(pc); + }, onfinish: function(event){ + self.dragging = false; + var pc = self._getArcPercent(event.position.x, event.position.y); + self.player.jPlayer("playHead", pc).jPlayer("play"); + } + }); + }, + _timeupdate: function(percent) { + var degs = percent * 3.6+"deg"; + + var spriteOffset = (Math.floor((Math.round(percent))*this.spriteRatio)-1)*-this.spritePitch; + + if (percent <= 50) { + if (this.cssTransforms) { + this.jq.progressHolder.removeClass(this.cssClass.gt50); + this.jq.progress1.css({'transform': 'rotate(' + degs + ')'}); + this.jq.progress2.hide(); + } else { // fall back + this.jq.progress1.css('background-position', '0 '+spriteOffset+'px'); + } + } else if (percent <= 100) { + if (this.cssTransforms) { + this.jq.progressHolder.addClass(this.cssClass.gt50); + this.jq.progress1.css({'transform': 'rotate(180deg)'}); + this.jq.progress2.css({'transform': 'rotate(' + degs + ')'}); + this.jq.progress2.show(); + } else { // fall back + this.jq.progress1.css('background-position', '0 '+spriteOffset+'px'); + } + } + }, + _progress: function(percent) { + var degs = percent * 3.6+"deg"; + + if (this.cssTransforms) { + if (percent <= 50) { + this.jq.bufferHolder.removeClass(this.cssClass.gt50); + this.jq.buffer1.css({'transform': 'rotate(' + degs + ')'}); + this.jq.buffer2.hide(); + } else if (percent <= 100) { + this.jq.bufferHolder.addClass(this.cssClass.gt50); + this.jq.buffer1.css({'transform': 'rotate(180deg)'}); + this.jq.buffer2.show(); + this.jq.buffer2.css({'transform': 'rotate(' + degs + ')'}); + } + } + }, + _getArcPercent: function(pageX, pageY) { + var offset = this.jq.circleControl.offset(), + x = pageX - offset.left - this.jq.circleControl.width()/2, + y = pageY - offset.top - this.jq.circleControl.height()/2, + theta = Math.atan2(y,x); + + if (theta > -1 * Math.PI && theta < -0.5 * Math.PI) { + theta = 2 * Math.PI + theta; + } + + // theta is now value between -0.5PI and 1.5PI + // ready to be normalized and applied + + return (theta + Math.PI / 2) / 2 * Math.PI * 10; + }, + setMedia: function(media) { + this.media = $.extend({}, media); + this.player.jPlayer("setMedia", this.media); + }, + play: function(time) { + this.player.jPlayer("play", time); + }, + pause: function(time) { + this.player.jPlayer("pause", time); + }, + destroy: function() { + this.player.unbind(this.eventNamespace); + this.player.jPlayer("destroy"); + } +}; diff --git a/lib/jquery.grab.js b/lib/jquery.grab.js new file mode 100644 index 00000000..d7318991 --- /dev/null +++ b/lib/jquery.grab.js @@ -0,0 +1,201 @@ +/* +jQuery grab +https://github.com/jussi-kalliokoski/jQuery.grab +Ported from Jin.js::gestures +https://github.com/jussi-kalliokoski/jin.js/ +Created by Jussi Kalliokoski +Licensed under MIT License. + +Includes fix for IE +*/ + + +(function($){ + var extend = $.extend, + mousedown = 'mousedown', + mousemove = 'mousemove', + mouseup = 'mouseup', + touchstart = 'touchstart', + touchmove = 'touchmove', + touchend = 'touchend', + touchcancel = 'touchcancel'; + + function unbind(elem, type, func){ + if (type.substr(0,5) !== 'touch'){ // A temporary fix for IE8 data passing problem in Jin. + return $(elem).unbind(type, func); + } + var fnc, i; + for (i=0; i1 ? val[1] : val[0]; + break; + + case _skew+"X": + curr[2] = Math.tan(toRadian(val)); + break; + + case _skew+"Y": + curr[1] = Math.tan(toRadian(val)); + break; + + case _matrix: + val = val.split(","); + curr[0] = val[0]; + curr[1] = val[1]; + curr[2] = val[2]; + curr[3] = val[3]; + curr[4] = parseInt(val[4], 10); + curr[5] = parseInt(val[5], 10); + break; + } + + // Matrix product (array in column-major order) + rslt[0] = prev[0] * curr[0] + prev[2] * curr[1]; + rslt[1] = prev[1] * curr[0] + prev[3] * curr[1]; + rslt[2] = prev[0] * curr[2] + prev[2] * curr[3]; + rslt[3] = prev[1] * curr[2] + prev[3] * curr[3]; + rslt[4] = prev[0] * curr[4] + prev[2] * curr[5] + prev[4]; + rslt[5] = prev[1] * curr[4] + prev[3] * curr[5] + prev[5]; + + prev = [rslt[0],rslt[1],rslt[2],rslt[3],rslt[4],rslt[5]]; + } + return rslt; +} + +// turns a matrix into its rotate, scale and skew components +// algorithm from http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp +function unmatrix(matrix) { + var + scaleX + , scaleY + , skew + , A = matrix[0] + , B = matrix[1] + , C = matrix[2] + , D = matrix[3] + ; + + // Make sure matrix is not singular + if ( A * D - B * C ) { + // step (3) + scaleX = Math.sqrt( A * A + B * B ); + A /= scaleX; + B /= scaleX; + // step (4) + skew = A * C + B * D; + C -= A * skew; + D -= B * skew; + // step (5) + scaleY = Math.sqrt( C * C + D * D ); + C /= scaleY; + D /= scaleY; + skew /= scaleY; + // step (6) + if ( A * D < B * C ) { + A = -A; + B = -B; + skew = -skew; + scaleX = -scaleX; + } + + // matrix is singular and cannot be interpolated + } else { + // In this case the elem shouldn't be rendered, hence scale == 0 + scaleX = scaleY = skew = 0; + } + + // The recomposition order is very important + // see http://hg.mozilla.org/mozilla-central/file/7cb3e9795d04/layout/style/nsStyleAnimation.cpp#l971 + return [ + [_translate, [+matrix[4], +matrix[5]]], + [_rotate, Math.atan2(B, A)], + [_skew + "X", Math.atan(skew)], + [_scale, [scaleX, scaleY]] + ]; +} + +// build the list of transform functions to interpolate +// use the algorithm described at http://dev.w3.org/csswg/css3-2d-transforms/#animation +function interpolationList( start, end ) { + var list = { + start: [], + end: [] + }, + i = -1, l, + currStart, currEnd, currType; + + // get rid of affine transform matrix + ( start == "none" || isAffine( start ) ) && ( start = "" ); + ( end == "none" || isAffine( end ) ) && ( end = "" ); + + // if end starts with the current computed style, this is a relative animation + // store computed style as the origin, remove it from start and end + if ( start && end && !end.indexOf("matrix") && toArray( start ).join() == toArray( end.split(")")[0] ).join() ) { + list.origin = start; + start = ""; + end = end.slice( end.indexOf(")") +1 ); + } + + if ( !start && !end ) { return; } + + // start or end are affine, or list of transform functions are identical + // => functions will be interpolated individually + if ( !start || !end || functionList(start) == functionList(end) ) { + + start && ( start = start.split(")") ) && ( l = start.length ); + end && ( end = end.split(")") ) && ( l = end.length ); + + while ( ++i < l-1 ) { + start[i] && ( currStart = start[i].split("(") ); + end[i] && ( currEnd = end[i].split("(") ); + currType = $.trim( ( currStart || currEnd )[0] ); + + append( list.start, parseFunction( currType, currStart ? currStart[1] : 0 ) ); + append( list.end, parseFunction( currType, currEnd ? currEnd[1] : 0 ) ); + } + + // otherwise, functions will be composed to a single matrix + } else { + list.start = unmatrix(matrix(start)); + list.end = unmatrix(matrix(end)) + } + + return list; +} + +function parseFunction( type, value ) { + var + // default value is 1 for scale, 0 otherwise + defaultValue = +(!type.indexOf(_scale)), + scaleX, + // remove X/Y from scaleX/Y & translateX/Y, not from skew + cat = type.replace( /e[XY]/, "e" ); + + switch ( type ) { + case _translate+"Y": + case _scale+"Y": + + value = [ + defaultValue, + value ? + parseFloat( value ): + defaultValue + ]; + break; + + case _translate+"X": + case _translate: + case _scale+"X": + scaleX = 1; + case _scale: + + value = value ? + ( value = value.split(",") ) && [ + parseFloat( value[0] ), + parseFloat( value.length>1 ? value[1] : type == _scale ? scaleX || value[0] : defaultValue+"" ) + ]: + [defaultValue, defaultValue]; + break; + + case _skew+"X": + case _skew+"Y": + case _rotate: + value = value ? toRadian( value ) : 0; + break; + + case _matrix: + return unmatrix( value ? toArray(value) : [1,0,0,1,0,0] ); + break; + } + + return [[ cat, value ]]; +} + +function isAffine( matrix ) { + return rAffine.test(matrix); +} + +function functionList( transform ) { + return transform.replace(/(?:\([^)]*\))|\s/g, ""); +} + +function append( arr1, arr2, value ) { + while ( value = arr2.shift() ) { + arr1.push( value ); + } +} + +// converts an angle string in any unit to a radian Float +function toRadian(value) { + return ~value.indexOf("deg") ? + parseInt(value,10) * (Math.PI * 2 / 360): + ~value.indexOf("grad") ? + parseInt(value,10) * (Math.PI/200): + parseFloat(value); +} + +// Converts "matrix(A,B,C,D,X,Y)" to [A,B,C,D,X,Y] +function toArray(matrix) { + // remove the unit of X and Y for Firefox + matrix = /([^,]*),([^,]*),([^,]*),([^,]*),([^,p]*)(?:px)?,([^)p]*)(?:px)?/.exec(matrix); + return [matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6]]; +} + +$.transform = { + centerOrigin: "margin" +}; + +})( jQuery, window, document, Math ); diff --git a/lib/mod.csstransforms.min.js b/lib/mod.csstransforms.min.js new file mode 100644 index 00000000..6386d5bf --- /dev/null +++ b/lib/mod.csstransforms.min.js @@ -0,0 +1,2 @@ +/* Modernizr custom build of 1.7pre: csstransforms */ +window.Modernizr=function(a,b,c){function G(){}function F(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1),d=(a+" "+p.join(c+" ")+c).split(" ");return!!E(d,b)}function E(a,b){for(var d in a)if(k[a[d]]!==c&&(!b||b(a[d],j)))return!0}function D(a,b){return(""+a).indexOf(b)!==-1}function C(a,b){return typeof a===b}function B(a,b){return A(o.join(a+";")+(b||""))}function A(a){k.cssText=a}var d="1.7pre",e={},f=!0,g=b.documentElement,h=b.head||b.getElementsByTagName("head")[0],i="modernizr",j=b.createElement(i),k=j.style,l=b.createElement("input"),m=":)",n=Object.prototype.toString,o=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),p="Webkit Moz O ms Khtml".split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v,w=function(a){var c=b.createElement("style"),d=b.createElement("div"),e;c.textContent=a+"{#modernizr{height:3px}}",h.appendChild(c),d.id="modernizr",g.appendChild(d),e=d.offsetHeight===3,c.parentNode.removeChild(c),d.parentNode.removeChild(d);return!!e},x=function(){function d(d,e){e=e||b.createElement(a[d]||"div");var f=(d="on"+d)in e;f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=C(e[d],"function"),C(e[d],c)||(e[d]=c),e.removeAttribute(d))),e=null;return f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),y=({}).hasOwnProperty,z;C(y,c)||C(y.call,c)?z=function(a,b){return b in a&&C(a.constructor.prototype[b],c)}:z=function(a,b){return y.call(a,b)},r.csstransforms=function(){return!!E(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])};for(var H in r)z(r,H)&&(v=H.toLowerCase(),e[v]=r[H](),u.push((e[v]?"":"no-")+v));e.input||G(),e.crosswindowmessaging=e.postmessage,e.historymanagement=e.history,e.addTest=function(a,b){a=a.toLowerCase();if(!e[a]){b=!!b(),g.className+=" "+(b?"":"no-")+a,e[a]=b;return e}},A(""),j=l=null,e._enableHTML5=f,e._version=d,g.className=g.className.replace(/\bno-js\b/,"")+" js "+u.join(" ");return e}(this,this.document) \ No newline at end of file diff --git a/lib/popcorn.ie8.js b/lib/popcorn.ie8.js new file mode 100644 index 00000000..c215e59a --- /dev/null +++ b/lib/popcorn.ie8.js @@ -0,0 +1,450 @@ +(function() { + + if ( !document.addEventListener && !document.removeEventListener && !document.dispatchEvent ) { + var events = {}; + + var addEventListener = function( eventName, callBack ) { + + eventName = ( eventName === "DOMContentLoaded" ) ? "readystatechange" : eventName; + + if ( Event[ eventName.toUpperCase() ] || eventName === "readystatechange" ) { + document.attachEvent( "on" + eventName, callBack ); + return; + } + + if ( !events[ eventName ] ) { + events[ eventName ] = { + events: [], + queue: [], + active: false + }; + } + + if ( events[ eventName ].active ) { + events[ eventName ].queue.push( callBack ); + } else { + events[ eventName ].events.push( callBack ); + } + }; + + var removeEventListener = function( eventName, callBack ) { + + eventName = ( eventName === "DOMContentLoaded" ) ? "readystatechange" : eventName; + + var i = 0, + listeners = events[ eventName ]; + + if ( Event[ eventName.toUpperCase() ] || eventName === "readystatechange" ) { + document.detachEvent( "on" + eventName, callBack ); + return; + } + + if ( !listeners ) { + return; + } + + for ( i = listeners.events.length - 1; i >= 0; i-- ) { + if ( callBack === listeners.events[ i ] ) { + delete listeners.events[ i ]; + } + } + + for ( i = listeners.queue.length - 1; i >= 0; i-- ) { + if ( callBack === listeners.queue[ i ] ) { + delete listeners.queue[ i ]; + } + } + }; + + var dispatchEvent = function( eventObject ) { + var evt, + self = this, + eventInterface, + listeners, + eventName = eventObject.type, + queuedListener; + + // A string was passed, create event object + if ( !eventName ) { + + eventName = eventObject; + eventInterface = Popcorn.events.getInterface( eventName ); + + if ( eventInterface ) { + + evt = document.createEvent( eventInterface ); + evt.initCustomEvent( eventName, true, true, window, 1 ); + } + } + + listeners = events[ eventName ]; + + if ( listeners ) { + listeners.active = true; + + for ( var i = 0; i < listeners.events.length; i++ ) { + if ( listeners.events[ i ] ) { + listeners.events[ i ].call( self, evt, self ); + } + } + + if ( listeners.queue.length ) { + while ( listeners.queue.length ) { + queuedListener = listeners.queue.shift(); + + if ( queuedListener ) { + listeners.events.push( queuedListener ); + } + } + } + + listeners.active = false; + + listeners.events.forEach(function( listener ) { + if ( !listener ) { + listeners.events.splice( listeners.events.indexOf( listener ), 1 ); + } + }); + + listeners.queue.forEach(function( listener ) { + if ( !listener ) { + listeners.queue.splice( listeners.queue.indexOf( listener ), 1 ); + } + }); + } + }; + + document.addEventListener = addEventListener; + document.removeEventListener = removeEventListener; + document.dispatchEvent = dispatchEvent; + + } + + if ( !Event.prototype.preventDefault ) { + Event.prototype.preventDefault = function() { + this.returnValue = false; + }; + } + if ( !Event.prototype.stopPropagation ) { + Event.prototype.stopPropagation = function() { + this.cancelBubble = true; + }; + } + + window.addEventListener = window.addEventListener || function( event, callBack ) { + + event = "on" + event; + + window.attachEvent( event, callBack ); + }; + + window.removeEventListener = window.removeEventListener || function( event, callBack ) { + + event = "on" + event; + + window.detachEvent( event, callBack ); + }; + + HTMLScriptElement.prototype.addEventListener = HTMLScriptElement.prototype.addEventListener || function( event, callBack ) { + + event = ( event === "load" ) ? "onreadystatechange" : "on" + event; + + if( event === "onreadystatechange" ){ + callBack.readyStateCheck = callBack.readyStateCheck || function( e ){ + + if( self.readyState === "loaded" ){ + callBack( e ); + } + }; + } + + this.attachEvent( event, ( callBack.readyStateCheck || callBack ) ); + }; + + HTMLScriptElement.prototype.removeEventListener = HTMLScriptElement.prototype.removeEventListener || function( event, callBack ) { + + event = ( event === "load" ) ? "onreadystatechange" : "on" + event; + + this.detachEvent( event, ( callBack.readyStateCheck || callBack ) ); + }; + + document.createEvent = document.createEvent || function ( type ) { + + return { + type : null, + target : null, + currentTarget : null, + cancelable : false, + detail: false, + bubbles : false, + initEvent : function (type, bubbles, cancelable) { + this.type = type; + }, + initCustomEvent: function(type, bubbles, cancelable, detail) { + this.type = type; + this.detail = detail; + }, + stopPropagation : function () {}, + stopImmediatePropagation : function () {} + } + }; + + Array.prototype.forEach = Array.prototype.forEach || function( fn, context ) { + + var obj = this, + hasOwn = Object.prototype.hasOwnProperty; + + if ( !obj || !fn ) { + return {}; + } + + context = context || this; + + var key, len; + + for ( key in obj ) { + if ( hasOwn.call( obj, key ) ) { + fn.call( context, obj[ key ], key, obj ); + } + } + return obj; + }; + + // Production steps of ECMA-262, Edition 5, 15.4.4.19 + // Reference: http://es5.github.com/#x15.4.4.19 + if ( !Array.prototype.map ) { + + Array.prototype.map = function( callback, thisArg ) { + + var T, A, k; + + if ( this == null ) { + throw new TypeError( "this is null or not defined" ); + } + + // 1. Let O be the result of calling ToObject passing the |this| value as the argument. + var O = Object( this ); + + // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + + // 4. If IsCallable(callback) is false, throw a TypeError exception. + // See: http://es5.github.com/#x9.11 + if ( {}.toString.call( callback ) != "[object Function]" ) { + throw new TypeError( callback + " is not a function" ); + } + + // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. + if ( thisArg ) { + T = thisArg; + } + + // 6. Let A be a new array created as if by the expression new Array(len) where Array is + // the standard built-in constructor with that name and len is the value of len. + A = new Array( len ); + + // 7. Let k be 0 + k = 0; + + // 8. Repeat, while k < len + while( k < len ) { + + var kValue, mappedValue; + + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + if ( k in O ) { + + // i. Let kValue be the result of calling the Get internal method of O with argument Pk. + kValue = O[ k ]; + + // ii. Let mappedValue be the result of calling the Call internal method of callback + // with T as the this value and argument list containing kValue, k, and O. + mappedValue = callback.call( T, kValue, k, O ); + + // iii. Call the DefineOwnProperty internal method of A with arguments + // Pk, Property Descriptor {Value: mappedValue, Writable: true, Enumerable: true, Configurable: true}, + // and false. + + // In browsers that support Object.defineProperty, use the following: + // Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true }); + + // For best browser support, use the following: + A[ k ] = mappedValue; + } + // d. Increase k by 1. + k++; + } + + // 9. return A + return A; + }; + } + + if ( !Array.prototype.indexOf ) { + + Array.prototype.indexOf = function ( searchElement /*, fromIndex */ ) { + + if ( this == null) { + + throw new TypeError(); + } + + var t = Object( this ), + len = t.length >>> 0; + + if ( len === 0 ) { + + return -1; + } + + var n = 0; + + if ( arguments.length > 0 ) { + + n = Number( arguments[ 1 ] ); + + if ( n != n ) { // shortcut for verifying if it's NaN + + n = 0; + } else if ( n != 0 && n != Infinity && n != -Infinity ) { + + n = ( n > 0 || -1 ) * Math.floor( Math.abs( n ) ); + } + } + + if ( n >= len ) { + return -1; + } + + var k = n >= 0 ? n : Math.max( len - Math.abs( n ), 0 ); + + for (; k < len; k++ ) { + + if ( k in t && t[ k ] === searchElement ) { + + return k; + } + } + + return -1; + } + } + + if ( typeof String.prototype.trim !== "function" ) { + + String.prototype.trim = function() { + return this.replace(/^\s+|\s+$/g, ""); + }; + } + + // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys + if (!Object.keys) { + Object.keys = (function () { + 'use strict'; + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), + dontEnums = [ + 'toString', + 'toLocaleString', + 'valueOf', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'constructor' + ], + dontEnumsLength = dontEnums.length; + + return function (obj) { + if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { + throw new TypeError('Object.keys called on non-object'); + } + + var result = [], prop, i; + + for (prop in obj) { + if (hasOwnProperty.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (i = 0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } + } + return result; + }; + }()); + } + + if ( !Object.defineProperties ) { + Object.defineProperties = function(obj, properties) { + function convertToDescriptor(desc) { + function hasProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + function isCallable(v) { + // NB: modify as necessary if other values than functions are callable. + return typeof v === "function"; + } + + if (typeof desc !== "object" || desc === null) + throw new TypeError("bad desc"); + + var d = {}; + + if (hasProperty(desc, "enumerable")) + d.enumerable = !!obj.enumerable; + if (hasProperty(desc, "configurable")) + d.configurable = !!desc.configurable; + if (hasProperty(desc, "value")) + d.value = obj.value; + if (hasProperty(desc, "writable")) + d.writable = !!desc.writable; + if ( hasProperty(desc, "get") ) { + var g = desc.get; + + if (!isCallable(g) && g !== "undefined") + throw new TypeError("bad get"); + d.get = g; + } + if ( hasProperty(desc, "set") ) { + var s = desc.set; + if (!isCallable(s) && s !== "undefined") + throw new TypeError("bad set"); + d.set = s; + } + + if (("get" in d || "set" in d) && ("value" in d || "writable" in d)) + throw new TypeError("identity-confused descriptor"); + + return d; + } + + if (typeof obj !== "object" || obj === null) + throw new TypeError("bad obj"); + + properties = Object(properties); + + var keys = Object.keys(properties); + var descs = []; + + for (var i = 0; i < keys.length; i++) + descs.push([keys[i], convertToDescriptor(properties[keys[i]])]); + + for (var i = 0; i < descs.length; i++) + Object.defineProperty(obj, descs[i][0], descs[i][1]); + + return obj; + }; + } + +})(); diff --git a/lib/popcorn.js b/lib/popcorn.js new file mode 100644 index 00000000..0f9eec69 --- /dev/null +++ b/lib/popcorn.js @@ -0,0 +1,2690 @@ +(function(global, document) { + + // Popcorn.js does not support archaic browsers + if ( !document.addEventListener ) { + global.Popcorn = { + isSupported: false + }; + + var methods = ( "byId forEach extend effects error guid sizeOf isArray nop position disable enable destroy" + + "addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " + + "timeUpdate plugin removePlugin compose effect xhr getJSONP getScript" ).split(/\s+/); + + while ( methods.length ) { + global.Popcorn[ methods.shift() ] = function() {}; + } + return; + } + + var + + AP = Array.prototype, + OP = Object.prototype, + + forEach = AP.forEach, + slice = AP.slice, + hasOwn = OP.hasOwnProperty, + toString = OP.toString, + + // Copy global Popcorn (may not exist) + _Popcorn = global.Popcorn, + + // Ready fn cache + readyStack = [], + readyBound = false, + readyFired = false, + + // Non-public internal data object + internal = { + events: { + hash: {}, + apis: {} + } + }, + + // Non-public `requestAnimFrame` + // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + requestAnimFrame = (function(){ + return global.requestAnimationFrame || + global.webkitRequestAnimationFrame || + global.mozRequestAnimationFrame || + global.oRequestAnimationFrame || + global.msRequestAnimationFrame || + function( callback, element ) { + global.setTimeout( callback, 16 ); + }; + }()), + + // Non-public `getKeys`, return an object's keys as an array + getKeys = function( obj ) { + return Object.keys ? Object.keys( obj ) : (function( obj ) { + var item, + list = []; + + for ( item in obj ) { + if ( hasOwn.call( obj, item ) ) { + list.push( item ); + } + } + return list; + })( obj ); + }, + + Abstract = { + // [[Put]] props from dictionary onto |this| + // MUST BE CALLED FROM WITHIN A CONSTRUCTOR: + // Abstract.put.call( this, dictionary ); + put: function( dictionary ) { + // For each own property of src, let key be the property key + // and desc be the property descriptor of the property. + for ( var key in dictionary ) { + if ( dictionary.hasOwnProperty( key ) ) { + this[ key ] = dictionary[ key ]; + } + } + } + }, + + + // Declare constructor + // Returns an instance object. + Popcorn = function( entity, options ) { + // Return new Popcorn object + return new Popcorn.p.init( entity, options || null ); + }; + + // Popcorn API version, automatically inserted via build system. + Popcorn.version = "@VERSION"; + + // Boolean flag allowing a client to determine if Popcorn can be supported + Popcorn.isSupported = true; + + // Instance caching + Popcorn.instances = []; + + // Declare a shortcut (Popcorn.p) to and a definition of + // the new prototype for our Popcorn constructor + Popcorn.p = Popcorn.prototype = { + + init: function( entity, options ) { + + var matches, nodeName, + self = this; + + // Supports Popcorn(function () { /../ }) + // Originally proposed by Daniel Brooks + + if ( typeof entity === "function" ) { + + // If document ready has already fired + if ( document.readyState === "complete" ) { + + entity( document, Popcorn ); + + return; + } + // Add `entity` fn to ready stack + readyStack.push( entity ); + + // This process should happen once per page load + if ( !readyBound ) { + + // set readyBound flag + readyBound = true; + + var DOMContentLoaded = function() { + + readyFired = true; + + // Remove global DOM ready listener + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // Execute all ready function in the stack + for ( var i = 0, readyStackLength = readyStack.length; i < readyStackLength; i++ ) { + + readyStack[ i ].call( document, Popcorn ); + + } + // GC readyStack + readyStack = null; + }; + + // Register global DOM ready listener + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + } + + return; + } + + if ( typeof entity === "string" ) { + try { + matches = document.querySelector( entity ); + } catch( e ) { + throw new Error( "Popcorn.js Error: Invalid media element selector: " + entity ); + } + } + + // Get media element by id or object reference + this.media = matches || entity; + + // inner reference to this media element's nodeName string value + nodeName = ( this.media.nodeName && this.media.nodeName.toLowerCase() ) || "video"; + + // Create an audio or video element property reference + this[ nodeName ] = this.media; + + this.options = Popcorn.extend( {}, options ) || {}; + + // Resolve custom ID or default prefixed ID + this.id = this.options.id || Popcorn.guid( nodeName ); + + // Throw if an attempt is made to use an ID that already exists + if ( Popcorn.byId( this.id ) ) { + throw new Error( "Popcorn.js Error: Cannot use duplicate ID (" + this.id + ")" ); + } + + this.isDestroyed = false; + + this.data = { + + // data structure of all + running: { + cue: [] + }, + + // Executed by either timeupdate event or in rAF loop + timeUpdate: Popcorn.nop, + + // Allows disabling a plugin per instance + disabled: {}, + + // Stores DOM event queues by type + events: {}, + + // Stores Special event hooks data + hooks: {}, + + // Store track event history data + history: [], + + // Stores ad-hoc state related data] + state: { + volume: this.media.volume + }, + + // Store track event object references by trackId + trackRefs: {}, + + // Playback track event queues + trackEvents: new TrackEvents( this ) + }; + + // Register new instance + Popcorn.instances.push( this ); + + // function to fire when video is ready + var isReady = function() { + + // chrome bug: http://code.google.com/p/chromium/issues/detail?id=119598 + // it is possible the video's time is less than 0 + // this has the potential to call track events more than once, when they should not + // start: 0, end: 1 will start, end, start again, when it should just start + // just setting it to 0 if it is below 0 fixes this issue + if ( self.media.currentTime < 0 ) { + + self.media.currentTime = 0; + } + + self.media.removeEventListener( "loadedmetadata", isReady, false ); + + var duration, videoDurationPlus, + runningPlugins, runningPlugin, rpLength, rpNatives; + + // Adding padding to the front and end of the arrays + // this is so we do not fall off either end + duration = self.media.duration; + + // Check for no duration info (NaN) + videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1; + + Popcorn.addTrackEvent( self, { + start: videoDurationPlus, + end: videoDurationPlus + }); + + if ( !self.isDestroyed ) { + self.data.durationChange = function() { + var newDuration = self.media.duration, + newDurationPlus = newDuration + 1, + byStart = self.data.trackEvents.byStart, + byEnd = self.data.trackEvents.byEnd; + + // Remove old padding events + byStart.pop(); + byEnd.pop(); + + // Remove any internal tracking of events that have end times greater than duration + // otherwise their end events will never be hit. + for ( var k = byEnd.length - 1; k > 0; k-- ) { + if ( byEnd[ k ].end > newDuration ) { + self.removeTrackEvent( byEnd[ k ]._id ); + } + } + + // Remove any internal tracking of events that have end times greater than duration + // otherwise their end events will never be hit. + for ( var i = 0; i < byStart.length; i++ ) { + if ( byStart[ i ].end > newDuration ) { + self.removeTrackEvent( byStart[ i ]._id ); + } + } + + // References to byEnd/byStart are reset, so accessing it this way is + // forced upon us. + self.data.trackEvents.byEnd.push({ + start: newDurationPlus, + end: newDurationPlus + }); + + self.data.trackEvents.byStart.push({ + start: newDurationPlus, + end: newDurationPlus + }); + }; + + // Listen for duration changes and adjust internal tracking of event timings + self.media.addEventListener( "durationchange", self.data.durationChange, false ); + } + + if ( self.options.frameAnimation ) { + + // if Popcorn is created with frameAnimation option set to true, + // requestAnimFrame is used instead of "timeupdate" media event. + // This is for greater frame time accuracy, theoretically up to + // 60 frames per second as opposed to ~4 ( ~every 15-250ms) + self.data.timeUpdate = function () { + + Popcorn.timeUpdate( self, {} ); + + // fire frame for each enabled active plugin of every type + Popcorn.forEach( Popcorn.manifest, function( key, val ) { + + runningPlugins = self.data.running[ val ]; + + // ensure there are running plugins on this type on this instance + if ( runningPlugins ) { + + rpLength = runningPlugins.length; + for ( var i = 0; i < rpLength; i++ ) { + + runningPlugin = runningPlugins[ i ]; + rpNatives = runningPlugin._natives; + rpNatives && rpNatives.frame && + rpNatives.frame.call( self, {}, runningPlugin, self.currentTime() ); + } + } + }); + + self.emit( "timeupdate" ); + + !self.isDestroyed && requestAnimFrame( self.data.timeUpdate ); + }; + + !self.isDestroyed && requestAnimFrame( self.data.timeUpdate ); + + } else { + + self.data.timeUpdate = function( event ) { + Popcorn.timeUpdate( self, event ); + }; + + if ( !self.isDestroyed ) { + self.media.addEventListener( "timeupdate", self.data.timeUpdate, false ); + } + } + }; + + self.media.addEventListener( "error", function() { + self.error = self.media.error; + }, false ); + + // http://www.whatwg.org/specs/web-apps/current-work/#dom-media-readystate + // + // If media is in readyState (rS) >= 1, we know the media's duration, + // which is required before running the isReady function. + // If rS is 0, attach a listener for "loadedmetadata", + // ( Which indicates that the media has moved from rS 0 to 1 ) + // + // This has been changed from a check for rS 2 because + // in certain conditions, Firefox can enter this code after dropping + // to rS 1 from a higher state such as 2 or 3. This caused a "loadeddata" + // listener to be attached to the media object, an event that had + // already triggered and would not trigger again. This left Popcorn with an + // instance that could never start a timeUpdate loop. + if ( self.media.readyState >= 1 ) { + + isReady(); + } else { + + self.media.addEventListener( "loadedmetadata", isReady, false ); + } + + return this; + } + }; + + // Extend constructor prototype to instance prototype + // Allows chaining methods to instances + Popcorn.p.init.prototype = Popcorn.p; + + Popcorn.byId = function( str ) { + var instances = Popcorn.instances, + length = instances.length, + i = 0; + + for ( ; i < length; i++ ) { + if ( instances[ i ].id === str ) { + return instances[ i ]; + } + } + + return null; + }; + + Popcorn.forEach = function( obj, fn, context ) { + + if ( !obj || !fn ) { + return {}; + } + + context = context || this; + + var key, len; + + // Use native whenever possible + if ( forEach && obj.forEach === forEach ) { + return obj.forEach( fn, context ); + } + + if ( toString.call( obj ) === "[object NodeList]" ) { + for ( key = 0, len = obj.length; key < len; key++ ) { + fn.call( context, obj[ key ], key, obj ); + } + return obj; + } + + for ( key in obj ) { + if ( hasOwn.call( obj, key ) ) { + fn.call( context, obj[ key ], key, obj ); + } + } + return obj; + }; + + Popcorn.extend = function( obj ) { + var dest = obj, src = slice.call( arguments, 1 ); + + Popcorn.forEach( src, function( copy ) { + for ( var prop in copy ) { + dest[ prop ] = copy[ prop ]; + } + }); + + return dest; + }; + + + // A Few reusable utils, memoized onto Popcorn + Popcorn.extend( Popcorn, { + noConflict: function( deep ) { + + if ( deep ) { + global.Popcorn = _Popcorn; + } + + return Popcorn; + }, + error: function( msg ) { + throw new Error( msg ); + }, + guid: function( prefix ) { + Popcorn.guid.counter++; + return ( prefix ? prefix : "" ) + ( +new Date() + Popcorn.guid.counter ); + }, + sizeOf: function( obj ) { + var size = 0; + + for ( var prop in obj ) { + size++; + } + + return size; + }, + isArray: Array.isArray || function( array ) { + return toString.call( array ) === "[object Array]"; + }, + + nop: function() {}, + + position: function( elem ) { + + if ( !elem.parentNode ) { + return null; + } + + var clientRect = elem.getBoundingClientRect(), + bounds = {}, + doc = elem.ownerDocument, + docElem = document.documentElement, + body = document.body, + clientTop, clientLeft, scrollTop, scrollLeft, top, left; + + // Determine correct clientTop/Left + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + + // Determine correct scrollTop/Left + scrollTop = ( global.pageYOffset && docElem.scrollTop || body.scrollTop ); + scrollLeft = ( global.pageXOffset && docElem.scrollLeft || body.scrollLeft ); + + // Temp top/left + top = Math.ceil( clientRect.top + scrollTop - clientTop ); + left = Math.ceil( clientRect.left + scrollLeft - clientLeft ); + + for ( var p in clientRect ) { + bounds[ p ] = Math.round( clientRect[ p ] ); + } + + return Popcorn.extend({}, bounds, { top: top, left: left }); + }, + + disable: function( instance, plugin ) { + + if ( instance.data.disabled[ plugin ] ) { + return; + } + + instance.data.disabled[ plugin ] = true; + + if ( plugin in Popcorn.registryByName && + instance.data.running[ plugin ] ) { + + for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) { + + event = instance.data.running[ plugin ][ i ]; + event._natives.end.call( instance, null, event ); + + instance.emit( "trackend", + Popcorn.extend({}, event, { + plugin: event.type, + type: "trackend" + }) + ); + } + } + + return instance; + }, + enable: function( instance, plugin ) { + + if ( !instance.data.disabled[ plugin ] ) { + return; + } + + instance.data.disabled[ plugin ] = false; + + if ( plugin in Popcorn.registryByName && + instance.data.running[ plugin ] ) { + + for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) { + + event = instance.data.running[ plugin ][ i ]; + event._natives.start.call( instance, null, event ); + + instance.emit( "trackstart", + Popcorn.extend({}, event, { + plugin: event.type, + type: "trackstart", + track: event + }) + ); + } + } + + return instance; + }, + destroy: function( instance ) { + var events = instance.data.events, + trackEvents = instance.data.trackEvents, + singleEvent, item, fn, plugin; + + // Iterate through all events and remove them + for ( item in events ) { + singleEvent = events[ item ]; + for ( fn in singleEvent ) { + delete singleEvent[ fn ]; + } + events[ item ] = null; + } + + // remove all plugins off the given instance + for ( plugin in Popcorn.registryByName ) { + Popcorn.removePlugin( instance, plugin ); + } + + // Remove all data.trackEvents #1178 + trackEvents.byStart.length = 0; + trackEvents.byEnd.length = 0; + + if ( !instance.isDestroyed ) { + instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false ); + instance.isDestroyed = true; + } + + Popcorn.instances.splice( Popcorn.instances.indexOf( instance ), 1 ); + } + }); + + // Memoized GUID Counter + Popcorn.guid.counter = 1; + + // Factory to implement getters, setters and controllers + // as Popcorn instance methods. The IIFE will create and return + // an object with defined methods + Popcorn.extend(Popcorn.p, (function() { + + var methods = "load play pause currentTime playbackRate volume duration preload playbackRate " + + "autoplay loop controls muted buffered readyState seeking paused played seekable ended", + ret = {}; + + + // Build methods, store in object that is returned and passed to extend + Popcorn.forEach( methods.split( /\s+/g ), function( name ) { + + ret[ name ] = function( arg ) { + var previous; + + if ( typeof this.media[ name ] === "function" ) { + + // Support for shorthanded play(n)/pause(n) jump to currentTime + // If arg is not null or undefined and called by one of the + // allowed shorthandable methods, then set the currentTime + // Supports time as seconds or SMPTE + if ( arg != null && /play|pause/.test( name ) ) { + this.media.currentTime = Popcorn.util.toSeconds( arg ); + } + + this.media[ name ](); + + return this; + } + + if ( arg != null ) { + // Capture the current value of the attribute property + previous = this.media[ name ]; + + // Set the attribute property with the new value + this.media[ name ] = arg; + + // If the new value is not the same as the old value + // emit an "attrchanged event" + if ( previous !== arg ) { + this.emit( "attrchange", { + attribute: name, + previousValue: previous, + currentValue: arg + }); + } + return this; + } + + return this.media[ name ]; + }; + }); + + return ret; + + })() + ); + + Popcorn.forEach( "enable disable".split(" "), function( method ) { + Popcorn.p[ method ] = function( plugin ) { + return Popcorn[ method ]( this, plugin ); + }; + }); + + Popcorn.extend(Popcorn.p, { + + // Rounded currentTime + roundTime: function() { + return Math.round( this.media.currentTime ); + }, + + // Attach an event to a single point in time + exec: function( id, time, fn ) { + var length = arguments.length, + eventType = "trackadded", + trackEvent, sec, options; + + // Check if first could possibly be a SMPTE string + // p.cue( "smpte string", fn ); + // try/catch avoid awful throw in Popcorn.util.toSeconds + // TODO: Get rid of that, replace with NaN return? + try { + sec = Popcorn.util.toSeconds( id ); + } catch ( e ) {} + + // If it can be converted into a number then + // it's safe to assume that the string was SMPTE + if ( typeof sec === "number" ) { + id = sec; + } + + // Shift arguments based on use case + // + // Back compat for: + // p.cue( time, fn ); + if ( typeof id === "number" && length === 2 ) { + fn = time; + time = id; + id = Popcorn.guid( "cue" ); + } else { + // Support for new forms + + // p.cue( "empty-cue" ); + if ( length === 1 ) { + // Set a time for an empty cue. It's not important what + // the time actually is, because the cue is a no-op + time = -1; + + } else { + + // Get the TrackEvent that matches the given id. + trackEvent = this.getTrackEvent( id ); + + if ( trackEvent ) { + + // remove existing cue so a new one can be added via trackEvents.add + this.data.trackEvents.remove( id ); + TrackEvent.end( this, trackEvent ); + // Update track event references + Popcorn.removeTrackEvent.ref( this, id ); + + eventType = "cuechange"; + + // p.cue( "my-id", 12 ); + // p.cue( "my-id", function() { ... }); + if ( typeof id === "string" && length === 2 ) { + + // p.cue( "my-id", 12 ); + // The path will update the cue time. + if ( typeof time === "number" ) { + // Re-use existing TrackEvent start callback + fn = trackEvent._natives.start; + } + + // p.cue( "my-id", function() { ... }); + // The path will update the cue function + if ( typeof time === "function" ) { + fn = time; + // Re-use existing TrackEvent start time + time = trackEvent.start; + } + } + } else { + + if ( length >= 2 ) { + + // p.cue( "a", "00:00:00"); + if ( typeof time === "string" ) { + try { + sec = Popcorn.util.toSeconds( time ); + } catch ( e ) {} + + time = sec; + } + + // p.cue( "b", 11 ); + // p.cue( "b", 11, function() {} ); + if ( typeof time === "number" ) { + fn = fn || Popcorn.nop(); + } + + // p.cue( "c", function() {}); + if ( typeof time === "function" ) { + fn = time; + time = -1; + } + } + } + } + } + + options = { + id: id, + start: time, + end: time + 1, + _running: false, + _natives: { + start: fn || Popcorn.nop, + end: Popcorn.nop, + type: "cue" + } + }; + + if ( trackEvent ) { + options = Popcorn.extend( trackEvent, options ); + } + + if ( eventType === "cuechange" ) { + + // Supports user defined track event id + options._id = options.id || options._id || Popcorn.guid( options._natives.type ); + + this.data.trackEvents.add( options ); + TrackEvent.start( this, options ); + + this.timeUpdate( this, null, true ); + + // Store references to user added trackevents in ref table + Popcorn.addTrackEvent.ref( this, options ); + + this.emit( eventType, Popcorn.extend({}, options, { + id: id, + type: eventType, + previousValue: { + time: trackEvent.start, + fn: trackEvent._natives.start + }, + currentValue: { + time: time, + fn: fn || Popcorn.nop + }, + track: trackEvent + })); + } else { + // Creating a one second track event with an empty end + Popcorn.addTrackEvent( this, options ); + } + + return this; + }, + + // Mute the calling media, optionally toggle + mute: function( toggle ) { + + var event = toggle == null || toggle === true ? "muted" : "unmuted"; + + // If `toggle` is explicitly `false`, + // unmute the media and restore the volume level + if ( event === "unmuted" ) { + this.media.muted = false; + this.media.volume = this.data.state.volume; + } + + // If `toggle` is either null or undefined, + // save the current volume and mute the media element + if ( event === "muted" ) { + this.data.state.volume = this.media.volume; + this.media.muted = true; + } + + // Trigger either muted|unmuted event + this.emit( event ); + + return this; + }, + + // Convenience method, unmute the calling media + unmute: function( toggle ) { + + return this.mute( toggle == null ? false : !toggle ); + }, + + // Get the client bounding box of an instance element + position: function() { + return Popcorn.position( this.media ); + }, + + // Toggle a plugin's playback behaviour (on or off) per instance + toggle: function( plugin ) { + return Popcorn[ this.data.disabled[ plugin ] ? "enable" : "disable" ]( this, plugin ); + }, + + // Set default values for plugin options objects per instance + defaults: function( plugin, defaults ) { + + // If an array of default configurations is provided, + // iterate and apply each to this instance + if ( Popcorn.isArray( plugin ) ) { + + Popcorn.forEach( plugin, function( obj ) { + for ( var name in obj ) { + this.defaults( name, obj[ name ] ); + } + }, this ); + + return this; + } + + if ( !this.options.defaults ) { + this.options.defaults = {}; + } + + if ( !this.options.defaults[ plugin ] ) { + this.options.defaults[ plugin ] = {}; + } + + Popcorn.extend( this.options.defaults[ plugin ], defaults ); + + return this; + } + }); + + Popcorn.Events = { + UIEvents: "blur focus focusin focusout load resize scroll unload", + MouseEvents: "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick", + Events: "loadstart progress suspend emptied stalled play pause error " + + "loadedmetadata loadeddata waiting playing canplay canplaythrough " + + "seeking seeked timeupdate ended ratechange durationchange volumechange" + }; + + Popcorn.Events.Natives = Popcorn.Events.UIEvents + " " + + Popcorn.Events.MouseEvents + " " + + Popcorn.Events.Events; + + internal.events.apiTypes = [ "UIEvents", "MouseEvents", "Events" ]; + + // Privately compile events table at load time + (function( events, data ) { + + var apis = internal.events.apiTypes, + eventsList = events.Natives.split( /\s+/g ), + idx = 0, len = eventsList.length, prop; + + for( ; idx < len; idx++ ) { + data.hash[ eventsList[idx] ] = true; + } + + apis.forEach(function( val, idx ) { + + data.apis[ val ] = {}; + + var apiEvents = events[ val ].split( /\s+/g ), + len = apiEvents.length, + k = 0; + + for ( ; k < len; k++ ) { + data.apis[ val ][ apiEvents[ k ] ] = true; + } + }); + })( Popcorn.Events, internal.events ); + + Popcorn.events = { + + isNative: function( type ) { + return !!internal.events.hash[ type ]; + }, + getInterface: function( type ) { + + if ( !Popcorn.events.isNative( type ) ) { + return false; + } + + var eventApi = internal.events, + apis = eventApi.apiTypes, + apihash = eventApi.apis, + idx = 0, len = apis.length, api, tmp; + + for ( ; idx < len; idx++ ) { + tmp = apis[ idx ]; + + if ( apihash[ tmp ][ type ] ) { + api = tmp; + break; + } + } + return api; + }, + // Compile all native events to single array + all: Popcorn.Events.Natives.split( /\s+/g ), + // Defines all Event handling static functions + fn: { + trigger: function( type, data ) { + var eventInterface, evt, clonedEvents, + events = this.data.events[ type ]; + + // setup checks for custom event system + if ( events ) { + eventInterface = Popcorn.events.getInterface( type ); + + if ( eventInterface ) { + evt = document.createEvent( eventInterface ); + evt.initEvent( type, true, true, global, 1 ); + + this.media.dispatchEvent( evt ); + + return this; + } + + // clone events in case callbacks remove callbacks themselves + clonedEvents = events.slice(); + + // iterate through all callbacks + while ( clonedEvents.length ) { + clonedEvents.shift().call( this, data ); + } + } + + return this; + }, + listen: function( type, fn ) { + var self = this, + hasEvents = true, + eventHook = Popcorn.events.hooks[ type ], + origType = type, + clonedEvents, + tmp; + + if ( typeof fn !== "function" ) { + throw new Error( "Popcorn.js Error: Listener is not a function" ); + } + + // Setup event registry entry + if ( !this.data.events[ type ] ) { + this.data.events[ type ] = []; + // Toggle if the previous assumption was untrue + hasEvents = false; + } + + // Check and setup event hooks + if ( eventHook ) { + // Execute hook add method if defined + if ( eventHook.add ) { + eventHook.add.call( this, {}, fn ); + } + + // Reassign event type to our piggyback event type if defined + if ( eventHook.bind ) { + type = eventHook.bind; + } + + // Reassign handler if defined + if ( eventHook.handler ) { + tmp = fn; + + fn = function wrapper( event ) { + eventHook.handler.call( self, event, tmp ); + }; + } + + // assume the piggy back event is registered + hasEvents = true; + + // Setup event registry entry + if ( !this.data.events[ type ] ) { + this.data.events[ type ] = []; + // Toggle if the previous assumption was untrue + hasEvents = false; + } + } + + // Register event and handler + this.data.events[ type ].push( fn ); + + // only attach one event of any type + if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) { + this.media.addEventListener( type, function( event ) { + if ( self.data.events[ type ] ) { + // clone events in case callbacks remove callbacks themselves + clonedEvents = self.data.events[ type ].slice(); + + // iterate through all callbacks + while ( clonedEvents.length ) { + clonedEvents.shift().call( self, event ); + } + } + }, false ); + } + return this; + }, + unlisten: function( type, fn ) { + var ind, + events = this.data.events[ type ]; + + if ( !events ) { + return; // no listeners = nothing to do + } + + if ( typeof fn === "string" ) { + // legacy support for string-based removal -- not recommended + for ( var i = 0; i < events.length; i++ ) { + if ( events[ i ].name === fn ) { + // decrement i because array length just got smaller + events.splice( i--, 1 ); + } + } + + return this; + } else if ( typeof fn === "function" ) { + while( ind !== -1 ) { + ind = events.indexOf( fn ); + if ( ind !== -1 ) { + events.splice( ind, 1 ); + } + } + + return this; + } + + // if we got to this point, we are deleting all functions of this type + this.data.events[ type ] = null; + + return this; + } + }, + hooks: { + canplayall: { + bind: "canplaythrough", + add: function( event, callback ) { + + var state = false; + + if ( this.media.readyState ) { + + // always call canplayall asynchronously + setTimeout(function() { + callback.call( this, event ); + }.bind(this), 0 ); + + state = true; + } + + this.data.hooks.canplayall = { + fired: state + }; + }, + // declare special handling instructions + handler: function canplayall( event, callback ) { + + if ( !this.data.hooks.canplayall.fired ) { + // trigger original user callback once + callback.call( this, event ); + + this.data.hooks.canplayall.fired = true; + } + } + } + } + }; + + // Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances + // Extend aliases (on, off, emit) + Popcorn.forEach( [ [ "trigger", "emit" ], [ "listen", "on" ], [ "unlisten", "off" ] ], function( key ) { + Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ]; + }); + + // Internal Only - construct simple "TrackEvent" + // data type objects + function TrackEvent( track ) { + Abstract.put.call( this, track ); + } + + // Determine if a TrackEvent's "start" and "trackstart" must be called. + TrackEvent.start = function( instance, track ) { + + if ( track.end > instance.media.currentTime && + track.start <= instance.media.currentTime && !track._running ) { + + track._running = true; + instance.data.running[ track._natives.type ].push( track ); + + if ( !instance.data.disabled[ track._natives.type ] ) { + + track._natives.start.call( instance, null, track ); + + instance.emit( "trackstart", + Popcorn.extend( {}, track, { + plugin: track._natives.type, + type: "trackstart", + track: track + }) + ); + } + } + }; + + // Determine if a TrackEvent's "end" and "trackend" must be called. + TrackEvent.end = function( instance, track ) { + + var runningPlugins; + + if ( ( track.end <= instance.media.currentTime || + track.start > instance.media.currentTime ) && track._running ) { + + runningPlugins = instance.data.running[ track._natives.type ]; + + track._running = false; + runningPlugins.splice( runningPlugins.indexOf( track ), 1 ); + + if ( !instance.data.disabled[ track._natives.type ] ) { + + track._natives.end.call( instance, null, track ); + + instance.emit( "trackend", + Popcorn.extend( {}, track, { + plugin: track._natives.type, + type: "trackend", + track: track + }) + ); + } + } + }; + + // Internal Only - construct "TrackEvents" + // data type objects that are used by the Popcorn + // instance, stored at p.data.trackEvents + function TrackEvents( parent ) { + this.parent = parent; + + this.byStart = [{ + start: -1, + end: -1 + }]; + + this.byEnd = [{ + start: -1, + end: -1 + }]; + this.animating = []; + this.startIndex = 0; + this.endIndex = 0; + this.previousUpdateTime = -1; + + this.count = 1; + } + + function isMatch( obj, key, value ) { + return obj[ key ] && obj[ key ] === value; + } + + TrackEvents.prototype.where = function( params ) { + return ( this.parent.getTrackEvents() || [] ).filter(function( event ) { + var key, value; + + // If no explicit params, match all TrackEvents + if ( !params ) { + return true; + } + + // Filter keys in params against both the top level properties + // and the _natives properties + for ( key in params ) { + value = params[ key ]; + if ( isMatch( event, key, value ) || isMatch( event._natives, key, value ) ) { + return true; + } + } + return false; + }); + }; + + TrackEvents.prototype.add = function( track ) { + + // Store this definition in an array sorted by times + var byStart = this.byStart, + byEnd = this.byEnd, + startIndex, endIndex; + + // Push track event ids into the history + if ( track && track._id ) { + this.parent.data.history.push( track._id ); + } + + track.start = Popcorn.util.toSeconds( track.start, this.parent.options.framerate ); + track.end = Popcorn.util.toSeconds( track.end, this.parent.options.framerate ); + + for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) { + + if ( track.start >= byStart[ startIndex ].start ) { + byStart.splice( startIndex + 1, 0, track ); + break; + } + } + + for ( endIndex = byEnd.length - 1; endIndex >= 0; endIndex-- ) { + + if ( track.end > byEnd[ endIndex ].end ) { + byEnd.splice( endIndex + 1, 0, track ); + break; + } + } + + // update startIndex and endIndex + if ( startIndex <= this.parent.data.trackEvents.startIndex && + track.start <= this.parent.data.trackEvents.previousUpdateTime ) { + + this.parent.data.trackEvents.startIndex++; + } + + if ( endIndex <= this.parent.data.trackEvents.endIndex && + track.end < this.parent.data.trackEvents.previousUpdateTime ) { + + this.parent.data.trackEvents.endIndex++; + } + + this.count++; + + }; + + TrackEvents.prototype.remove = function( removeId, state ) { + + if ( removeId instanceof TrackEvent ) { + removeId = removeId.id; + } + + if ( typeof removeId === "object" ) { + // Filter by key=val and remove all matching TrackEvents + this.where( removeId ).forEach(function( event ) { + // |this| refers to the calling Popcorn "parent" instance + this.removeTrackEvent( event._id ); + }, this.parent ); + + return this; + } + + var start, end, animate, historyLen, track, + length = this.byStart.length, + index = 0, + indexWasAt = 0, + byStart = [], + byEnd = [], + animating = [], + history = [], + comparable = {}; + + state = state || {}; + + while ( --length > -1 ) { + start = this.byStart[ index ]; + end = this.byEnd[ index ]; + + // Padding events will not have _id properties. + // These should be safely pushed onto the front and back of the + // track event array + if ( !start._id ) { + byStart.push( start ); + byEnd.push( end ); + } + + // Filter for user track events (vs system track events) + if ( start._id ) { + + // If not a matching start event for removal + if ( start._id !== removeId ) { + byStart.push( start ); + } + + // If not a matching end event for removal + if ( end._id !== removeId ) { + byEnd.push( end ); + } + + // If the _id is matched, capture the current index + if ( start._id === removeId ) { + indexWasAt = index; + + // cache the track event being removed + track = start; + } + } + // Increment the track index + index++; + } + + // Reset length to be used by the condition below to determine + // if animating track events should also be filtered for removal. + // Reset index below to be used by the reverse while as an + // incrementing counter + length = this.animating.length; + index = 0; + + if ( length ) { + while ( --length > -1 ) { + animate = this.animating[ index ]; + + // Padding events will not have _id properties. + // These should be safely pushed onto the front and back of the + // track event array + if ( !animate._id ) { + animating.push( animate ); + } + + // If not a matching animate event for removal + if ( animate._id && animate._id !== removeId ) { + animating.push( animate ); + } + // Increment the track index + index++; + } + } + + // Update + if ( indexWasAt <= this.startIndex ) { + this.startIndex--; + } + + if ( indexWasAt <= this.endIndex ) { + this.endIndex--; + } + + this.byStart = byStart; + this.byEnd = byEnd; + this.animating = animating; + this.count--; + + historyLen = this.parent.data.history.length; + + for ( var i = 0; i < historyLen; i++ ) { + if ( this.parent.data.history[ i ] !== removeId ) { + history.push( this.parent.data.history[ i ] ); + } + } + + // Update ordered history array + this.parent.data.history = history; + + }; + + // Helper function used to retrieve old values of properties that + // are provided for update. + function getPreviousProperties( oldOptions, newOptions ) { + var matchProps = {}; + + for ( var prop in oldOptions ) { + if ( hasOwn.call( newOptions, prop ) && hasOwn.call( oldOptions, prop ) ) { + matchProps[ prop ] = oldOptions[ prop ]; + } + } + + return matchProps; + } + + // Internal Only - Adds track events to the instance object + Popcorn.addTrackEvent = function( obj, track ) { + var temp; + + if ( track instanceof TrackEvent ) { + return; + } + + track = new TrackEvent( track ); + + // Determine if this track has default options set for it + // If so, apply them to the track object + if ( track && track._natives && track._natives.type && + ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) { + + // To ensure that the TrackEvent Invariant Policy is enforced, + // First, copy the properties of the newly created track event event + // to a temporary holder + temp = Popcorn.extend( {}, track ); + + // Next, copy the default onto the newly created trackevent, followed by the + // temporary holder. + Popcorn.extend( track, obj.options.defaults[ track._natives.type ], temp ); + } + + if ( track._natives ) { + // Supports user defined track event id + track._id = track.id || track._id || Popcorn.guid( track._natives.type ); + + // Trigger _setup method if exists + if ( track._natives._setup ) { + + track._natives._setup.call( obj, track ); + + obj.emit( "tracksetup", Popcorn.extend( {}, track, { + plugin: track._natives.type, + type: "tracksetup", + track: track + })); + } + } + + obj.data.trackEvents.add( track ); + TrackEvent.start( obj, track ); + + this.timeUpdate( obj, null, true ); + + // Store references to user added trackevents in ref table + if ( track._id ) { + Popcorn.addTrackEvent.ref( obj, track ); + } + + obj.emit( "trackadded", Popcorn.extend({}, track, + track._natives ? { plugin: track._natives.type } : {}, { + type: "trackadded", + track: track + })); + }; + + // Internal Only - Adds track event references to the instance object's trackRefs hash table + Popcorn.addTrackEvent.ref = function( obj, track ) { + obj.data.trackRefs[ track._id ] = track; + + return obj; + }; + + Popcorn.removeTrackEvent = function( obj, removeId ) { + var track = obj.getTrackEvent( removeId ); + + if ( !track ) { + return; + } + + // If a _teardown function was defined, + // enforce for track event removals + if ( track._natives._teardown ) { + track._natives._teardown.call( obj, track ); + } + + obj.data.trackEvents.remove( removeId ); + + // Update track event references + Popcorn.removeTrackEvent.ref( obj, removeId ); + + if ( track._natives ) { + + // Fire a trackremoved event + obj.emit( "trackremoved", Popcorn.extend({}, track, { + plugin: track._natives.type, + type: "trackremoved", + track: track + })); + } + }; + + // Internal Only - Removes track event references from instance object's trackRefs hash table + Popcorn.removeTrackEvent.ref = function( obj, removeId ) { + delete obj.data.trackRefs[ removeId ]; + + return obj; + }; + + // Return an array of track events bound to this instance object + Popcorn.getTrackEvents = function( obj ) { + + var trackevents = [], + refs = obj.data.trackEvents.byStart, + length = refs.length, + idx = 0, + ref; + + for ( ; idx < length; idx++ ) { + ref = refs[ idx ]; + // Return only user attributed track event references + if ( ref._id ) { + trackevents.push( ref ); + } + } + + return trackevents; + }; + + // Internal Only - Returns an instance object's trackRefs hash table + Popcorn.getTrackEvents.ref = function( obj ) { + return obj.data.trackRefs; + }; + + // Return a single track event bound to this instance object + Popcorn.getTrackEvent = function( obj, trackId ) { + return obj.data.trackRefs[ trackId ]; + }; + + // Internal Only - Returns an instance object's track reference by track id + Popcorn.getTrackEvent.ref = function( obj, trackId ) { + return obj.data.trackRefs[ trackId ]; + }; + + Popcorn.getLastTrackEventId = function( obj ) { + return obj.data.history[ obj.data.history.length - 1 ]; + }; + + Popcorn.timeUpdate = function( obj, event ) { + var currentTime = obj.media.currentTime, + previousTime = obj.data.trackEvents.previousUpdateTime, + tracks = obj.data.trackEvents, + end = tracks.endIndex, + start = tracks.startIndex, + byStartLen = tracks.byStart.length, + byEndLen = tracks.byEnd.length, + registryByName = Popcorn.registryByName, + trackstart = "trackstart", + trackend = "trackend", + + byEnd, byStart, byAnimate, natives, type, runningPlugins; + + // Playbar advancing + if ( previousTime <= currentTime ) { + + while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end <= currentTime ) { + + byEnd = tracks.byEnd[ end ]; + natives = byEnd._natives; + type = natives && natives.type; + + // If plugin does not exist on this instance, remove it + if ( !natives || + ( !!registryByName[ type ] || + !!obj[ type ] ) ) { + + if ( byEnd._running === true ) { + + byEnd._running = false; + runningPlugins = obj.data.running[ type ]; + runningPlugins.splice( runningPlugins.indexOf( byEnd ), 1 ); + + if ( !obj.data.disabled[ type ] ) { + + natives.end.call( obj, event, byEnd ); + + obj.emit( trackend, + Popcorn.extend({}, byEnd, { + plugin: type, + type: trackend, + track: byEnd + }) + ); + } + } + + end++; + } else { + // remove track event + Popcorn.removeTrackEvent( obj, byEnd._id ); + return; + } + } + + while ( tracks.byStart[ start ] && tracks.byStart[ start ].start <= currentTime ) { + + byStart = tracks.byStart[ start ]; + natives = byStart._natives; + type = natives && natives.type; + // If plugin does not exist on this instance, remove it + if ( !natives || + ( !!registryByName[ type ] || + !!obj[ type ] ) ) { + if ( byStart.end > currentTime && + byStart._running === false ) { + + byStart._running = true; + obj.data.running[ type ].push( byStart ); + + if ( !obj.data.disabled[ type ] ) { + + natives.start.call( obj, event, byStart ); + + obj.emit( trackstart, + Popcorn.extend({}, byStart, { + plugin: type, + type: trackstart, + track: byStart + }) + ); + } + } + start++; + } else { + // remove track event + Popcorn.removeTrackEvent( obj, byStart._id ); + return; + } + } + + // Playbar receding + } else if ( previousTime > currentTime ) { + + while ( tracks.byStart[ start ] && tracks.byStart[ start ].start > currentTime ) { + + byStart = tracks.byStart[ start ]; + natives = byStart._natives; + type = natives && natives.type; + + // if plugin does not exist on this instance, remove it + if ( !natives || + ( !!registryByName[ type ] || + !!obj[ type ] ) ) { + + if ( byStart._running === true ) { + + byStart._running = false; + runningPlugins = obj.data.running[ type ]; + runningPlugins.splice( runningPlugins.indexOf( byStart ), 1 ); + + if ( !obj.data.disabled[ type ] ) { + + natives.end.call( obj, event, byStart ); + + obj.emit( trackend, + Popcorn.extend({}, byStart, { + plugin: type, + type: trackend, + track: byStart + }) + ); + } + } + start--; + } else { + // remove track event + Popcorn.removeTrackEvent( obj, byStart._id ); + return; + } + } + + while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end > currentTime ) { + + byEnd = tracks.byEnd[ end ]; + natives = byEnd._natives; + type = natives && natives.type; + + // if plugin does not exist on this instance, remove it + if ( !natives || + ( !!registryByName[ type ] || + !!obj[ type ] ) ) { + + if ( byEnd.start <= currentTime && + byEnd._running === false ) { + + byEnd._running = true; + obj.data.running[ type ].push( byEnd ); + + if ( !obj.data.disabled[ type ] ) { + + natives.start.call( obj, event, byEnd ); + + obj.emit( trackstart, + Popcorn.extend({}, byEnd, { + plugin: type, + type: trackstart, + track: byEnd + }) + ); + } + } + end--; + } else { + // remove track event + Popcorn.removeTrackEvent( obj, byEnd._id ); + return; + } + } + } + + tracks.endIndex = end; + tracks.startIndex = start; + tracks.previousUpdateTime = currentTime; + + //enforce index integrity if trackRemoved + tracks.byStart.length < byStartLen && tracks.startIndex--; + tracks.byEnd.length < byEndLen && tracks.endIndex--; + + }; + + // Map and Extend TrackEvent functions to all Popcorn instances + Popcorn.extend( Popcorn.p, { + + getTrackEvents: function() { + return Popcorn.getTrackEvents.call( null, this ); + }, + + getTrackEvent: function( id ) { + return Popcorn.getTrackEvent.call( null, this, id ); + }, + + getLastTrackEventId: function() { + return Popcorn.getLastTrackEventId.call( null, this ); + }, + + removeTrackEvent: function( id ) { + + Popcorn.removeTrackEvent.call( null, this, id ); + return this; + }, + + removePlugin: function( name ) { + Popcorn.removePlugin.call( null, this, name ); + return this; + }, + + timeUpdate: function( event ) { + Popcorn.timeUpdate.call( null, this, event ); + return this; + }, + + destroy: function() { + Popcorn.destroy.call( null, this ); + return this; + } + }); + + // Plugin manifests + Popcorn.manifest = {}; + // Plugins are registered + Popcorn.registry = []; + Popcorn.registryByName = {}; + // An interface for extending Popcorn + // with plugin functionality + Popcorn.plugin = function( name, definition, manifest ) { + + if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) { + Popcorn.error( "'" + name + "' is a protected function name" ); + return; + } + + // Provides some sugar, but ultimately extends + // the definition into Popcorn.p + var isfn = typeof definition === "function", + blacklist = [ "start", "end", "type", "manifest" ], + methods = [ "_setup", "_teardown", "start", "end", "frame" ], + plugin = {}, + setup; + + // combines calls of two function calls into one + var combineFn = function( first, second ) { + + first = first || Popcorn.nop; + second = second || Popcorn.nop; + + return function() { + first.apply( this, arguments ); + second.apply( this, arguments ); + }; + }; + + // If `manifest` arg is undefined, check for manifest within the `definition` object + // If no `definition.manifest`, an empty object is a sufficient fallback + Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {}; + + // apply safe, and empty default functions + methods.forEach(function( method ) { + definition[ method ] = safeTry( definition[ method ] || Popcorn.nop, name ); + }); + + var pluginFn = function( setup, options ) { + + if ( !options ) { + return this; + } + + // When the "ranges" property is set and its value is an array, short-circuit + // the pluginFn definition to recall itself with an options object generated from + // each range object in the ranges array. (eg. { start: 15, end: 16 } ) + if ( options.ranges && Popcorn.isArray(options.ranges) ) { + Popcorn.forEach( options.ranges, function( range ) { + // Create a fresh object, extend with current options + // and start/end range object's properties + // Works with in/out as well. + var opts = Popcorn.extend( {}, options, range ); + + // Remove the ranges property to prevent infinitely + // entering this condition + delete opts.ranges; + + // Call the plugin with the newly created opts object + this[ name ]( opts ); + }, this); + + // Return the Popcorn instance to avoid creating an empty track event + return this; + } + + // Storing the plugin natives + var natives = options._natives = {}, + compose = "", + originalOpts, manifestOpts; + + Popcorn.extend( natives, setup ); + + options._natives.type = options._natives.plugin = name; + options._running = false; + + natives.start = natives.start || natives[ "in" ]; + natives.end = natives.end || natives[ "out" ]; + + if ( options.once ) { + natives.end = combineFn( natives.end, function() { + this.removeTrackEvent( options._id ); + }); + } + + // extend teardown to always call end if running + natives._teardown = combineFn(function() { + + var args = slice.call( arguments ), + runningPlugins = this.data.running[ natives.type ]; + + // end function signature is not the same as teardown, + // put null on the front of arguments for the event parameter + args.unshift( null ); + + // only call end if event is running + args[ 1 ]._running && + runningPlugins.splice( runningPlugins.indexOf( options ), 1 ) && + natives.end.apply( this, args ); + + args[ 1 ]._running = false; + this.emit( "trackend", + Popcorn.extend( {}, options, { + plugin: natives.type, + type: "trackend", + track: Popcorn.getTrackEvent( this, options.id || options._id ) + }) + ); + }, natives._teardown ); + + // extend teardown to always trigger trackteardown after teardown + natives._teardown = combineFn( natives._teardown, function() { + + this.emit( "trackteardown", Popcorn.extend( {}, options, { + plugin: name, + type: "trackteardown", + track: Popcorn.getTrackEvent( this, options.id || options._id ) + })); + }); + + // default to an empty string if no effect exists + // split string into an array of effects + options.compose = options.compose || []; + if ( typeof options.compose === "string" ) { + options.compose = options.compose.split( " " ); + } + options.effect = options.effect || []; + if ( typeof options.effect === "string" ) { + options.effect = options.effect.split( " " ); + } + + // join the two arrays together + options.compose = options.compose.concat( options.effect ); + + options.compose.forEach(function( composeOption ) { + + // if the requested compose is garbage, throw it away + compose = Popcorn.compositions[ composeOption ] || {}; + + // extends previous functions with compose function + methods.forEach(function( method ) { + natives[ method ] = combineFn( natives[ method ], compose[ method ] ); + }); + }); + + // Ensure a manifest object, an empty object is a sufficient fallback + options._natives.manifest = manifest; + + // Checks for expected properties + if ( !( "start" in options ) ) { + options.start = options[ "in" ] || 0; + } + + if ( !options.end && options.end !== 0 ) { + options.end = options[ "out" ] || Number.MAX_VALUE; + } + + // Use hasOwn to detect non-inherited toString, since all + // objects will receive a toString - its otherwise undetectable + if ( !hasOwn.call( options, "toString" ) ) { + options.toString = function() { + var props = [ + "start: " + options.start, + "end: " + options.end, + "id: " + (options.id || options._id) + ]; + + // Matches null and undefined, allows: false, 0, "" and truthy + if ( options.target != null ) { + props.push( "target: " + options.target ); + } + + return name + " ( " + props.join(", ") + " )"; + }; + } + + // Resolves 239, 241, 242 + if ( !options.target ) { + + // Sometimes the manifest may be missing entirely + // or it has an options object that doesn't have a `target` property + manifestOpts = "options" in manifest && manifest.options; + + options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target; + } + + if ( !options._id && options._natives ) { + // ensure an initial id is there before setup is called + options._id = Popcorn.guid( options._natives.type ); + } + + if ( options instanceof TrackEvent ) { + + if ( options._natives ) { + // Supports user defined track event id + options._id = options.id || options._id || Popcorn.guid( options._natives.type ); + + // Trigger _setup method if exists + if ( options._natives._setup ) { + + options._natives._setup.call( this, options ); + + this.emit( "tracksetup", Popcorn.extend( {}, options, { + plugin: options._natives.type, + type: "tracksetup", + track: options + })); + } + } + + this.data.trackEvents.add( options ); + TrackEvent.start( this, options ); + + this.timeUpdate( this, null, true ); + + // Store references to user added trackevents in ref table + if ( options._id ) { + Popcorn.addTrackEvent.ref( this, options ); + } + } else { + // Create new track event for this instance + Popcorn.addTrackEvent( this, options ); + } + + // Future support for plugin event definitions + // for all of the native events + Popcorn.forEach( setup, function( callback, type ) { + // Don't attempt to create events for certain properties: + // "start", "end", "type", "manifest". Fixes #1365 + if ( blacklist.indexOf( type ) === -1 ) { + this.on( type, callback ); + } + }, this ); + + return this; + }; + + // Extend Popcorn.p with new named definition + // Assign new named definition + Popcorn.p[ name ] = plugin[ name ] = function( id, options ) { + var length = arguments.length, + trackEvent, defaults, mergedSetupOpts, previousOpts, newOpts; + + // Shift arguments based on use case + // + // Back compat for: + // p.plugin( options ); + if ( id && !options ) { + options = id; + id = null; + } else { + + // Get the trackEvent that matches the given id. + trackEvent = this.getTrackEvent( id ); + + // If the track event does not exist, ensure that the options + // object has a proper id + if ( !trackEvent ) { + options.id = id; + + // If the track event does exist, merge the updated properties + } else { + + newOpts = options; + previousOpts = getPreviousProperties( trackEvent, newOpts ); + + // Call the plugins defined update method if provided. Allows for + // custom defined updating for a track event to be defined by the plugin author + if ( trackEvent._natives._update ) { + + this.data.trackEvents.remove( trackEvent ); + + // It's safe to say that the intent of Start/End will never change + // Update them first before calling update + if ( hasOwn.call( options, "start" ) ) { + trackEvent.start = options.start; + } + + if ( hasOwn.call( options, "end" ) ) { + trackEvent.end = options.end; + } + + TrackEvent.end( this, trackEvent ); + + if ( isfn ) { + definition.call( this, trackEvent ); + } + + trackEvent._natives._update.call( this, trackEvent, options ); + + this.data.trackEvents.add( trackEvent ); + TrackEvent.start( this, trackEvent ); + } else { + // This branch is taken when there is no explicitly defined + // _update method for a plugin. Which will occur either explicitly or + // as a result of the plugin definition being a function that _returns_ + // a definition object. + // + // In either case, this path can ONLY be reached for TrackEvents that + // already exist. + + // Directly update the TrackEvent instance. + // This supports TrackEvent invariant enforcement. + Popcorn.extend( trackEvent, options ); + + this.data.trackEvents.remove( id ); + + // If a _teardown function was defined, + // enforce for track event removals + if ( trackEvent._natives._teardown ) { + trackEvent._natives._teardown.call( this, trackEvent ); + } + + // Update track event references + Popcorn.removeTrackEvent.ref( this, id ); + + if ( isfn ) { + pluginFn.call( this, definition.call( this, trackEvent ), trackEvent ); + } else { + + // Supports user defined track event id + trackEvent._id = trackEvent.id || trackEvent._id || Popcorn.guid( trackEvent._natives.type ); + + if ( trackEvent._natives && trackEvent._natives._setup ) { + + trackEvent._natives._setup.call( this, trackEvent ); + + this.emit( "tracksetup", Popcorn.extend( {}, trackEvent, { + plugin: trackEvent._natives.type, + type: "tracksetup", + track: trackEvent + })); + } + + this.data.trackEvents.add( trackEvent ); + TrackEvent.start( this, trackEvent ); + + this.timeUpdate( this, null, true ); + + // Store references to user added trackevents in ref table + Popcorn.addTrackEvent.ref( this, trackEvent ); + } + + // Fire an event with change information + this.emit( "trackchange", { + id: trackEvent.id, + type: "trackchange", + previousValue: previousOpts, + currentValue: trackEvent, + track: trackEvent + }); + + return this; + } + + if ( trackEvent._natives.type !== "cue" ) { + // Fire an event with change information + this.emit( "trackchange", { + id: trackEvent.id, + type: "trackchange", + previousValue: previousOpts, + currentValue: newOpts, + track: trackEvent + }); + } + + return this; + } + } + + this.data.running[ name ] = this.data.running[ name ] || []; + + // Merge with defaults if they exist, make sure per call is prioritized + defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {}; + mergedSetupOpts = Popcorn.extend( {}, defaults, options ); + + pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition, + mergedSetupOpts ); + + return this; + }; + + // if the manifest parameter exists we should extend it onto the definition object + // so that it shows up when calling Popcorn.registry and Popcorn.registryByName + if ( manifest ) { + Popcorn.extend( definition, { + manifest: manifest + }); + } + + // Push into the registry + var entry = { + fn: plugin[ name ], + definition: definition, + base: definition, + parents: [], + name: name + }; + Popcorn.registry.push( + Popcorn.extend( plugin, entry, { + type: name + }) + ); + Popcorn.registryByName[ name ] = entry; + + return plugin; + }; + + // Storage for plugin function errors + Popcorn.plugin.errors = []; + + // Returns wrapped plugin function + function safeTry( fn, pluginName ) { + return function() { + + // When Popcorn.plugin.debug is true, do not suppress errors + if ( Popcorn.plugin.debug ) { + return fn.apply( this, arguments ); + } + + try { + return fn.apply( this, arguments ); + } catch ( ex ) { + + // Push plugin function errors into logging queue + Popcorn.plugin.errors.push({ + plugin: pluginName, + thrown: ex, + source: fn.toString() + }); + + // Trigger an error that the instance can listen for + // and react to + this.emit( "pluginerror", Popcorn.plugin.errors ); + } + }; + } + + // Debug-mode flag for plugin development + // True for Popcorn development versions, false for stable/tagged versions + Popcorn.plugin.debug = ( Popcorn.version === "@" + "VERSION" ); + + // removePlugin( type ) removes all tracks of that from all instances of popcorn + // removePlugin( obj, type ) removes all tracks of type from obj, where obj is a single instance of popcorn + Popcorn.removePlugin = function( obj, name ) { + + // Check if we are removing plugin from an instance or from all of Popcorn + if ( !name ) { + + // Fix the order + name = obj; + obj = Popcorn.p; + + if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) { + Popcorn.error( "'" + name + "' is a protected function name" ); + return; + } + + var registryLen = Popcorn.registry.length, + registryIdx; + + // remove plugin reference from registry + for ( registryIdx = 0; registryIdx < registryLen; registryIdx++ ) { + if ( Popcorn.registry[ registryIdx ].name === name ) { + Popcorn.registry.splice( registryIdx, 1 ); + delete Popcorn.registryByName[ name ]; + delete Popcorn.manifest[ name ]; + + // delete the plugin + delete obj[ name ]; + + // plugin found and removed, stop checking, we are done + return; + } + } + + } + + var byStart = obj.data.trackEvents.byStart, + byEnd = obj.data.trackEvents.byEnd, + animating = obj.data.trackEvents.animating, + idx, sl; + + // remove all trackEvents + for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) { + + if ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) { + + byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] ); + + byStart.splice( idx, 1 ); + + // update for loop if something removed, but keep checking + idx--; sl--; + if ( obj.data.trackEvents.startIndex <= idx ) { + obj.data.trackEvents.startIndex--; + obj.data.trackEvents.endIndex--; + } + } + + // clean any remaining references in the end index + // we do this seperate from the above check because they might not be in the same order + if ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) { + + byEnd.splice( idx, 1 ); + } + } + + //remove all animating events + for ( idx = 0, sl = animating.length; idx < sl; idx++ ) { + + if ( animating[ idx ] && animating[ idx ]._natives && animating[ idx ]._natives.type === name ) { + + animating.splice( idx, 1 ); + + // update for loop if something removed, but keep checking + idx--; sl--; + } + } + + }; + + Popcorn.compositions = {}; + + // Plugin inheritance + Popcorn.compose = function( name, definition, manifest ) { + + // If `manifest` arg is undefined, check for manifest within the `definition` object + // If no `definition.manifest`, an empty object is a sufficient fallback + Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {}; + + // register the effect by name + Popcorn.compositions[ name ] = definition; + }; + + Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose; + + var rnaiveExpr = /^(?:\.|#|\[)/; + + // Basic DOM utilities and helpers API. See #1037 + Popcorn.dom = { + debug: false, + // Popcorn.dom.find( selector, context ) + // + // Returns the first element that matches the specified selector + // Optionally provide a context element, defaults to `document` + // + // eg. + // Popcorn.dom.find("video") returns the first video element + // Popcorn.dom.find("#foo") returns the first element with `id="foo"` + // Popcorn.dom.find("foo") returns the first element with `id="foo"` + // Note: Popcorn.dom.find("foo") is the only allowed deviation + // from valid querySelector selector syntax + // + // Popcorn.dom.find(".baz") returns the first element with `class="baz"` + // Popcorn.dom.find("[preload]") returns the first element with `preload="..."` + // ... + // See https://developer.mozilla.org/En/DOM/Document.querySelector + // + // + find: function( selector, context ) { + var node = null; + + // Default context is the `document` + context = context || document; + + if ( selector ) { + + // If the selector does not begin with "#", "." or "[", + // it could be either a nodeName or ID w/o "#" + if ( !rnaiveExpr.test( selector ) ) { + + // Try finding an element that matches by ID first + node = document.getElementById( selector ); + + // If a match was found by ID, return the element + if ( node !== null ) { + return node; + } + } + // Assume no elements have been found yet + // Catch any invalid selector syntax errors and bury them. + try { + node = context.querySelector( selector ); + } catch ( e ) { + if ( Popcorn.dom.debug ) { + throw new Error(e); + } + } + } + return node; + } + }; + + // Cache references to reused RegExps + var rparams = /\?/, + // XHR Setup object + setup = { + ajax: null, + url: "", + data: "", + dataType: "", + success: Popcorn.nop, + type: "GET", + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8" + }; + + Popcorn.xhr = function( options ) { + var settings; + + options.dataType = options.dataType && options.dataType.toLowerCase() || null; + + if ( options.dataType && + ( options.dataType === "jsonp" || options.dataType === "script" ) ) { + + Popcorn.xhr.getJSONP( + options.url, + options.success, + options.dataType === "script" + ); + return; + } + + // Merge the "setup" defaults and custom "options" + // into a new plain object. + settings = Popcorn.extend( {}, setup, options ); + + // Create new XMLHttpRequest object + settings.ajax = new XMLHttpRequest(); + + if ( settings.ajax ) { + + if ( settings.type === "GET" && settings.data ) { + + // append query string + settings.url += ( rparams.test( settings.url ) ? "&" : "?" ) + settings.data; + + // Garbage collect and reset settings.data + settings.data = null; + } + + // Open the request + settings.ajax.open( settings.type, settings.url, settings.async ); + + // For POST, set the content-type request header + if ( settings.type === "POST" ) { + settings.ajax.setRequestHeader( + "Content-Type", settings.contentType + ); + } + + settings.ajax.send( settings.data || null ); + + return Popcorn.xhr.httpData( settings ); + } + }; + + + Popcorn.xhr.httpData = function( settings ) { + + var data, json = null, + parser, xml = null; + + settings.ajax.onreadystatechange = function() { + + if ( settings.ajax.readyState === 4 ) { + + try { + json = JSON.parse( settings.ajax.responseText ); + } catch( e ) { + //suppress + } + + data = { + xml: settings.ajax.responseXML, + text: settings.ajax.responseText, + json: json + }; + + // Normalize: data.xml is non-null in IE9 regardless of if response is valid xml + if ( !data.xml || !data.xml.documentElement ) { + data.xml = null; + + try { + parser = new DOMParser(); + xml = parser.parseFromString( settings.ajax.responseText, "text/xml" ); + + if ( !xml.getElementsByTagName( "parsererror" ).length ) { + data.xml = xml; + } + } catch ( e ) { + // data.xml remains null + } + } + + // If a dataType was specified, return that type of data + if ( settings.dataType ) { + data = data[ settings.dataType ]; + } + + + settings.success.call( settings.ajax, data ); + + } + }; + return data; + }; + + Popcorn.xhr.getJSONP = function( url, success, isScript ) { + + var head = document.head || document.getElementsByTagName( "head" )[ 0 ] || document.documentElement, + script = document.createElement( "script" ), + isFired = false, + params = [], + rjsonp = /(=)\?(?=&|$)|\?\?/, + replaceInUrl, prefix, paramStr, callback, callparam; + + if ( !isScript ) { + + // is there a calback already in the url + callparam = url.match( /(callback=[^&]*)/ ); + + if ( callparam !== null && callparam.length ) { + + prefix = callparam[ 1 ].split( "=" )[ 1 ]; + + // Since we need to support developer specified callbacks + // and placeholders in harmony, make sure matches to "callback=" + // aren't just placeholders. + // We coded ourselves into a corner here. + // JSONP callbacks should never have been + // allowed to have developer specified callbacks + if ( prefix === "?" ) { + prefix = "jsonp"; + } + + // get the callback name + callback = Popcorn.guid( prefix ); + + // replace existing callback name with unique callback name + url = url.replace( /(callback=[^&]*)/, "callback=" + callback ); + } else { + + callback = Popcorn.guid( "jsonp" ); + + if ( rjsonp.test( url ) ) { + url = url.replace( rjsonp, "$1" + callback ); + } + + // split on first question mark, + // this is to capture the query string + params = url.split( /\?(.+)?/ ); + + // rebuild url with callback + url = params[ 0 ] + "?"; + if ( params[ 1 ] ) { + url += params[ 1 ] + "&"; + } + url += "callback=" + callback; + } + + // Define the JSONP success callback globally + window[ callback ] = function( data ) { + // Fire success callbacks + success && success( data ); + isFired = true; + }; + } + + script.addEventListener( "load", function() { + + // Handling remote script loading callbacks + if ( isScript ) { + // getScript + success && success(); + } + + // Executing for JSONP requests + if ( isFired ) { + // Garbage collect the callback + delete window[ callback ]; + } + // Garbage collect the script resource + head.removeChild( script ); + }, false ); + + script.addEventListener( "error", function( e ) { + // Handling remote script loading callbacks + success && success( { error: e } ); + + // Executing for JSONP requests + if ( !isScript ) { + // Garbage collect the callback + delete window[ callback ]; + } + // Garbage collect the script resource + head.removeChild( script ); + }, false ); + + script.src = url; + head.insertBefore( script, head.firstChild ); + + return; + }; + + Popcorn.getJSONP = Popcorn.xhr.getJSONP; + + Popcorn.getScript = Popcorn.xhr.getScript = function( url, success ) { + + return Popcorn.xhr.getJSONP( url, success, true ); + }; + + Popcorn.util = { + // Simple function to parse a timestamp into seconds + // Acceptable formats are: + // HH:MM:SS.MMM + // HH:MM:SS;FF + // Hours and minutes are optional. They default to 0 + toSeconds: function( timeStr, framerate ) { + // Hours and minutes are optional + // Seconds must be specified + // Seconds can be followed by milliseconds OR by the frame information + var validTimeFormat = /^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/, + errorMessage = "Invalid time format", + digitPairs, lastIndex, lastPair, firstPair, + frameInfo, frameTime; + + if ( typeof timeStr === "number" ) { + return timeStr; + } + + if ( typeof timeStr === "string" && + !validTimeFormat.test( timeStr ) ) { + Popcorn.error( errorMessage ); + } + + digitPairs = timeStr.split( ":" ); + lastIndex = digitPairs.length - 1; + lastPair = digitPairs[ lastIndex ]; + + // Fix last element: + if ( lastPair.indexOf( ";" ) > -1 ) { + + frameInfo = lastPair.split( ";" ); + frameTime = 0; + + if ( framerate && ( typeof framerate === "number" ) ) { + frameTime = parseFloat( frameInfo[ 1 ], 10 ) / framerate; + } + + digitPairs[ lastIndex ] = parseInt( frameInfo[ 0 ], 10 ) + frameTime; + } + + firstPair = digitPairs[ 0 ]; + + return { + + 1: parseFloat( firstPair, 10 ), + + 2: ( parseInt( firstPair, 10 ) * 60 ) + + parseFloat( digitPairs[ 1 ], 10 ), + + 3: ( parseInt( firstPair, 10 ) * 3600 ) + + ( parseInt( digitPairs[ 1 ], 10 ) * 60 ) + + parseFloat( digitPairs[ 2 ], 10 ) + + }[ digitPairs.length || 1 ]; + } + }; + + // alias for exec function + Popcorn.p.cue = Popcorn.p.exec; + + // Protected API methods + Popcorn.protect = { + natives: getKeys( Popcorn.p ).map(function( val ) { + return val.toLowerCase(); + }) + }; + + // Setup logging for deprecated methods + Popcorn.forEach({ + // Deprecated: Recommended + "listen": "on", + "unlisten": "off", + "trigger": "emit", + "exec": "cue" + + }, function( recommend, api ) { + var original = Popcorn.p[ api ]; + // Override the deprecated api method with a method of the same name + // that logs a warning and defers to the new recommended method + Popcorn.p[ api ] = function() { + if ( typeof console !== "undefined" && console.warn ) { + console.warn( + "Deprecated method '" + api + "', " + + (recommend == null ? "do not use." : "use '" + recommend + "' instead." ) + ); + + // Restore api after first warning + Popcorn.p[ api ] = original; + } + return Popcorn.p[ recommend ].apply( this, [].slice.call( arguments ) ); + }; + }); + + + // Exposes Popcorn to global context + global.Popcorn = Popcorn; + +})(window, window.document); diff --git a/lib/popcorn.player.js b/lib/popcorn.player.js new file mode 100644 index 00000000..7e154f4f --- /dev/null +++ b/lib/popcorn.player.js @@ -0,0 +1,437 @@ +(function( Popcorn ) { + + // combines calls of two function calls into one + var combineFn = function( first, second ) { + + first = first || Popcorn.nop; + second = second || Popcorn.nop; + + return function() { + + first.apply( this, arguments ); + second.apply( this, arguments ); + }; + }; + + // ID string matching + var rIdExp = /^(#([\w\-\_\.]+))$/; + + Popcorn.player = function( name, player ) { + + // return early if a player already exists under this name + if ( Popcorn[ name ] ) { + + return; + } + + player = player || {}; + + var playerFn = function( target, src, options ) { + + options = options || {}; + + // List of events + var date = new Date() / 1000, + baselineTime = date, + currentTime = 0, + readyState = 0, + volume = 1, + muted = false, + events = {}, + + // The container div of the resource + container = typeof target === "string" ? Popcorn.dom.find( target ) : target, + basePlayer = {}, + timeout, + popcorn; + + if ( !Object.prototype.__defineGetter__ ) { + + basePlayer = container || document.createElement( "div" ); + } + + // copies a div into the media object + for( var val in container ) { + + // don't copy properties if using container as baseplayer + if ( val in basePlayer ) { + + continue; + } + + if ( typeof container[ val ] === "object" ) { + + basePlayer[ val ] = container[ val ]; + } else if ( typeof container[ val ] === "function" ) { + + basePlayer[ val ] = (function( value ) { + + // this is a stupid ugly kludgy hack in honour of Safari + // in Safari a NodeList is a function, not an object + if ( "length" in container[ value ] && !container[ value ].call ) { + + return container[ value ]; + } else { + + return function() { + + return container[ value ].apply( container, arguments ); + }; + } + }( val )); + } else { + + Popcorn.player.defineProperty( basePlayer, val, { + get: (function( value ) { + + return function() { + + return container[ value ]; + }; + }( val )), + set: Popcorn.nop, + configurable: true + }); + } + } + + var timeupdate = function() { + + date = new Date() / 1000; + + if ( !basePlayer.paused ) { + + basePlayer.currentTime = basePlayer.currentTime + ( date - baselineTime ); + basePlayer.dispatchEvent( "timeupdate" ); + timeout = setTimeout( timeupdate, 10 ); + } + + baselineTime = date; + }; + + basePlayer.play = function() { + + this.paused = false; + + if ( basePlayer.readyState >= 4 ) { + + baselineTime = new Date() / 1000; + basePlayer.dispatchEvent( "play" ); + timeupdate(); + } + }; + + basePlayer.pause = function() { + + this.paused = true; + basePlayer.dispatchEvent( "pause" ); + }; + + Popcorn.player.defineProperty( basePlayer, "currentTime", { + get: function() { + + return currentTime; + }, + set: function( val ) { + + // make sure val is a number + currentTime = +val; + basePlayer.dispatchEvent( "timeupdate" ); + + return currentTime; + }, + configurable: true + }); + + Popcorn.player.defineProperty( basePlayer, "volume", { + get: function() { + + return volume; + }, + set: function( val ) { + + // make sure val is a number + volume = +val; + basePlayer.dispatchEvent( "volumechange" ); + return volume; + }, + configurable: true + }); + + Popcorn.player.defineProperty( basePlayer, "muted", { + get: function() { + + return muted; + }, + set: function( val ) { + + // make sure val is a number + muted = +val; + basePlayer.dispatchEvent( "volumechange" ); + return muted; + }, + configurable: true + }); + + Popcorn.player.defineProperty( basePlayer, "readyState", { + get: function() { + + return readyState; + }, + set: function( val ) { + + readyState = val; + return readyState; + }, + configurable: true + }); + + // Adds an event listener to the object + basePlayer.addEventListener = function( evtName, fn ) { + + if ( !events[ evtName ] ) { + + events[ evtName ] = []; + } + + events[ evtName ].push( fn ); + return fn; + }; + + // Removes an event listener from the object + basePlayer.removeEventListener = function( evtName, fn ) { + + var i, + listeners = events[ evtName ]; + + if ( !listeners ){ + + return; + } + + // walk backwards so we can safely splice + for ( i = events[ evtName ].length - 1; i >= 0; i-- ) { + + if( fn === listeners[ i ] ) { + + listeners.splice(i, 1); + } + } + + return fn; + }; + + // Can take event object or simple string + basePlayer.dispatchEvent = function( oEvent ) { + + var evt, + self = this, + eventInterface, + eventName = oEvent.type; + + // A string was passed, create event object + if ( !eventName ) { + + eventName = oEvent; + eventInterface = Popcorn.events.getInterface( eventName ); + + if ( eventInterface ) { + + evt = document.createEvent( eventInterface ); + evt.initEvent( eventName, true, true, window, 1 ); + } + } + + if ( events[ eventName ] ) { + + for ( var i = events[ eventName ].length - 1; i >= 0; i-- ) { + + events[ eventName ][ i ].call( self, evt, self ); + } + } + }; + + // Attempt to get src from playerFn parameter + basePlayer.src = src || ""; + basePlayer.duration = 0; + basePlayer.paused = true; + basePlayer.ended = 0; + + options && options.events && Popcorn.forEach( options.events, function( val, key ) { + + basePlayer.addEventListener( key, val, false ); + }); + + // true and undefined returns on canPlayType means we should attempt to use it, + // false means we cannot play this type + if ( player._canPlayType( container.nodeName, src ) !== false ) { + + if ( player._setup ) { + + player._setup.call( basePlayer, options ); + } else { + + // there is no setup, which means there is nothing to load + basePlayer.readyState = 4; + basePlayer.dispatchEvent( "loadedmetadata" ); + basePlayer.dispatchEvent( "loadeddata" ); + basePlayer.dispatchEvent( "canplaythrough" ); + } + } else { + + // Asynchronous so that users can catch this event + setTimeout( function() { + basePlayer.dispatchEvent( "error" ); + }, 0 ); + } + + popcorn = new Popcorn.p.init( basePlayer, options ); + + if ( player._teardown ) { + + popcorn.destroy = combineFn( popcorn.destroy, function() { + + player._teardown.call( basePlayer, options ); + }); + } + + return popcorn; + }; + + playerFn.canPlayType = player._canPlayType = player._canPlayType || Popcorn.nop; + + Popcorn[ name ] = Popcorn.player.registry[ name ] = playerFn; + }; + + Popcorn.player.registry = {}; + + Popcorn.player.defineProperty = Object.defineProperty || function( object, description, options ) { + + object.__defineGetter__( description, options.get || Popcorn.nop ); + 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 ](); + } + }; + }; + + // Popcorn.smart will attempt to find you a wrapper or player. If it can't do that, + // it will default to using an HTML5 video in the target. + Popcorn.smart = function( target, src, options ) { + var node = typeof target === "string" ? Popcorn.dom.find( target ) : target, + i, srci, j, media, mediaWrapper, popcorn, srcLength, + // We leave HTMLVideoElement and HTMLAudioElement wrappers out + // of the mix, since we'll default to HTML5 video if nothing + // else works. Waiting on #1254 before we add YouTube to this. + wrappers = "HTMLYouTubeVideoElement HTMLVimeoVideoElement HTMLSoundCloudAudioElement HTMLNullVideoElement".split(" "); + + if ( !node ) { + Popcorn.error( "Specified target `" + target + "` was not found." ); + return; + } + + // If our src is not an array, create an array of one. + src = typeof src === "string" ? [ src ] : src; + + // Loop through each src, and find the first playable. + for ( i = 0, srcLength = src.length; i < srcLength; i++ ) { + srci = src[ i ]; + + // See if we can use a wrapper directly, if not, try players. + for ( j = 0; j < wrappers.length; j++ ) { + mediaWrapper = Popcorn[ wrappers[ j ] ]; + if ( mediaWrapper && mediaWrapper._canPlaySrc( srci ) === "probably" ) { + media = mediaWrapper( node ); + popcorn = Popcorn( media, options ); + // Set src, but not until after we return the media so the caller + // can get error events, if any. + setTimeout( function() { + media.src = srci; + }, 0 ); + return popcorn; + } + } + + // No wrapper can play this, check players. + for ( var key in Popcorn.player.registry ) { + if ( Popcorn.player.registry.hasOwnProperty( key ) ) { + if ( Popcorn.player.registry[ key ].canPlayType( node.nodeName, srci ) ) { + // Popcorn.smart( player, src, /* options */ ) + return Popcorn[ key ]( node, srci, options ); + } + } + } + } + + // If we don't have any players or wrappers that can handle this, + // Default to using HTML5 video. Similar to the HTMLVideoElement + // wrapper, we put a video in the div passed to us via: + // Popcorn.smart( div, src, options ) + var videoHTML, + videoElement, + videoID = Popcorn.guid( "popcorn-video-" ), + videoHTMLContainer = document.createElement( "div" ); + + videoHTMLContainer.style.width = "100%"; + videoHTMLContainer.style.height = "100%"; + + // If we only have one source, do not bother with source elements. + // This means we don't have the IE9 hack, + // and we can properly listen to error events. + // That way an error event can be told to backup to Flash if it fails. + if ( src.length === 1 ) { + videoElement = document.createElement( "video" ); + videoElement.id = videoID; + node.appendChild( videoElement ); + setTimeout( function() { + // Hack to decode html characters like & to & + var decodeDiv = document.createElement( "div" ); + decodeDiv.innerHTML = src[ 0 ]; + + videoElement.src = decodeDiv.firstChild.nodeValue; + }, 0 ); + return Popcorn( '#' + videoID, options ); + } + + node.appendChild( videoHTMLContainer ); + // IE9 doesn't like dynamic creation of source elements on
  • from the page HTML. Allows page to be valid HTML, while not interfereing with display animations @@ -311,7 +311,7 @@ if(this.playlist.length && index !== undefined) { $(this.cssSelector.playlist + " .jp-playlist-current").removeClass("jp-playlist-current"); $(this.cssSelector.playlist + " li:nth-child(" + (index + 1) + ")").addClass("jp-playlist-current").find(".jp-playlist-item").addClass("jp-playlist-current"); - $(this.cssSelector.title + " li").html(this.playlist[index].title + (this.playlist[index].artist ? " " : "")); + // $(this.cssSelector.details + " li").html("" + (this.playlist[index].artist ? " " : "")); } }, setPlaylist: function(playlist) { From 2216c7cba1e6cb1a6026e89822547bf3aa3b19d6 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Sun, 8 Jun 2014 22:16:37 +0100 Subject: [PATCH 060/218] Updated playlist to use the autoBlur option of jplayer core --- add-on/jplayer.playlist.js | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index 48e5cd0f..428e4b78 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -92,26 +92,35 @@ } }); + // The blur function executes in the context of the click handler + var blur = function() { + if($(this.cssSelector.jPlayer).jPlayer("option", "autoBlur")) { + $(this).blur(); + } + }; + // Create click handlers for the extra buttons that do playlist functions. - $(this.cssSelector.previous).click(function() { + $(this.cssSelector.previous).click(function(e) { + e.preventDefault(); self.previous(); - $(this).blur(); - return false; + blur.call(this); }); - $(this.cssSelector.next).click(function() { + $(this.cssSelector.next).click(function(e) { + e.preventDefault(); self.next(); - $(this).blur(); - return false; + blur.call(this); }); - $(this.cssSelector.shuffle).click(function() { + $(this.cssSelector.shuffle).click(function(e) { + e.preventDefault(); self.shuffle(true); - return false; + blur.call(this); }); - $(this.cssSelector.shuffleOff).click(function() { + $(this.cssSelector.shuffleOff).click(function(e) { + e.preventDefault(); self.shuffle(false); - return false; + blur.call(this); }).hide(); // Put the title in its initial display state From 54408ecfb11d2f5b19132f8fcbcbdd9992bd33ce Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Sun, 8 Jun 2014 23:02:25 +0100 Subject: [PATCH 061/218] Playlist - Fixed bug in autoBlur - Added useStateClassSkin support. --- add-on/jplayer.playlist.js | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index 428e4b78..45b29b8e 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -7,7 +7,7 @@ * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.3.1 + * Version: 2.3.2 * Date: 8th June 2014 * * Requires: @@ -44,6 +44,9 @@ self.previous(); } } + }, + stateClass: { + shuffled: "jp-state-shuffled" } }, this._options, options); // Object: The jPlayer constructor options for this playlist and the playlist options @@ -94,7 +97,7 @@ // The blur function executes in the context of the click handler var blur = function() { - if($(this.cssSelector.jPlayer).jPlayer("option", "autoBlur")) { + if($(self.cssSelector.jPlayer).jPlayer("option", "autoBlur")) { $(this).blur(); } }; @@ -114,7 +117,11 @@ $(this.cssSelector.shuffle).click(function(e) { e.preventDefault(); - self.shuffle(true); + if(self.shuffled && $(self.cssSelector.jPlayer).jPlayer("option", "useStateClassSkin")) { + self.shuffle(false); + } else { + self.shuffle(true); + } blur.call(this); }); $(this.cssSelector.shuffleOff).click(function(e) { @@ -308,12 +315,20 @@ } else { $(this.cssSelector.playlist + " ." + this.options.playlistOptions.removeItemClass).hide(); } + if(this.shuffled) { - $(this.cssSelector.shuffleOff).show(); - $(this.cssSelector.shuffle).hide(); + $(this.cssSelector.jPlayer).jPlayer("addStateClass", "shuffled"); } else { - $(this.cssSelector.shuffleOff).hide(); - $(this.cssSelector.shuffle).show(); + $(this.cssSelector.jPlayer).jPlayer("removeStateClass", "shuffled"); + } + if($(this.cssSelector.shuffle).length && $(this.cssSelector.shuffleOff).length) { + if(this.shuffled) { + $(this.cssSelector.shuffleOff).show(); + $(this.cssSelector.shuffle).hide(); + } else { + $(this.cssSelector.shuffleOff).hide(); + $(this.cssSelector.shuffle).show(); + } } }, _highlight: function(index) { From e7a426d48d13f2bfaaebc68627d6c65ddd86e458 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Mon, 9 Jun 2014 18:04:12 +0100 Subject: [PATCH 062/218] Playlist - autoBlur now affects the track selection, free DL and remove links. --- add-on/jplayer.playlist.js | 42 ++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index 45b29b8e..f6e886ac 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -7,8 +7,8 @@ * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.3.2 - * Date: 8th June 2014 + * Version: 2.3.3 + * Date: 9th June 2014 * * Requires: * - jQuery 1.7.0+ @@ -95,24 +95,17 @@ } }); - // The blur function executes in the context of the click handler - var blur = function() { - if($(self.cssSelector.jPlayer).jPlayer("option", "autoBlur")) { - $(this).blur(); - } - }; - // Create click handlers for the extra buttons that do playlist functions. $(this.cssSelector.previous).click(function(e) { e.preventDefault(); self.previous(); - blur.call(this); + self.blur(this); }); $(this.cssSelector.next).click(function(e) { e.preventDefault(); self.next(); - blur.call(this); + self.blur(this); }); $(this.cssSelector.shuffle).click(function(e) { @@ -122,12 +115,12 @@ } else { self.shuffle(true); } - blur.call(this); + self.blur(this); }); $(this.cssSelector.shuffleOff).click(function(e) { e.preventDefault(); self.shuffle(false); - blur.call(this); + self.blur(this); }).hide(); // Put the title in its initial display state @@ -283,30 +276,30 @@ _createItemHandlers: function() { var self = this; // Create live handlers for the playlist items - $(this.cssSelector.playlist).off("click", "a." + this.options.playlistOptions.itemClass).on("click", "a." + this.options.playlistOptions.itemClass, function() { + $(this.cssSelector.playlist).off("click", "a." + this.options.playlistOptions.itemClass).on("click", "a." + this.options.playlistOptions.itemClass, function(e) { + e.preventDefault(); var index = $(this).parent().parent().index(); if(self.current !== index) { self.play(index); } else { $(self.cssSelector.jPlayer).jPlayer("play"); } - $(this).blur(); - return false; + self.blur(this); }); // Create live handlers that disable free media links to force access via right click - $(this.cssSelector.playlist).off("click", "a." + this.options.playlistOptions.freeItemClass).on("click", "a." + this.options.playlistOptions.freeItemClass, function() { + $(this.cssSelector.playlist).off("click", "a." + this.options.playlistOptions.freeItemClass).on("click", "a." + this.options.playlistOptions.freeItemClass, function(e) { + e.preventDefault(); $(this).parent().parent().find("." + self.options.playlistOptions.itemClass).click(); - $(this).blur(); - return false; + self.blur(this); }); // Create live handlers for the remove controls - $(this.cssSelector.playlist).off("click", "a." + this.options.playlistOptions.removeItemClass).on("click", "a." + this.options.playlistOptions.removeItemClass, function() { + $(this.cssSelector.playlist).off("click", "a." + this.options.playlistOptions.removeItemClass).on("click", "a." + this.options.playlistOptions.removeItemClass, function(e) { + e.preventDefault(); var index = $(this).parent().parent().index(); self.remove(index); - $(this).blur(); - return false; + self.blur(this); }); }, _updateControls: function() { @@ -489,6 +482,11 @@ $(this).slideDown(self.options.playlistOptions.shuffleTime); }); } + }, + blur: function(that) { + if($(this.cssSelector.jPlayer).jPlayer("option", "autoBlur")) { + $(that).blur(); + } } }; })(jQuery); From cf430360126765a06cd6a20d34ba23753479c0c2 Mon Sep 17 00:00:00 2001 From: Mark Panaghiston Date: Mon, 9 Jun 2014 18:11:39 +0100 Subject: [PATCH 063/218] Playlist - removed tabindex from free DL link and changed track link to tabindex 0 --- add-on/jplayer.playlist.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/add-on/jplayer.playlist.js b/add-on/jplayer.playlist.js index f6e886ac..057f3eae 100644 --- a/add-on/jplayer.playlist.js +++ b/add-on/jplayer.playlist.js @@ -7,7 +7,7 @@ * http://www.opensource.org/licenses/MIT * * Author: Mark J Panaghiston - * Version: 2.3.3 + * Version: 2.3.4 * Date: 9th June 2014 * * Requires: @@ -261,14 +261,14 @@ } else { listItem += " | "; } - listItem += "" + property + ""; + listItem += "" + property + ""; } }); listItem += ")"; } // The title is given next in the HTML otherwise the float:right on the free media corrupts in IE6/7 - listItem += "" + media.title + (media.artist ? " " : "") + ""; + listItem += "" + media.title + (media.artist ? " " : "") + ""; listItem += "