Cleaning up jplayer
This commit is contained in:
		
							parent
							
								
									92e925e1ee
								
							
						
					
					
						commit
						69b392b739
					
				@ -1,31 +0,0 @@
 | 
			
		||||
jPlayer : HTML5 Audio & Video for jQuery
 | 
			
		||||
 | 
			
		||||
http://www.jplayer.org/
 | 
			
		||||
 | 
			
		||||
What is jPlayer?
 | 
			
		||||
 | 
			
		||||
jPlayer is a jQuery plugin that allows you to:
 | 
			
		||||
 | 
			
		||||
 * play and control media files in your webpage
 | 
			
		||||
 * create and style a media player using just HTML and CSS
 | 
			
		||||
 * add audio and video to your jQuery projects
 | 
			
		||||
 * support more devices using HTML5
 | 
			
		||||
 * support older browsers using a Flash Fallback
 | 
			
		||||
 * control media on your website using a JavaScript API
 | 
			
		||||
 | 
			
		||||
jPlayer supports:
 | 
			
		||||
 * HTML5: mp3, m4a (AAC), m4v (H.264), ogv*, oga*, wav*, webm*
 | 
			
		||||
 * Flash: mp3, m4a (AAC), m4v (H.264)
 | 
			
		||||
(*) Optional counterpart formats to increase HTML5 x-browser support.
 | 
			
		||||
 | 
			
		||||
Dual licensed under the MIT and GPL licenses.
 | 
			
		||||
 * http://www.opensource.org/licenses/mit-license.php
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 | 
			
		||||
Quick Start Guide:
 | 
			
		||||
http://www.jplayer.org/latest/quick-start-guide/
 | 
			
		||||
 | 
			
		||||
Developer Guide and API Reference:
 | 
			
		||||
http://www.jplayer.org/latest/developer-guide/
 | 
			
		||||
 | 
			
		||||
Author: Mark J Panaghiston
 | 
			
		||||
@ -1,415 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * jPlayer Plugin for jQuery JavaScript Library
 | 
			
		||||
 * http://www.happyworm.com/jquery/jplayer
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009 - 2011 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
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Mark J Panaghiston
 | 
			
		||||
 * Version: 2.1.0
 | 
			
		||||
 * Date: 1st September 2011
 | 
			
		||||
 *
 | 
			
		||||
 * 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);
 | 
			
		||||
 *
 | 
			
		||||
 * Compiled using: Adobe Flex Compiler (mxmlc) Version 4.5.1 build 21328
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package {
 | 
			
		||||
	import flash.system.Security;
 | 
			
		||||
	import flash.external.ExternalInterface;
 | 
			
		||||
 | 
			
		||||
	import flash.utils.Timer;
 | 
			
		||||
	import flash.events.TimerEvent;
 | 
			
		||||
	
 | 
			
		||||
	import flash.text.TextField;
 | 
			
		||||
	import flash.text.TextFormat;
 | 
			
		||||
 | 
			
		||||
	import flash.events.KeyboardEvent;
 | 
			
		||||
 | 
			
		||||
	import flash.display.Sprite;
 | 
			
		||||
	import happyworm.jPlayer.*;
 | 
			
		||||
 | 
			
		||||
	import flash.display.StageAlign;
 | 
			
		||||
	import flash.display.StageScaleMode;
 | 
			
		||||
	import flash.events.Event;
 | 
			
		||||
	import flash.events.MouseEvent;
 | 
			
		||||
 | 
			
		||||
	import flash.ui.ContextMenu;
 | 
			
		||||
	import flash.ui.ContextMenuItem;
 | 
			
		||||
	import flash.events.ContextMenuEvent;
 | 
			
		||||
	import flash.net.URLRequest;
 | 
			
		||||
	import flash.net.navigateToURL;
 | 
			
		||||
 | 
			
		||||
	public class Jplayer extends Sprite {
 | 
			
		||||
		private var jQuery:String;
 | 
			
		||||
		private var sentNumberFractionDigits:uint = 2;
 | 
			
		||||
 | 
			
		||||
		public var commonStatus:JplayerStatus = new JplayerStatus(); // Used for inital ready event so volume is correct.
 | 
			
		||||
 | 
			
		||||
		private var myInitTimer:Timer = new Timer(100, 0);
 | 
			
		||||
 | 
			
		||||
		private var myMp3Player:JplayerMp3;
 | 
			
		||||
		private var myMp4Player:JplayerMp4;
 | 
			
		||||
 | 
			
		||||
		private var isMp3:Boolean = false;
 | 
			
		||||
		private var isVideo:Boolean = false;
 | 
			
		||||
 | 
			
		||||
		private var txLog:TextField;
 | 
			
		||||
		private var debug:Boolean = false; // Set debug to false for release compile!
 | 
			
		||||
 | 
			
		||||
		public function Jplayer() {
 | 
			
		||||
			flash.system.Security.allowDomain("*");
 | 
			
		||||
 | 
			
		||||
			jQuery = loaderInfo.parameters.jQuery + "('#" + loaderInfo.parameters.id + "').jPlayer";
 | 
			
		||||
			commonStatus.volume = Number(loaderInfo.parameters.vol);
 | 
			
		||||
			commonStatus.muted = loaderInfo.parameters.muted == "true";
 | 
			
		||||
 | 
			
		||||
			stage.scaleMode = StageScaleMode.NO_SCALE;
 | 
			
		||||
			stage.align = StageAlign.TOP_LEFT;
 | 
			
		||||
			stage.addEventListener(Event.RESIZE, resizeHandler);
 | 
			
		||||
			stage.addEventListener(MouseEvent.CLICK, clickHandler);
 | 
			
		||||
 | 
			
		||||
			var initialVolume:Number = commonStatus.volume;
 | 
			
		||||
			if(commonStatus.muted) {
 | 
			
		||||
				initialVolume = 0;
 | 
			
		||||
			}
 | 
			
		||||
			myMp3Player = new JplayerMp3(initialVolume);
 | 
			
		||||
			addChild(myMp3Player);
 | 
			
		||||
 | 
			
		||||
			myMp4Player = new JplayerMp4(initialVolume);
 | 
			
		||||
			addChild(myMp4Player);
 | 
			
		||||
 | 
			
		||||
			setupListeners(!isMp3, isMp3); // Set up the listeners to the default isMp3 state.
 | 
			
		||||
 | 
			
		||||
			// The ContextMenu only partially works. The menu select events never occur.
 | 
			
		||||
			// Investigated and it is something to do with the way jPlayer inserts the Flash on the page.
 | 
			
		||||
			// A simple test inserting the Jplayer.swf on a page using: 1) SWFObject 2.2 works. 2) AC_FL_RunContent() works.
 | 
			
		||||
			// jPlayer Flash insertion is based on SWFObject 2.2 and the resaon behind this failure is not clear. The Flash insertion HTML on the page looks similar.
 | 
			
		||||
			var myContextMenu:ContextMenu = new ContextMenu();
 | 
			
		||||
			myContextMenu.hideBuiltInItems();
 | 
			
		||||
			var menuItem_jPlayer:ContextMenuItem = new ContextMenuItem("jPlayer " + JplayerStatus.VERSION);
 | 
			
		||||
			var menuItem_happyworm:ContextMenuItem = new ContextMenuItem("© 2009-2011 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);
 | 
			
		||||
			contextMenu = myContextMenu;
 | 
			
		||||
 | 
			
		||||
			// Log console for dev compile option: debug
 | 
			
		||||
			if(debug) {
 | 
			
		||||
				txLog = new TextField();
 | 
			
		||||
				txLog.x = 5;
 | 
			
		||||
				txLog.y = 5;
 | 
			
		||||
				txLog.width = 540;
 | 
			
		||||
				txLog.height = 390;
 | 
			
		||||
				txLog.border = true;
 | 
			
		||||
				txLog.background = true;
 | 
			
		||||
				txLog.backgroundColor = 0xEEEEFF;
 | 
			
		||||
				txLog.multiline = true;
 | 
			
		||||
				txLog.text = "jPlayer " + JplayerStatus.VERSION;
 | 
			
		||||
				txLog.visible = false;
 | 
			
		||||
				this.addChild(txLog);
 | 
			
		||||
				this.stage.addEventListener(KeyboardEvent.KEY_UP, keyboardHandler);
 | 
			
		||||
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler);
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Delay init() because Firefox 3.5.7+ developed a bug with local testing in Firebug.
 | 
			
		||||
			myInitTimer.addEventListener(TimerEvent.TIMER, init);
 | 
			
		||||
			myInitTimer.start();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		private function init(e:TimerEvent):void {
 | 
			
		||||
			myInitTimer.stop();
 | 
			
		||||
			if(ExternalInterface.available) {
 | 
			
		||||
				ExternalInterface.addCallback("fl_setAudio_mp3", fl_setAudio_mp3);
 | 
			
		||||
				ExternalInterface.addCallback("fl_setAudio_m4a", fl_setAudio_m4a);
 | 
			
		||||
				ExternalInterface.addCallback("fl_setVideo_m4v", fl_setVideo_m4v);
 | 
			
		||||
				ExternalInterface.addCallback("fl_clearMedia", fl_clearMedia);
 | 
			
		||||
				ExternalInterface.addCallback("fl_load", fl_load);
 | 
			
		||||
				ExternalInterface.addCallback("fl_play", fl_play);
 | 
			
		||||
				ExternalInterface.addCallback("fl_pause", fl_pause);
 | 
			
		||||
				ExternalInterface.addCallback("fl_play_head", fl_play_head);
 | 
			
		||||
				ExternalInterface.addCallback("fl_volume", fl_volume);
 | 
			
		||||
				ExternalInterface.addCallback("fl_mute", fl_mute);
 | 
			
		||||
 | 
			
		||||
				ExternalInterface.call(jQuery, "jPlayerFlashEvent", JplayerEvent.JPLAYER_READY, extractStatusData(commonStatus)); // See JplayerStatus() class for version number.
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function setupListeners(oldMP3:Boolean, newMP3:Boolean):void {
 | 
			
		||||
			if(oldMP3 != newMP3) {
 | 
			
		||||
				if(newMP3) {
 | 
			
		||||
					listenToMp3(true);
 | 
			
		||||
					listenToMp4(false);
 | 
			
		||||
				} else {
 | 
			
		||||
					listenToMp3(false);
 | 
			
		||||
					listenToMp4(true);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function listenToMp3(active:Boolean):void {
 | 
			
		||||
			if(active) {
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
 | 
			
		||||
				
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.addEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
 | 
			
		||||
			} else {
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
 | 
			
		||||
				
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
 | 
			
		||||
				myMp3Player.removeEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function listenToMp4(active:Boolean):void {
 | 
			
		||||
			if(active) {
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp4Player.addEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerMetaDataHandler); // Note the unique handler
 | 
			
		||||
			} else {
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
 | 
			
		||||
 | 
			
		||||
				myMp4Player.removeEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerMetaDataHandler); // Note the unique handler
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_setAudio_mp3(src:String):Boolean {
 | 
			
		||||
			if (src != null) {
 | 
			
		||||
				log("fl_setAudio_mp3: "+src);
 | 
			
		||||
				setupListeners(isMp3, true);
 | 
			
		||||
				isMp3 = true;
 | 
			
		||||
				isVideo = false;
 | 
			
		||||
				myMp4Player.clearFile();
 | 
			
		||||
				myMp3Player.setFile(src);
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				log("fl_setAudio_mp3: null");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_setAudio_m4a(src:String):Boolean {
 | 
			
		||||
			if (src != null) {
 | 
			
		||||
				log("fl_setAudio_m4a: "+src);
 | 
			
		||||
				setupListeners(isMp3, false);
 | 
			
		||||
				isMp3 = false;
 | 
			
		||||
				isVideo = false;
 | 
			
		||||
				myMp3Player.clearFile();
 | 
			
		||||
				myMp4Player.setFile(src);
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				log("fl_setAudio_m4a: null");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_setVideo_m4v(src:String):Boolean {
 | 
			
		||||
			if (src != null) {
 | 
			
		||||
				log("fl_setVideo_m4v: "+src);
 | 
			
		||||
				setupListeners(isMp3, false);
 | 
			
		||||
				isMp3 = false;
 | 
			
		||||
				isVideo = true;
 | 
			
		||||
				myMp3Player.clearFile();
 | 
			
		||||
				myMp4Player.setFile(src);
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				log("fl_setVideo_m4v: null");
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_clearMedia():void {
 | 
			
		||||
			log("clearMedia.");
 | 
			
		||||
			myMp3Player.clearFile();
 | 
			
		||||
			myMp4Player.clearFile();
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_load():Boolean {
 | 
			
		||||
			log("load.");
 | 
			
		||||
			if(isMp3) {
 | 
			
		||||
				return myMp3Player.load();
 | 
			
		||||
			} else {
 | 
			
		||||
				return myMp4Player.load();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_play(time:Number = NaN):Boolean {
 | 
			
		||||
			log("play: time = " + time);
 | 
			
		||||
			if(isMp3) {
 | 
			
		||||
				return myMp3Player.play(time * 1000); // Flash uses milliseconds
 | 
			
		||||
			} else {
 | 
			
		||||
				return myMp4Player.play(time * 1000); // Flash uses milliseconds
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_pause(time:Number = NaN):Boolean {
 | 
			
		||||
			log("pause: time = " + time);
 | 
			
		||||
			if(isMp3) {
 | 
			
		||||
				return myMp3Player.pause(time * 1000); // Flash uses milliseconds
 | 
			
		||||
			} else {
 | 
			
		||||
				return myMp4Player.pause(time * 1000); // Flash uses milliseconds
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_play_head(percent:Number):Boolean {
 | 
			
		||||
			log("play_head: "+percent+"%");
 | 
			
		||||
			if(isMp3) {
 | 
			
		||||
				return myMp3Player.playHead(percent);
 | 
			
		||||
			} else {
 | 
			
		||||
				return myMp4Player.playHead(percent);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_volume(v:Number):void {
 | 
			
		||||
			log("volume: "+v);
 | 
			
		||||
			commonStatus.volume = v;
 | 
			
		||||
			if(!commonStatus.muted) {
 | 
			
		||||
				myMp3Player.setVolume(v);
 | 
			
		||||
				myMp4Player.setVolume(v);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function fl_mute(mute:Boolean):void {
 | 
			
		||||
			log("mute: "+mute);
 | 
			
		||||
			commonStatus.muted = mute;
 | 
			
		||||
			if(mute) {
 | 
			
		||||
				myMp3Player.setVolume(0);
 | 
			
		||||
				myMp4Player.setVolume(0);
 | 
			
		||||
			} else {
 | 
			
		||||
				myMp3Player.setVolume(commonStatus.volume);
 | 
			
		||||
				myMp4Player.setVolume(commonStatus.volume);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function jPlayerFlashEvent(e:JplayerEvent):void {
 | 
			
		||||
			log("jPlayer Flash Event: " + e.type + ": " + e.target);
 | 
			
		||||
			if(ExternalInterface.available) {
 | 
			
		||||
				ExternalInterface.call(jQuery, "jPlayerFlashEvent", e.type, extractStatusData(e.data));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function extractStatusData(data:JplayerStatus):Object {
 | 
			
		||||
			var myStatus:Object = {
 | 
			
		||||
				version: JplayerStatus.VERSION,
 | 
			
		||||
				src: data.src,
 | 
			
		||||
				paused: !data.isPlaying, // Changing this name requires inverting all assignments and conditional statements.
 | 
			
		||||
				srcSet: data.srcSet,
 | 
			
		||||
				seekPercent: data.seekPercent,
 | 
			
		||||
				currentPercentRelative: data.currentPercentRelative,
 | 
			
		||||
				currentPercentAbsolute: data.currentPercentAbsolute,
 | 
			
		||||
				currentTime: data.currentTime / 1000, // JavaScript uses seconds
 | 
			
		||||
				duration: data.duration / 1000, // JavaScript uses seconds
 | 
			
		||||
				volume: commonStatus.volume,
 | 
			
		||||
				muted: commonStatus.muted
 | 
			
		||||
			};
 | 
			
		||||
			log("extractStatusData: sp="+myStatus.seekPercent+" cpr="+myStatus.currentPercentRelative+" cpa="+myStatus.currentPercentAbsolute+" ct="+myStatus.currentTime+" d="+myStatus.duration);
 | 
			
		||||
			return myStatus;
 | 
			
		||||
		}
 | 
			
		||||
		private function jPlayerMetaDataHandler(e:JplayerEvent):void {
 | 
			
		||||
			log("jPlayerMetaDataHandler:" + e.target);
 | 
			
		||||
			if(ExternalInterface.available) {
 | 
			
		||||
				resizeHandler(new Event(Event.RESIZE));
 | 
			
		||||
				ExternalInterface.call(jQuery, "jPlayerFlashEvent", e.type, extractStatusData(e.data));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function resizeHandler(e:Event):void {
 | 
			
		||||
			log("resizeHandler: stageWidth = " + stage.stageWidth + " | stageHeight = " + stage.stageHeight);
 | 
			
		||||
 | 
			
		||||
			var mediaX:Number = 0;
 | 
			
		||||
			var mediaY:Number = 0;
 | 
			
		||||
			var mediaWidth:Number = 0;
 | 
			
		||||
			var mediaHeight:Number = 0;
 | 
			
		||||
 | 
			
		||||
			if(stage.stageWidth > 0 && stage.stageHeight > 0 && myMp4Player.myVideo.width > 0 && myMp4Player.myVideo.height > 0) {
 | 
			
		||||
				var aspectRatioStage:Number = stage.stageWidth / stage.stageHeight;
 | 
			
		||||
				var aspectRatioVideo:Number = myMp4Player.myVideo.width / myMp4Player.myVideo.height;
 | 
			
		||||
				if(aspectRatioStage < aspectRatioVideo) {
 | 
			
		||||
					mediaWidth = stage.stageWidth;
 | 
			
		||||
					mediaHeight = stage.stageWidth / aspectRatioVideo;
 | 
			
		||||
					mediaX = 0;
 | 
			
		||||
					mediaY = (stage.stageHeight - mediaHeight) / 2;
 | 
			
		||||
				} else {
 | 
			
		||||
					mediaWidth = stage.stageHeight * aspectRatioVideo;
 | 
			
		||||
					mediaHeight = stage.stageHeight;
 | 
			
		||||
					mediaX = (stage.stageWidth - mediaWidth) / 2;
 | 
			
		||||
					mediaY = 0;
 | 
			
		||||
				}
 | 
			
		||||
				resizeEntity(myMp4Player, mediaX, mediaY, mediaWidth, mediaHeight);
 | 
			
		||||
			}
 | 
			
		||||
			if(debug && stage.stageWidth > 20 && stage.stageHeight > 20) {
 | 
			
		||||
				txLog.width = stage.stageWidth - 10;
 | 
			
		||||
				txLog.height = stage.stageHeight - 10;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function resizeEntity(entity:Sprite, mediaX:Number, mediaY:Number, mediaWidth:Number, mediaHeight:Number):void {
 | 
			
		||||
			entity.x = mediaX;
 | 
			
		||||
			entity.y = mediaY;
 | 
			
		||||
			entity.width = mediaWidth;
 | 
			
		||||
			entity.height = mediaHeight;
 | 
			
		||||
		}
 | 
			
		||||
		private function clickHandler(e:MouseEvent):void {
 | 
			
		||||
			if(isMp3) {
 | 
			
		||||
				jPlayerFlashEvent(new JplayerEvent(JplayerEvent.JPLAYER_CLICK, myMp3Player.myStatus, "click"))
 | 
			
		||||
			} else {
 | 
			
		||||
				jPlayerFlashEvent(new JplayerEvent(JplayerEvent.JPLAYER_CLICK, myMp4Player.myStatus, "click"))
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// This event is never called. See comments in class constructor.
 | 
			
		||||
		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;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function debugMsgHandler(e:JplayerEvent):void {
 | 
			
		||||
			log(e.msg);
 | 
			
		||||
		}
 | 
			
		||||
		private function keyboardHandler(e:KeyboardEvent):void {
 | 
			
		||||
			log("keyboardHandler: e.keyCode = " + e.keyCode);
 | 
			
		||||
			switch(e.keyCode) {
 | 
			
		||||
				case 68 : // d
 | 
			
		||||
					txLog.visible = !txLog.visible;
 | 
			
		||||
					log("Toggled log display: " + txLog.visible);
 | 
			
		||||
					break;
 | 
			
		||||
				case 76 : // l
 | 
			
		||||
					if(e.ctrlKey && e.shiftKey) {
 | 
			
		||||
						txLog.text = "Cleared log.";
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@ -1,69 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * jPlayer Plugin for jQuery JavaScript Library
 | 
			
		||||
 * http://www.happyworm.com/jquery/jplayer
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009 - 2011 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
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Mark J Panaghiston
 | 
			
		||||
 * Date: 8th August 2011
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package happyworm.jPlayer {
 | 
			
		||||
	import flash.events.Event;
 | 
			
		||||
	
 | 
			
		||||
	public class JplayerEvent extends Event {
 | 
			
		||||
		
 | 
			
		||||
		// The event strings must match those in the JavaScript's $.jPlayer.event object
 | 
			
		||||
 | 
			
		||||
		public static const JPLAYER_READY:String = "jPlayer_ready";
 | 
			
		||||
		public static const JPLAYER_FLASHRESET:String = "jPlayer_flashreset"; // Handled in JavaScript
 | 
			
		||||
		public static const JPLAYER_RESIZE:String = "jPlayer_resize"; // Handled in JavaScript
 | 
			
		||||
		public static const JPLAYER_REPEAT:String = "jPlayer_repeat"; // Handled in JavaScript
 | 
			
		||||
		public static const JPLAYER_CLICK:String = "jPlayer_click";
 | 
			
		||||
		public static const JPLAYER_ERROR:String = "jPlayer_error";
 | 
			
		||||
		public static const JPLAYER_WARNING:String = "jPlayer_warning"; // Currently not used by the flash solution
 | 
			
		||||
 | 
			
		||||
		public static const JPLAYER_LOADSTART:String = "jPlayer_loadstart";
 | 
			
		||||
		public static const JPLAYER_PROGRESS:String = "jPlayer_progress";
 | 
			
		||||
		public static const JPLAYER_SUSPEND:String = "jPlayer_suspend"; // Not implemented
 | 
			
		||||
		public static const JPLAYER_ABORT:String = "jPlayer_abort"; // Not implemented
 | 
			
		||||
		public static const JPLAYER_EMPTIED:String = "jPlayer_emptied"; // Not implemented
 | 
			
		||||
		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_LOADEDDATA:String = "jPlayer_loadeddata"; // Not implemented
 | 
			
		||||
		public static const JPLAYER_WAITING:String = "jPlayer_waiting"; // Not implemented
 | 
			
		||||
		public static const JPLAYER_PLAYING:String = "jPlayer_playing"; // Not implemented
 | 
			
		||||
		public static const JPLAYER_CANPLAY:String = "jPlayer_canplay"; // Not implemented
 | 
			
		||||
		public static const JPLAYER_CANPLAYTHROUGH:String = "jPlayer_canplaythrough"; // Not implemented
 | 
			
		||||
		public static const JPLAYER_SEEKING:String = "jPlayer_seeking";
 | 
			
		||||
		public static const JPLAYER_SEEKED:String = "jPlayer_seeked";
 | 
			
		||||
		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_VOLUMECHANGE:String = "jPlayer_volumechange"; // See JavaScript
 | 
			
		||||
 | 
			
		||||
		// Events used internal to jPlayer's Flash.
 | 
			
		||||
		public static const DEBUG_MSG:String = "debug_msg";
 | 
			
		||||
 | 
			
		||||
		public var data:JplayerStatus;
 | 
			
		||||
		public var msg:String = ""
 | 
			
		||||
 | 
			
		||||
		public function JplayerEvent(type:String, data:JplayerStatus, msg:String = "", bubbles:Boolean = false, cancelable:Boolean = false) {
 | 
			
		||||
			super(type, bubbles, cancelable);
 | 
			
		||||
			this.data = data;
 | 
			
		||||
			this.msg = msg;
 | 
			
		||||
		}
 | 
			
		||||
		public override function clone():Event {
 | 
			
		||||
			return new JplayerEvent(type, data, msg, bubbles, cancelable);
 | 
			
		||||
		}
 | 
			
		||||
		public override function toString():String {
 | 
			
		||||
			return formatToString("JplayerEvent", "type", "bubbles", "cancelable", "eventPhase", "data", "msg");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,328 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * jPlayer Plugin for jQuery JavaScript Library
 | 
			
		||||
 * http://www.happyworm.com/jquery/jplayer
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009 - 2011 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
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Mark J Panaghiston
 | 
			
		||||
 * Date: 1st September 2011
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package happyworm.jPlayer {
 | 
			
		||||
	import flash.display.Sprite;
 | 
			
		||||
 | 
			
		||||
	import flash.media.Sound;
 | 
			
		||||
	import flash.media.SoundChannel;
 | 
			
		||||
	import flash.media.SoundLoaderContext;
 | 
			
		||||
	import flash.media.SoundTransform;
 | 
			
		||||
	import flash.net.URLRequest;
 | 
			
		||||
	import flash.utils.Timer;
 | 
			
		||||
	import flash.errors.IOError;
 | 
			
		||||
	import flash.events.*;
 | 
			
		||||
 | 
			
		||||
	public class JplayerMp3 extends Sprite {
 | 
			
		||||
		private var mySound:Sound = new Sound();
 | 
			
		||||
		private var myChannel:SoundChannel = new SoundChannel();
 | 
			
		||||
		private var myContext:SoundLoaderContext = new SoundLoaderContext(3000, false);
 | 
			
		||||
		private var myTransform:SoundTransform = new SoundTransform();
 | 
			
		||||
		private var myRequest:URLRequest = new URLRequest();
 | 
			
		||||
 | 
			
		||||
		private var timeUpdateTimer:Timer = new Timer(250, 0); // Matched to HTML event freq
 | 
			
		||||
		private var progressTimer:Timer = new Timer(250, 0); // Matched to HTML event freq
 | 
			
		||||
		private var seekingTimer:Timer = new Timer(100, 0); // Internal: How often seeking is checked to see if it is over.
 | 
			
		||||
		
 | 
			
		||||
		public var myStatus:JplayerStatus = new JplayerStatus();
 | 
			
		||||
 | 
			
		||||
		public function JplayerMp3(volume:Number) {
 | 
			
		||||
			timeUpdateTimer.addEventListener(TimerEvent.TIMER, timeUpdateHandler);
 | 
			
		||||
			progressTimer.addEventListener(TimerEvent.TIMER, progressHandler);
 | 
			
		||||
			seekingTimer.addEventListener(TimerEvent.TIMER, seekingHandler);
 | 
			
		||||
			setVolume(volume);
 | 
			
		||||
		}
 | 
			
		||||
		public function setFile(src:String):void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "setFile: " + src));
 | 
			
		||||
			if(myStatus.isPlaying) {
 | 
			
		||||
				myChannel.stop();
 | 
			
		||||
				progressUpdates(false);
 | 
			
		||||
				timeUpdates(false);
 | 
			
		||||
			}
 | 
			
		||||
			try {
 | 
			
		||||
				mySound.close();
 | 
			
		||||
			} catch (err:IOError) {
 | 
			
		||||
				// Occurs if the file is either yet to be opened or has finished downloading.
 | 
			
		||||
			}
 | 
			
		||||
			mySound = null;
 | 
			
		||||
			mySound = new Sound();
 | 
			
		||||
			mySound.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
 | 
			
		||||
			mySound.addEventListener(Event.OPEN, loadOpen);
 | 
			
		||||
			mySound.addEventListener(Event.COMPLETE, loadComplete);
 | 
			
		||||
			myRequest = new URLRequest(src);
 | 
			
		||||
			myStatus.reset();
 | 
			
		||||
			myStatus.src = src;
 | 
			
		||||
			myStatus.srcSet = true;
 | 
			
		||||
			timeUpdateEvent();
 | 
			
		||||
		}
 | 
			
		||||
		public function clearFile():void {
 | 
			
		||||
			setFile("");
 | 
			
		||||
			myStatus.srcSet = false;
 | 
			
		||||
		}
 | 
			
		||||
		private function errorHandler(err:IOErrorEvent):void {
 | 
			
		||||
			// MP3 player needs to stop progress and timeupdate events as they are started before the error occurs.
 | 
			
		||||
			// NB: The MP4 player works differently and the error occurs before they are started.
 | 
			
		||||
			progressUpdates(false);
 | 
			
		||||
			timeUpdates(false);
 | 
			
		||||
			myStatus.error(); // Resets status except the src, and it sets srcError property.
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_ERROR, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function loadOpen(e:Event):void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "loadOpen:"));
 | 
			
		||||
			myStatus.loading();
 | 
			
		||||
			if(myStatus.playOnLoad) {
 | 
			
		||||
				myStatus.playOnLoad = false; // Capture the flag
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_LOADSTART, myStatus)); // So loadstart event happens before play event occurs.
 | 
			
		||||
				play();
 | 
			
		||||
			} else {
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_LOADSTART, myStatus));
 | 
			
		||||
				pause();
 | 
			
		||||
			}
 | 
			
		||||
			progressUpdates(true);
 | 
			
		||||
		}
 | 
			
		||||
		private function loadComplete(e:Event):void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "loadComplete:"));
 | 
			
		||||
			myStatus.loaded();
 | 
			
		||||
			progressUpdates(false);
 | 
			
		||||
			progressEvent();
 | 
			
		||||
		}
 | 
			
		||||
		private function soundCompleteHandler(e:Event):void {
 | 
			
		||||
			myStatus.pausePosition = 0;
 | 
			
		||||
			myStatus.isPlaying = false;
 | 
			
		||||
			timeUpdates(false);
 | 
			
		||||
			timeUpdateEvent();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_ENDED, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function progressUpdates(active:Boolean):void {
 | 
			
		||||
			// Using a timer rather than Flash's load progress event, because that event gave data at about 200Hz. The 10Hz timer is closer to HTML5 norm.
 | 
			
		||||
			if(active) {
 | 
			
		||||
				progressTimer.start();
 | 
			
		||||
			} else {
 | 
			
		||||
				progressTimer.stop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function progressHandler(e:TimerEvent):void {
 | 
			
		||||
			progressEvent();
 | 
			
		||||
		}
 | 
			
		||||
		private function progressEvent():void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "progressEvent:"));
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PROGRESS, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function timeUpdates(active:Boolean):void {
 | 
			
		||||
			if(active) {
 | 
			
		||||
				timeUpdateTimer.start();
 | 
			
		||||
			} else {
 | 
			
		||||
				timeUpdateTimer.stop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function timeUpdateHandler(e:TimerEvent):void {
 | 
			
		||||
			timeUpdateEvent();
 | 
			
		||||
		}
 | 
			
		||||
		private function timeUpdateEvent():void {
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_TIMEUPDATE, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function seeking(active:Boolean):void {
 | 
			
		||||
			if(active) {
 | 
			
		||||
				if(!myStatus.isSeeking) {
 | 
			
		||||
					seekingEvent();
 | 
			
		||||
					seekingTimer.start();
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				seekingTimer.stop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function seekingHandler(e:TimerEvent):void {
 | 
			
		||||
			if(myStatus.pausePosition <= getDuration()) {
 | 
			
		||||
				seekedEvent();
 | 
			
		||||
				seeking(false);
 | 
			
		||||
				if(myStatus.playOnSeek) {
 | 
			
		||||
					myStatus.playOnSeek = false; // Capture the flag.
 | 
			
		||||
					play();
 | 
			
		||||
				}
 | 
			
		||||
			} else if(myStatus.isLoaded && (myStatus.pausePosition > getDuration())) {
 | 
			
		||||
				// Illegal seek time
 | 
			
		||||
				seeking(false);
 | 
			
		||||
				seekedEvent();
 | 
			
		||||
				pause(0);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function seekingEvent():void {
 | 
			
		||||
			myStatus.isSeeking = true;
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_SEEKING, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function seekedEvent():void {
 | 
			
		||||
			myStatus.isSeeking = false;
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_SEEKED, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		public function load():Boolean {
 | 
			
		||||
			if(myStatus.loadRequired()) {
 | 
			
		||||
				myStatus.startingDownload();
 | 
			
		||||
				mySound.load(myRequest, myContext);
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function play(time:Number = NaN):Boolean {
 | 
			
		||||
			var wasPlaying:Boolean = myStatus.isPlaying;
 | 
			
		||||
 | 
			
		||||
			if(!isNaN(time) && myStatus.srcSet) {
 | 
			
		||||
				if(myStatus.isPlaying) {
 | 
			
		||||
					myChannel.stop();
 | 
			
		||||
					myStatus.isPlaying = false;
 | 
			
		||||
				}
 | 
			
		||||
				myStatus.pausePosition = time;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(myStatus.isStartingDownload) {
 | 
			
		||||
				myStatus.playOnLoad = true; // Raise flag, captured in loadOpen()
 | 
			
		||||
				return true;
 | 
			
		||||
			} else if(myStatus.loadRequired()) {
 | 
			
		||||
				myStatus.playOnLoad = true; // Raise flag, captured in loadOpen()
 | 
			
		||||
				return load();
 | 
			
		||||
			} else if((myStatus.isLoading || myStatus.isLoaded) && !myStatus.isPlaying) {
 | 
			
		||||
				if(myStatus.isLoaded && myStatus.pausePosition > getDuration()) { // The time is invalid, ie., past the end.
 | 
			
		||||
					myStatus.pausePosition = 0;
 | 
			
		||||
					timeUpdates(false);
 | 
			
		||||
					timeUpdateEvent();
 | 
			
		||||
					if(wasPlaying) { // For when playing and then get a play(huge)
 | 
			
		||||
						this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PAUSE, myStatus));
 | 
			
		||||
					}
 | 
			
		||||
				} else if(myStatus.pausePosition > getDuration()) {
 | 
			
		||||
					myStatus.playOnSeek = true;
 | 
			
		||||
					seeking(true);
 | 
			
		||||
				} else {
 | 
			
		||||
					myStatus.isPlaying = true; // Set immediately before playing. Could affects events.
 | 
			
		||||
					myChannel = mySound.play(myStatus.pausePosition);
 | 
			
		||||
					myChannel.soundTransform = myTransform;
 | 
			
		||||
					myChannel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
 | 
			
		||||
					timeUpdates(true);
 | 
			
		||||
					if(!wasPlaying) {
 | 
			
		||||
						this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PLAY, myStatus));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function pause(time:Number = NaN):Boolean {
 | 
			
		||||
			myStatus.playOnLoad = false; // Reset flag in case load/play issued immediately before this command, ie., before loadOpen() event.
 | 
			
		||||
			myStatus.playOnSeek = false; // Reset flag in case play(time) issued before the command and is still seeking to time set.
 | 
			
		||||
 | 
			
		||||
			var wasPlaying:Boolean = myStatus.isPlaying;
 | 
			
		||||
 | 
			
		||||
			// To avoid possible loops with timeupdate and pause(time). A pause() does not have the problem.
 | 
			
		||||
			var alreadyPausedAtTime:Boolean = false;
 | 
			
		||||
			if(!isNaN(time) && myStatus.pausePosition == time) {
 | 
			
		||||
				alreadyPausedAtTime = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(myStatus.isPlaying) {
 | 
			
		||||
				myStatus.isPlaying = false;
 | 
			
		||||
				myChannel.stop();
 | 
			
		||||
				if(myChannel.position > 0) { // Required otherwise a fast play then pause causes myChannel.position to equal zero and not the correct value. ie., When it happens leave pausePosition alone.
 | 
			
		||||
					myStatus.pausePosition = myChannel.position;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(!isNaN(time) && myStatus.srcSet) {
 | 
			
		||||
				myStatus.pausePosition = time;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(wasPlaying) {
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PAUSE, myStatus));
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if(myStatus.isStartingDownload) {
 | 
			
		||||
				return true;
 | 
			
		||||
			} else if(myStatus.loadRequired()) {
 | 
			
		||||
				if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation.
 | 
			
		||||
					return load();
 | 
			
		||||
				} else {
 | 
			
		||||
					return true; // Technically the pause(0) succeeded. ie., It did nothing, since nothing was required.
 | 
			
		||||
				}
 | 
			
		||||
			} else if(myStatus.isLoading || myStatus.isLoaded) {
 | 
			
		||||
				if(myStatus.isLoaded && myStatus.pausePosition > getDuration()) { // The time is invalid, ie., past the end.
 | 
			
		||||
					myStatus.pausePosition = 0;
 | 
			
		||||
				} else if(myStatus.pausePosition > getDuration()) {
 | 
			
		||||
					seeking(true);
 | 
			
		||||
				}
 | 
			
		||||
				timeUpdates(false);
 | 
			
		||||
				// Need to be careful with timeupdate event, otherwise a pause in a timeupdate event can cause a loop.
 | 
			
		||||
				// Neither pause() nor pause(time) will cause a timeupdate loop.
 | 
			
		||||
				if(wasPlaying || !isNaN(time) && !alreadyPausedAtTime) {
 | 
			
		||||
					timeUpdateEvent();
 | 
			
		||||
				}
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function playHead(percent:Number):Boolean {
 | 
			
		||||
			var time:Number = percent * getDuration() / 100;
 | 
			
		||||
			if(myStatus.isPlaying || myStatus.playOnLoad || myStatus.playOnSeek) {
 | 
			
		||||
				return play(time);
 | 
			
		||||
			} else {
 | 
			
		||||
				return pause(time);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function setVolume(v:Number):void {
 | 
			
		||||
			myStatus.volume = v;
 | 
			
		||||
			myTransform.volume = v;
 | 
			
		||||
			myChannel.soundTransform = myTransform;
 | 
			
		||||
		}
 | 
			
		||||
		private function updateStatusValues():void {
 | 
			
		||||
			myStatus.seekPercent = 100 * getLoadRatio();
 | 
			
		||||
			myStatus.currentTime = getCurrentTime();
 | 
			
		||||
			myStatus.currentPercentRelative = 100 * getCurrentRatioRel();
 | 
			
		||||
			myStatus.currentPercentAbsolute = 100 * getCurrentRatioAbs();
 | 
			
		||||
			myStatus.duration = getDuration();
 | 
			
		||||
		}
 | 
			
		||||
		public function getLoadRatio():Number {
 | 
			
		||||
			if((myStatus.isLoading || myStatus.isLoaded) && mySound.bytesTotal > 0) {
 | 
			
		||||
				return mySound.bytesLoaded / mySound.bytesTotal;
 | 
			
		||||
			} else {
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getDuration():Number {
 | 
			
		||||
			if(mySound.length > 0) {
 | 
			
		||||
				return mySound.length;
 | 
			
		||||
			} else {
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getCurrentTime():Number {
 | 
			
		||||
			if(myStatus.isPlaying) {
 | 
			
		||||
				return myChannel.position;
 | 
			
		||||
			} else {
 | 
			
		||||
				return myStatus.pausePosition;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getCurrentRatioRel():Number {
 | 
			
		||||
			if((getDuration() > 0) && (getCurrentTime() <= getDuration())) {
 | 
			
		||||
				return getCurrentTime() / getDuration();
 | 
			
		||||
			} else {
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getCurrentRatioAbs():Number {
 | 
			
		||||
			return getCurrentRatioRel() * getLoadRatio();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,413 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * jPlayer Plugin for jQuery JavaScript Library
 | 
			
		||||
 * http://www.happyworm.com/jquery/jplayer
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009 - 2011 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
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Mark J Panaghiston
 | 
			
		||||
 * Date: 7th August 2011
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package happyworm.jPlayer {
 | 
			
		||||
	import flash.display.Sprite;
 | 
			
		||||
 | 
			
		||||
	import flash.media.Video;
 | 
			
		||||
	import flash.media.SoundTransform;
 | 
			
		||||
 | 
			
		||||
	import flash.net.NetConnection;
 | 
			
		||||
	import flash.net.NetStream;
 | 
			
		||||
 | 
			
		||||
	import flash.utils.Timer;
 | 
			
		||||
 | 
			
		||||
	import flash.events.NetStatusEvent;
 | 
			
		||||
	import flash.events.SecurityErrorEvent;
 | 
			
		||||
	import flash.events.TimerEvent;
 | 
			
		||||
 | 
			
		||||
	public class JplayerMp4 extends Sprite {
 | 
			
		||||
		
 | 
			
		||||
		public var myVideo:Video = new Video();
 | 
			
		||||
		private var myConnection:NetConnection;
 | 
			
		||||
		private var myStream:NetStream;
 | 
			
		||||
		
 | 
			
		||||
		private var myTransform:SoundTransform = new SoundTransform();
 | 
			
		||||
 | 
			
		||||
		public var myStatus:JplayerStatus = new JplayerStatus();
 | 
			
		||||
		
 | 
			
		||||
		private var timeUpdateTimer:Timer = new Timer(250, 0); // Matched to HTML event freq
 | 
			
		||||
		private var progressTimer:Timer = new Timer(250, 0); // Matched to HTML event freq
 | 
			
		||||
		private var seekingTimer:Timer = new Timer(100, 0); // Internal: How often seeking is checked to see if it is over.
 | 
			
		||||
 | 
			
		||||
		public function JplayerMp4(volume:Number) {
 | 
			
		||||
			myConnection = new NetConnection();
 | 
			
		||||
			myConnection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
 | 
			
		||||
			myConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
 | 
			
		||||
			myVideo.smoothing = true;
 | 
			
		||||
			this.addChild(myVideo);
 | 
			
		||||
			
 | 
			
		||||
			timeUpdateTimer.addEventListener(TimerEvent.TIMER, timeUpdateHandler);
 | 
			
		||||
			progressTimer.addEventListener(TimerEvent.TIMER, progressHandler);
 | 
			
		||||
			seekingTimer.addEventListener(TimerEvent.TIMER, seekingHandler);
 | 
			
		||||
 | 
			
		||||
			myStatus.volume = volume;
 | 
			
		||||
		}
 | 
			
		||||
		private function progressUpdates(active:Boolean):void {
 | 
			
		||||
			if(active) {
 | 
			
		||||
				progressTimer.start();
 | 
			
		||||
			} else {
 | 
			
		||||
				progressTimer.stop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function progressHandler(e:TimerEvent):void {
 | 
			
		||||
			if(myStatus.isLoading) {
 | 
			
		||||
				if(getLoadRatio() == 1) { // Close as can get to a loadComplete event since client.onPlayStatus only works with FMS
 | 
			
		||||
					this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "progressHandler: loadComplete"));
 | 
			
		||||
					myStatus.loaded();
 | 
			
		||||
					progressUpdates(false);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			progressEvent();
 | 
			
		||||
		}
 | 
			
		||||
		private function progressEvent():void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "progressEvent:"));
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PROGRESS, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function timeUpdates(active:Boolean):void {
 | 
			
		||||
			if(active) {
 | 
			
		||||
				timeUpdateTimer.start();
 | 
			
		||||
			} else {
 | 
			
		||||
				timeUpdateTimer.stop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function timeUpdateHandler(e:TimerEvent):void {
 | 
			
		||||
			timeUpdateEvent();
 | 
			
		||||
		}
 | 
			
		||||
		private function timeUpdateEvent():void {
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_TIMEUPDATE, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function seeking(active:Boolean):void {
 | 
			
		||||
			if(active) {
 | 
			
		||||
				if(!myStatus.isSeeking) {
 | 
			
		||||
					seekingEvent();
 | 
			
		||||
				}
 | 
			
		||||
				seekingTimer.start();
 | 
			
		||||
			} else {
 | 
			
		||||
				if(myStatus.isSeeking) {
 | 
			
		||||
					seekedEvent();
 | 
			
		||||
				}
 | 
			
		||||
				seekingTimer.stop();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function seekingHandler(e:TimerEvent):void {
 | 
			
		||||
			if(getSeekTimeRatio() <= getLoadRatio()) {
 | 
			
		||||
				seeking(false);
 | 
			
		||||
				if(myStatus.playOnSeek) {
 | 
			
		||||
					myStatus.playOnSeek = false; // Capture the flag.
 | 
			
		||||
					play(myStatus.pausePosition); // Must pass time or the seek time is never set.
 | 
			
		||||
				} else {
 | 
			
		||||
					pause(myStatus.pausePosition); // Must pass time or the stream.time is read.
 | 
			
		||||
				}
 | 
			
		||||
			} else if(myStatus.metaDataReady && myStatus.pausePosition > myStatus.duration) {
 | 
			
		||||
				// Illegal seek time
 | 
			
		||||
				seeking(false);
 | 
			
		||||
				pause(0);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function seekingEvent():void {
 | 
			
		||||
			myStatus.isSeeking = true;
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_SEEKING, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function seekedEvent():void {
 | 
			
		||||
			myStatus.isSeeking = false;
 | 
			
		||||
			updateStatusValues();
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_SEEKED, myStatus));
 | 
			
		||||
		}
 | 
			
		||||
		private function netStatusHandler(e:NetStatusEvent):void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "netStatusHandler: '" + e.info.code + "'"));
 | 
			
		||||
			switch(e.info.code) {
 | 
			
		||||
				case "NetConnection.Connect.Success":
 | 
			
		||||
					connectStream();
 | 
			
		||||
					break;
 | 
			
		||||
				case "NetStream.Play.Start":
 | 
			
		||||
					// This event code occurs once, when the media is opened. Equiv to loadOpen() in mp3 player.
 | 
			
		||||
					myStatus.loading();
 | 
			
		||||
					this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_LOADSTART, myStatus));
 | 
			
		||||
					progressUpdates(true);
 | 
			
		||||
					// See onMetaDataHandler() for other condition, since duration is vital.
 | 
			
		||||
					break;
 | 
			
		||||
				case "NetStream.Play.Stop":
 | 
			
		||||
					this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "NetStream.Play.Stop: getDuration() - getCurrentTime() = " + (getDuration() - getCurrentTime())));
 | 
			
		||||
 | 
			
		||||
					// Check if media is at the end (or close) otherwise this was due to download bandwidth stopping playback. ie., Download is not fast enough.
 | 
			
		||||
					if(Math.abs(getDuration() - getCurrentTime()) < 150) { // Testing found 150ms worked best for M4A files, where playHead(99.9) caused a stuck state due to firing with ~116ms left to play.
 | 
			
		||||
						endedEvent();
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case "NetStream.Seek.InvalidTime":
 | 
			
		||||
					// Used for capturing invalid set times and clicks on the end of the progress bar.
 | 
			
		||||
					endedEvent();
 | 
			
		||||
					break;
 | 
			
		||||
				case "NetStream.Play.StreamNotFound":
 | 
			
		||||
					myStatus.error(); // Resets status except the src, and it sets srcError property.
 | 
			
		||||
					this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_ERROR, myStatus));
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			// "NetStream.Seek.Notify" event code is not very useful. It occurs after every seek(t) command issued and does not appear to wait for the media to be ready.
 | 
			
		||||
		}
 | 
			
		||||
		private function endedEvent():void {
 | 
			
		||||
			var wasPlaying:Boolean = myStatus.isPlaying;
 | 
			
		||||
			pause(0);
 | 
			
		||||
			timeUpdates(false);
 | 
			
		||||
			timeUpdateEvent();
 | 
			
		||||
			if(wasPlaying) {
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_ENDED, myStatus));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function securityErrorHandler(event:SecurityErrorEvent):void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "securityErrorHandler."));
 | 
			
		||||
		}
 | 
			
		||||
		private function connectStream():void {
 | 
			
		||||
			this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "connectStream."));
 | 
			
		||||
			var customClient:Object = new Object();
 | 
			
		||||
			customClient.onMetaData = onMetaDataHandler;
 | 
			
		||||
			// customClient.onPlayStatus = onPlayStatusHandler; // According to the forums and my tests, onPlayStatus only works with FMS (Flash Media Server).
 | 
			
		||||
			myStream = null;
 | 
			
		||||
			myStream = new NetStream(myConnection);
 | 
			
		||||
			myStream.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
 | 
			
		||||
			myStream.client = customClient;
 | 
			
		||||
			myVideo.attachNetStream(myStream);
 | 
			
		||||
			setVolume(myStatus.volume);
 | 
			
		||||
			myStream.play(myStatus.src);
 | 
			
		||||
		}
 | 
			
		||||
		public function setFile(src:String):void {
 | 
			
		||||
			if(myStream != null) {
 | 
			
		||||
				myStream.close();
 | 
			
		||||
			}
 | 
			
		||||
			myVideo.clear();
 | 
			
		||||
			progressUpdates(false);
 | 
			
		||||
			timeUpdates(false);
 | 
			
		||||
 | 
			
		||||
			myStatus.reset();
 | 
			
		||||
			myStatus.src = src;
 | 
			
		||||
			myStatus.srcSet = true;
 | 
			
		||||
			timeUpdateEvent();
 | 
			
		||||
		}
 | 
			
		||||
		public function clearFile():void {
 | 
			
		||||
			setFile("");
 | 
			
		||||
			myStatus.srcSet = false;
 | 
			
		||||
		}
 | 
			
		||||
		public function load():Boolean {
 | 
			
		||||
			if(myStatus.loadRequired()) {
 | 
			
		||||
				myStatus.startingDownload();
 | 
			
		||||
				myConnection.connect(null);
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function play(time:Number = NaN):Boolean {
 | 
			
		||||
			var wasPlaying:Boolean = myStatus.isPlaying;
 | 
			
		||||
 | 
			
		||||
			if(!isNaN(time) && myStatus.srcSet) {
 | 
			
		||||
				if(myStatus.isPlaying) {
 | 
			
		||||
					myStream.pause();
 | 
			
		||||
					myStatus.isPlaying = false;
 | 
			
		||||
				}
 | 
			
		||||
				myStatus.pausePosition = time;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(myStatus.isStartingDownload) {
 | 
			
		||||
				myStatus.playOnLoad = true; // Raise flag, captured in onMetaDataHandler()
 | 
			
		||||
				return true;
 | 
			
		||||
			} else if(myStatus.loadRequired()) {
 | 
			
		||||
				myStatus.playOnLoad = true; // Raise flag, captured in onMetaDataHandler()
 | 
			
		||||
				return load();
 | 
			
		||||
			} else if((myStatus.isLoading || myStatus.isLoaded) && !myStatus.isPlaying) {
 | 
			
		||||
				if(myStatus.metaDataReady && myStatus.pausePosition > myStatus.duration) { // The time is invalid, ie., past the end.
 | 
			
		||||
					myStream.pause(); // Since it is playing by default at this point.
 | 
			
		||||
					myStatus.pausePosition = 0;
 | 
			
		||||
					myStream.seek(0);
 | 
			
		||||
					timeUpdates(false);
 | 
			
		||||
					timeUpdateEvent();
 | 
			
		||||
					if(wasPlaying) { // For when playing and then get a play(huge)
 | 
			
		||||
						this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PAUSE, myStatus));
 | 
			
		||||
					}
 | 
			
		||||
				} else if(getSeekTimeRatio() > getLoadRatio()) { // Use an estimate based on the downloaded amount
 | 
			
		||||
					myStatus.playOnSeek = true;
 | 
			
		||||
					seeking(true);
 | 
			
		||||
					myStream.pause(); // Since it is playing by default at this point.
 | 
			
		||||
				} else {
 | 
			
		||||
					if(!isNaN(time)) { // Avoid using seek() when it is already correct.
 | 
			
		||||
						myStream.seek(myStatus.pausePosition/1000); // Since time is in ms and seek() takes seconds
 | 
			
		||||
					}
 | 
			
		||||
					myStatus.isPlaying = true; // Set immediately before playing. Could affects events.
 | 
			
		||||
					myStream.resume();
 | 
			
		||||
					timeUpdates(true);
 | 
			
		||||
					if(!wasPlaying) {
 | 
			
		||||
						this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PLAY, myStatus));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function pause(time:Number = NaN):Boolean {
 | 
			
		||||
			myStatus.playOnLoad = false; // Reset flag in case load/play issued immediately before this command, ie., before onMetadata() event.
 | 
			
		||||
			myStatus.playOnSeek = false; // Reset flag in case play(time) issued before the command and is still seeking to time set.
 | 
			
		||||
 | 
			
		||||
			var wasPlaying:Boolean = myStatus.isPlaying;
 | 
			
		||||
 | 
			
		||||
			// To avoid possible loops with timeupdate and pause(time). A pause() does not have the problem.
 | 
			
		||||
			var alreadyPausedAtTime:Boolean = false;
 | 
			
		||||
			if(!isNaN(time) && myStatus.pausePosition == time) {
 | 
			
		||||
				alreadyPausedAtTime = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Need to wait for metadata to load before ever issuing a pause. The metadata handler will call this function if needed, when ready.
 | 
			
		||||
			if(myStream != null && myStatus.metaDataReady) { // myStream is a null until the 1st media is loaded. ie., The 1st ever setMedia being followed by a pause() or pause(t).
 | 
			
		||||
				myStream.pause();
 | 
			
		||||
			}
 | 
			
		||||
			if(myStatus.isPlaying) {
 | 
			
		||||
				myStatus.isPlaying = false;
 | 
			
		||||
				myStatus.pausePosition = myStream.time * 1000;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if(!isNaN(time) && myStatus.srcSet) {
 | 
			
		||||
				myStatus.pausePosition = time;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(wasPlaying) {
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_PAUSE, myStatus));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(myStatus.isStartingDownload) {
 | 
			
		||||
				return true;
 | 
			
		||||
			} else if(myStatus.loadRequired()) {
 | 
			
		||||
				if(time > 0) { // We do not want the stop() command, which does pause(0), causing a load operation.
 | 
			
		||||
					return load();
 | 
			
		||||
				} else {
 | 
			
		||||
					return true; // Technically the pause(0) succeeded. ie., It did nothing, since nothing was required.
 | 
			
		||||
				}
 | 
			
		||||
			} else if(myStatus.isLoading || myStatus.isLoaded) {
 | 
			
		||||
				if(myStatus.metaDataReady && myStatus.pausePosition > myStatus.duration) { // The time is invalid, ie., past the end.
 | 
			
		||||
					myStatus.pausePosition = 0;
 | 
			
		||||
					myStream.seek(0);
 | 
			
		||||
					seekedEvent(); // Deals with seeking effect when using setMedia() then pause(huge). NB: There is no preceeding seeking event.
 | 
			
		||||
				} else if(!isNaN(time)) {
 | 
			
		||||
					if(getSeekTimeRatio() > getLoadRatio()) { // Use an estimate based on the downloaded amount
 | 
			
		||||
						seeking(true);
 | 
			
		||||
					} else {
 | 
			
		||||
						if(myStatus.metaDataReady) { // Otherwise seek(0) will stop the metadata loading.
 | 
			
		||||
							myStream.seek(myStatus.pausePosition/1000);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				timeUpdates(false);
 | 
			
		||||
				// Need to be careful with timeupdate event, otherwise a pause in a timeupdate event can cause a loop.
 | 
			
		||||
				// Neither pause() nor pause(time) will cause a timeupdate loop.
 | 
			
		||||
				if(wasPlaying || !isNaN(time) && !alreadyPausedAtTime) {
 | 
			
		||||
					timeUpdateEvent();
 | 
			
		||||
				}
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function playHead(percent:Number):Boolean {
 | 
			
		||||
			var time:Number = percent * getDuration() * getLoadRatio() / 100;
 | 
			
		||||
			if(myStatus.isPlaying || myStatus.playOnLoad || myStatus.playOnSeek) {
 | 
			
		||||
				return play(time);
 | 
			
		||||
			} else {
 | 
			
		||||
				return pause(time);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function setVolume(v:Number):void {
 | 
			
		||||
			myStatus.volume = v;
 | 
			
		||||
			myTransform.volume = v;
 | 
			
		||||
			if(myStream != null) {
 | 
			
		||||
				myStream.soundTransform = myTransform;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		private function updateStatusValues():void {
 | 
			
		||||
			myStatus.seekPercent = 100 * getLoadRatio();
 | 
			
		||||
			myStatus.currentTime = getCurrentTime();
 | 
			
		||||
			myStatus.currentPercentRelative = 100 * getCurrentRatioRel();
 | 
			
		||||
			myStatus.currentPercentAbsolute = 100 * getCurrentRatioAbs();
 | 
			
		||||
			myStatus.duration = getDuration();
 | 
			
		||||
		}
 | 
			
		||||
		public function getLoadRatio():Number {
 | 
			
		||||
			if((myStatus.isLoading || myStatus.isLoaded) && myStream.bytesTotal > 0) {
 | 
			
		||||
				return myStream.bytesLoaded / myStream.bytesTotal;
 | 
			
		||||
			} else {
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getDuration():Number {
 | 
			
		||||
			return myStatus.duration; // Set from meta data.
 | 
			
		||||
		}
 | 
			
		||||
		public function getCurrentTime():Number {
 | 
			
		||||
			if(myStatus.isPlaying) {
 | 
			
		||||
				return myStream.time * 1000;
 | 
			
		||||
			} else {
 | 
			
		||||
				return myStatus.pausePosition;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getCurrentRatioRel():Number {
 | 
			
		||||
			if((getLoadRatio() > 0) && (getCurrentRatioAbs() <= getLoadRatio())) {
 | 
			
		||||
				return getCurrentRatioAbs() / getLoadRatio();
 | 
			
		||||
			} else {
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getCurrentRatioAbs():Number {
 | 
			
		||||
			if(getDuration() > 0) {
 | 
			
		||||
				return getCurrentTime() / getDuration();
 | 
			
		||||
			} else {
 | 
			
		||||
				return 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function getSeekTimeRatio():Number {
 | 
			
		||||
			if(getDuration() > 0) {
 | 
			
		||||
				return myStatus.pausePosition / getDuration();
 | 
			
		||||
			} else {
 | 
			
		||||
				return 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		public function onMetaDataHandler(info:Object):void { // Used in connectStream() in myStream.client object.
 | 
			
		||||
			// This event occurs when jumping to the start of static files! ie., seek(0) will cause this event to occur.
 | 
			
		||||
			if(!myStatus.metaDataReady) {
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "onMetaDataHandler: " + info.duration + " | " + info.width + "x" + info.height));
 | 
			
		||||
 | 
			
		||||
				myStatus.metaDataReady = true; // Set flag so that this event only effects jPlayer the 1st time.
 | 
			
		||||
				myStatus.metaData = info;
 | 
			
		||||
				myStatus.duration = info.duration * 1000; // Only available via Meta Data.
 | 
			
		||||
				if(info.width != undefined) {
 | 
			
		||||
					myVideo.width = info.width;
 | 
			
		||||
				}
 | 
			
		||||
				if(info.height != undefined) {
 | 
			
		||||
					myVideo.height = info.height;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if(myStatus.playOnLoad) {
 | 
			
		||||
					myStatus.playOnLoad = false; // Capture the flag
 | 
			
		||||
					if(myStatus.pausePosition > 0 ) { // Important for setMedia followed by play(time).
 | 
			
		||||
						play(myStatus.pausePosition);
 | 
			
		||||
					} else {
 | 
			
		||||
						play(); // Not always sending pausePosition avoids the extra seek(0) for a normal play() command.
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					pause(myStatus.pausePosition); // Always send the pausePosition. Important for setMedia() followed by pause(time). Deals with not reading stream.time with setMedia() and play() immediately followed by stop() or pause(0)
 | 
			
		||||
				}
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.JPLAYER_LOADEDMETADATA, myStatus));
 | 
			
		||||
			} else {
 | 
			
		||||
				this.dispatchEvent(new JplayerEvent(JplayerEvent.DEBUG_MSG, myStatus, "onMetaDataHandler: Already read (NO EFFECT)"));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,101 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * jPlayer Plugin for jQuery JavaScript Library
 | 
			
		||||
 * http://www.happyworm.com/jquery/jplayer
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009 - 2011 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
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Mark J Panaghiston
 | 
			
		||||
 * Date: 1st September 2011
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package happyworm.jPlayer {
 | 
			
		||||
	public class JplayerStatus {
 | 
			
		||||
 | 
			
		||||
		public static const VERSION:String = "2.1.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()
 | 
			
		||||
 | 
			
		||||
		public var src:String;
 | 
			
		||||
		public var srcError:Boolean;
 | 
			
		||||
 | 
			
		||||
		public var srcSet:Boolean;
 | 
			
		||||
		public var isPlaying:Boolean;
 | 
			
		||||
		public var isSeeking:Boolean;
 | 
			
		||||
 | 
			
		||||
		public var playOnLoad:Boolean;
 | 
			
		||||
		public var playOnSeek:Boolean;
 | 
			
		||||
 | 
			
		||||
		public var isStartingDownload:Boolean;
 | 
			
		||||
		public var isLoading:Boolean;
 | 
			
		||||
		public var isLoaded:Boolean;
 | 
			
		||||
 | 
			
		||||
		public var pausePosition:Number;
 | 
			
		||||
 | 
			
		||||
		public var seekPercent:Number;
 | 
			
		||||
		public var currentTime:Number;
 | 
			
		||||
		public var currentPercentRelative:Number;
 | 
			
		||||
		public var currentPercentAbsolute:Number;
 | 
			
		||||
		public var duration:Number;
 | 
			
		||||
		
 | 
			
		||||
		public var metaDataReady:Boolean;
 | 
			
		||||
		public var metaData:Object;
 | 
			
		||||
 | 
			
		||||
		public function JplayerStatus() {
 | 
			
		||||
			reset();
 | 
			
		||||
		}
 | 
			
		||||
		public function reset():void {
 | 
			
		||||
			src = "";
 | 
			
		||||
			srcError = false;
 | 
			
		||||
 | 
			
		||||
			srcSet = false;
 | 
			
		||||
			isPlaying = false;
 | 
			
		||||
			isSeeking = false;
 | 
			
		||||
 | 
			
		||||
			playOnLoad = false;
 | 
			
		||||
			playOnSeek = false;
 | 
			
		||||
 | 
			
		||||
			isStartingDownload = false;
 | 
			
		||||
			isLoading = false;
 | 
			
		||||
			isLoaded = false;
 | 
			
		||||
 | 
			
		||||
			pausePosition = 0;
 | 
			
		||||
 | 
			
		||||
			seekPercent = 0;
 | 
			
		||||
			currentTime = 0;
 | 
			
		||||
			currentPercentRelative = 0;
 | 
			
		||||
			currentPercentAbsolute = 0;
 | 
			
		||||
			duration = 0;
 | 
			
		||||
			
 | 
			
		||||
			metaDataReady = false;
 | 
			
		||||
			metaData = {};
 | 
			
		||||
		}
 | 
			
		||||
		public function error():void {
 | 
			
		||||
			var srcSaved:String = src;
 | 
			
		||||
			reset();
 | 
			
		||||
			src = srcSaved;
 | 
			
		||||
			srcError = true;
 | 
			
		||||
		}
 | 
			
		||||
		public function loadRequired():Boolean {
 | 
			
		||||
			return (srcSet && !isStartingDownload && !isLoading && !isLoaded);
 | 
			
		||||
		}
 | 
			
		||||
		public function startingDownload():void {
 | 
			
		||||
			isStartingDownload = true;
 | 
			
		||||
			isLoading = false;
 | 
			
		||||
			isLoaded = false;
 | 
			
		||||
		}
 | 
			
		||||
		public function loading():void {
 | 
			
		||||
			isStartingDownload = false;
 | 
			
		||||
			isLoading = true;
 | 
			
		||||
			isLoaded = false;
 | 
			
		||||
		}
 | 
			
		||||
		public function loaded():void {
 | 
			
		||||
			isStartingDownload = false;
 | 
			
		||||
			isLoading = false;
 | 
			
		||||
			isLoaded = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,452 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Playlist Object for the jPlayer Plugin
 | 
			
		||||
 * http://www.jplayer.org
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (c) 2009 - 2011 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
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Mark J Panaghiston
 | 
			
		||||
 * Version: 2.1.0 (jPlayer 2.1.0)
 | 
			
		||||
 * Date: 1st September 2011
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Code verified using http://www.jshint.com/ */
 | 
			
		||||
/*jshint asi:false, bitwise:false, boss:false, browser:true, curly:true, debug:false, eqeqeq:true, eqnull:false, evil:false, forin:false, immed:false, jquery:true, laxbreak:false, newcap:true, noarg:true, noempty:true, nonew:true, nomem:false, onevar:false, passfail:false, plusplus:false, regexp:false, undef:true, sub:false, strict:false, white:false */
 | 
			
		||||
/*global  jPlayerPlaylist: true, jQuery:false, alert:false */
 | 
			
		||||
 | 
			
		||||
(function($, undefined) {
 | 
			
		||||
 | 
			
		||||
	jPlayerPlaylist = function(cssSelector, playlist, options) {
 | 
			
		||||
		var self = this;
 | 
			
		||||
 | 
			
		||||
		this.current = 0;
 | 
			
		||||
		this.loop = false; // Flag used with the jPlayer repeat event
 | 
			
		||||
		this.shuffled = false;
 | 
			
		||||
		this.removing = false; // Flag is true during remove animation, disabling the remove() method until complete.
 | 
			
		||||
 | 
			
		||||
		this.cssSelector = $.extend({}, this._cssSelector, cssSelector); // Object: Containing the css selectors for jPlayer and its cssSelectorAncestor
 | 
			
		||||
		this.options = $.extend(true, {}, this._options, options); // Object: The jPlayer constructor options for this playlist and the playlist options
 | 
			
		||||
 | 
			
		||||
		this.playlist = []; // Array of Objects: The current playlist displayed (Un-shuffled or Shuffled)
 | 
			
		||||
		this.original = []; // Array of Objects: The original playlist
 | 
			
		||||
 | 
			
		||||
		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.playlist = this.cssSelector.cssSelectorAncestor + " .jp-playlist";
 | 
			
		||||
		this.cssSelector.next = this.cssSelector.cssSelectorAncestor + " .jp-next";
 | 
			
		||||
		this.cssSelector.previous = this.cssSelector.cssSelectorAncestor + " .jp-previous";
 | 
			
		||||
		this.cssSelector.shuffle = this.cssSelector.cssSelectorAncestor + " .jp-shuffle";
 | 
			
		||||
		this.cssSelector.shuffleOff = this.cssSelector.cssSelectorAncestor + " .jp-shuffle-off";
 | 
			
		||||
 | 
			
		||||
		// Override the cssSelectorAncestor given in options
 | 
			
		||||
		this.options.cssSelectorAncestor = this.cssSelector.cssSelectorAncestor;
 | 
			
		||||
 | 
			
		||||
		// Override the default repeat event handler
 | 
			
		||||
		this.options.repeat = function(event) {
 | 
			
		||||
			self.loop = event.jPlayer.options.loop;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		// Create a ready event handler to initialize the playlist
 | 
			
		||||
		$(this.cssSelector.jPlayer).bind($.jPlayer.event.ready, function(event) {
 | 
			
		||||
			self._init();
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// Create an ended event handler to move to the next item
 | 
			
		||||
		$(this.cssSelector.jPlayer).bind($.jPlayer.event.ended, function(event) {
 | 
			
		||||
			self.next();
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// Create a play event handler to pause other instances
 | 
			
		||||
		$(this.cssSelector.jPlayer).bind($.jPlayer.event.play, function(event) {
 | 
			
		||||
			$(this).jPlayer("pauseOthers");
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// 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();
 | 
			
		||||
			} else {
 | 
			
		||||
				$(self.cssSelector.title).hide();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		// Create click handlers for the extra buttons that do playlist functions.
 | 
			
		||||
		$(this.cssSelector.previous).click(function() {
 | 
			
		||||
			self.previous();
 | 
			
		||||
			$(this).blur();
 | 
			
		||||
			return false;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		$(this.cssSelector.next).click(function() {
 | 
			
		||||
			self.next();
 | 
			
		||||
			$(this).blur();
 | 
			
		||||
			return false;
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
		$(this.cssSelector.shuffle).click(function() {
 | 
			
		||||
			self.shuffle(true);
 | 
			
		||||
			return false;
 | 
			
		||||
		});
 | 
			
		||||
		$(this.cssSelector.shuffleOff).click(function() {
 | 
			
		||||
			self.shuffle(false);
 | 
			
		||||
			return false;
 | 
			
		||||
		}).hide();
 | 
			
		||||
 | 
			
		||||
		// Put the title in its initial display state
 | 
			
		||||
		if(!this.options.fullScreen) {
 | 
			
		||||
			$(this.cssSelector.title).hide();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Remove the empty <li> from the page HTML. Allows page to be valid HTML, while not interfereing with display animations
 | 
			
		||||
		$(this.cssSelector.playlist + " ul").empty();
 | 
			
		||||
 | 
			
		||||
		// Create .live() handlers for the playlist items along with the free media and remove controls.
 | 
			
		||||
		this._createItemHandlers();
 | 
			
		||||
 | 
			
		||||
		// Instance jPlayer
 | 
			
		||||
		$(this.cssSelector.jPlayer).jPlayer(this.options);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	jPlayerPlaylist.prototype = {
 | 
			
		||||
		_cssSelector: { // static object, instanced in constructor
 | 
			
		||||
			jPlayer: "#jquery_jplayer_1",
 | 
			
		||||
			cssSelectorAncestor: "#jp_container_1"
 | 
			
		||||
		},
 | 
			
		||||
		_options: { // static object, instanced in constructor
 | 
			
		||||
			playlistOptions: {
 | 
			
		||||
				autoPlay: false,
 | 
			
		||||
				loopOnPrevious: false,
 | 
			
		||||
				shuffleOnLoop: true,
 | 
			
		||||
				enableRemoveControls: false,
 | 
			
		||||
				displayTime: 'slow',
 | 
			
		||||
				addTime: 'fast',
 | 
			
		||||
				removeTime: 'fast',
 | 
			
		||||
				shuffleTime: 'slow',
 | 
			
		||||
				itemClass: "jp-playlist-item",
 | 
			
		||||
				freeGroupClass: "jp-free-media",
 | 
			
		||||
				freeItemClass: "jp-playlist-item-free",
 | 
			
		||||
				removeItemClass: "jp-playlist-item-remove"
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		option: function(option, value) { // For changing playlist options only
 | 
			
		||||
			if(value === undefined) {
 | 
			
		||||
				return this.options.playlistOptions[option];
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			this.options.playlistOptions[option] = value;
 | 
			
		||||
 | 
			
		||||
			switch(option) {
 | 
			
		||||
				case "enableRemoveControls":
 | 
			
		||||
					this._updateControls();
 | 
			
		||||
					break;
 | 
			
		||||
				case "itemClass":
 | 
			
		||||
				case "freeGroupClass":
 | 
			
		||||
				case "freeItemClass":
 | 
			
		||||
				case "removeItemClass":
 | 
			
		||||
					this._refresh(true); // Instant
 | 
			
		||||
					this._createItemHandlers();
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			return this;
 | 
			
		||||
		},
 | 
			
		||||
		_init: function() {
 | 
			
		||||
			var self = this;
 | 
			
		||||
			this._refresh(function() {
 | 
			
		||||
				if(self.options.playlistOptions.autoPlay) {
 | 
			
		||||
					self.play(self.current);
 | 
			
		||||
				} else {
 | 
			
		||||
					self.select(self.current);
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		_initPlaylist: function(playlist) {
 | 
			
		||||
			this.current = 0;
 | 
			
		||||
			this.shuffled = false;
 | 
			
		||||
			this.removing = false;
 | 
			
		||||
			this.original = $.extend(true, [], playlist); // Copy the Array of Objects
 | 
			
		||||
			this._originalPlaylist();
 | 
			
		||||
		},
 | 
			
		||||
		_originalPlaylist: function() {
 | 
			
		||||
			var self = this;
 | 
			
		||||
			this.playlist = [];
 | 
			
		||||
			// Make both arrays point to the same object elements. Gives us 2 different arrays, each pointing to the same actual object. ie., Not copies of the object.
 | 
			
		||||
			$.each(this.original, function(i,v) {
 | 
			
		||||
				self.playlist[i] = self.original[i];
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		_refresh: function(instant) {
 | 
			
		||||
			/* instant: Can be undefined, true or a function.
 | 
			
		||||
			 *	undefined -> use animation timings
 | 
			
		||||
			 *	true -> no animation
 | 
			
		||||
			 *	function -> use animation timings and excute function at half way point.
 | 
			
		||||
			 */
 | 
			
		||||
			var self = this;
 | 
			
		||||
 | 
			
		||||
			if(instant && !$.isFunction(instant)) {
 | 
			
		||||
				$(this.cssSelector.playlist + " ul").empty();
 | 
			
		||||
				$.each(this.playlist, function(i,v) {
 | 
			
		||||
					$(self.cssSelector.playlist + " ul").append(self._createListItem(self.playlist[i]));
 | 
			
		||||
				});
 | 
			
		||||
				this._updateControls();
 | 
			
		||||
			} else {
 | 
			
		||||
				var displayTime = $(this.cssSelector.playlist + " ul").children().length ? this.options.playlistOptions.displayTime : 0;
 | 
			
		||||
 | 
			
		||||
				$(this.cssSelector.playlist + " ul").slideUp(displayTime, function() {
 | 
			
		||||
					var $this = $(this);
 | 
			
		||||
					$(this).empty();
 | 
			
		||||
					
 | 
			
		||||
					$.each(self.playlist, function(i,v) {
 | 
			
		||||
						$this.append(self._createListItem(self.playlist[i]));
 | 
			
		||||
					});
 | 
			
		||||
					self._updateControls();
 | 
			
		||||
					if($.isFunction(instant)) {
 | 
			
		||||
						instant();
 | 
			
		||||
					}
 | 
			
		||||
					if(self.playlist.length) {
 | 
			
		||||
						$(this).slideDown(self.options.playlistOptions.displayTime);
 | 
			
		||||
					} else {
 | 
			
		||||
						$(this).show();
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		_createListItem: function(media) {
 | 
			
		||||
			var self = this;
 | 
			
		||||
 | 
			
		||||
			// Wrap the <li> contents in a <div>
 | 
			
		||||
			var listItem = "<li><div>";
 | 
			
		||||
 | 
			
		||||
			// Create remove control
 | 
			
		||||
			listItem += "<a href='javascript:;' class='" + this.options.playlistOptions.removeItemClass + "'>×</a>";
 | 
			
		||||
 | 
			
		||||
			// Create links to free media
 | 
			
		||||
			if(media.free) {
 | 
			
		||||
				var first = true;
 | 
			
		||||
				listItem += "<span class='" + this.options.playlistOptions.freeGroupClass + "'>(";
 | 
			
		||||
				$.each(media, function(property,value) {
 | 
			
		||||
					if($.jPlayer.prototype.format[property]) { // Check property is a media format.
 | 
			
		||||
						if(first) {
 | 
			
		||||
							first = false;
 | 
			
		||||
						} else {
 | 
			
		||||
							listItem += " | ";
 | 
			
		||||
						}
 | 
			
		||||
						listItem += "<a class='" + self.options.playlistOptions.freeItemClass + "' href='" + value + "' tabindex='1'>" + property + "</a>";
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
				listItem += ")</span>";
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// The title is given next in the HTML otherwise the float:right on the free media corrupts in IE6/7
 | 
			
		||||
			listItem += "<a href='javascript:;' class='" + this.options.playlistOptions.itemClass + "' tabindex='1'>" + media.title + (media.artist ? " <span class='jp-artist'>by " + media.artist + "</span>" : "") + "</a>";
 | 
			
		||||
			listItem += "</div></li>";
 | 
			
		||||
 | 
			
		||||
			return listItem;
 | 
			
		||||
		},
 | 
			
		||||
		_createItemHandlers: function() {
 | 
			
		||||
			var self = this;
 | 
			
		||||
			// Create .live() handlers for the playlist items
 | 
			
		||||
			$(this.cssSelector.playlist + " a." + this.options.playlistOptions.itemClass).die("click").live("click", function() {
 | 
			
		||||
				var index = $(this).parent().parent().index();
 | 
			
		||||
				if(self.current !== index) {
 | 
			
		||||
					self.play(index);
 | 
			
		||||
				} else {
 | 
			
		||||
					$(self.cssSelector.jPlayer).jPlayer("play");
 | 
			
		||||
				}
 | 
			
		||||
				$(this).blur();
 | 
			
		||||
				return false;
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			// Create .live() handlers that disable free media links to force access via right click
 | 
			
		||||
			$(self.cssSelector.playlist + " a." + this.options.playlistOptions.freeItemClass).die("click").live("click", function() {
 | 
			
		||||
				$(this).parent().parent().find("." + self.options.playlistOptions.itemClass).click();
 | 
			
		||||
				$(this).blur();
 | 
			
		||||
				return false;
 | 
			
		||||
			});
 | 
			
		||||
 | 
			
		||||
			// Create .live() handlers for the remove controls
 | 
			
		||||
			$(self.cssSelector.playlist + " a." + this.options.playlistOptions.removeItemClass).die("click").live("click", function() {
 | 
			
		||||
				var index = $(this).parent().parent().index();
 | 
			
		||||
				self.remove(index);
 | 
			
		||||
				$(this).blur();
 | 
			
		||||
				return false;
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		_updateControls: function() {
 | 
			
		||||
			if(this.options.playlistOptions.enableRemoveControls) {
 | 
			
		||||
				$(this.cssSelector.playlist + " ." + this.options.playlistOptions.removeItemClass).show();
 | 
			
		||||
			} else {
 | 
			
		||||
				$(this.cssSelector.playlist + " ." + this.options.playlistOptions.removeItemClass).hide();
 | 
			
		||||
			}
 | 
			
		||||
			if(this.shuffled) {
 | 
			
		||||
				$(this.cssSelector.shuffleOff).show();
 | 
			
		||||
				$(this.cssSelector.shuffle).hide();
 | 
			
		||||
			} else {
 | 
			
		||||
				$(this.cssSelector.shuffleOff).hide();
 | 
			
		||||
				$(this.cssSelector.shuffle).show();
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		_highlight: function(index) {
 | 
			
		||||
			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 ? " <span class='jp-artist'>by " + this.playlist[index].artist + "</span>" : ""));
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		setPlaylist: function(playlist) {
 | 
			
		||||
			this._initPlaylist(playlist);
 | 
			
		||||
			this._init();
 | 
			
		||||
		},
 | 
			
		||||
		add: function(media, playNow) {
 | 
			
		||||
			$(this.cssSelector.playlist + " ul").append(this._createListItem(media)).find("li:last-child").hide().slideDown(this.options.playlistOptions.addTime);
 | 
			
		||||
			this._updateControls();
 | 
			
		||||
			this.original.push(media);
 | 
			
		||||
			this.playlist.push(media); // Both array elements share the same object pointer. Comforms with _initPlaylist(p) system.
 | 
			
		||||
 | 
			
		||||
			if(playNow) {
 | 
			
		||||
				this.play(this.playlist.length - 1);
 | 
			
		||||
			} else {
 | 
			
		||||
				if(this.original.length === 1) {
 | 
			
		||||
					this.select(0);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		remove: function(index) {
 | 
			
		||||
			var self = this;
 | 
			
		||||
 | 
			
		||||
			if(index === undefined) {
 | 
			
		||||
				this._initPlaylist([]);
 | 
			
		||||
				this._refresh(function() {
 | 
			
		||||
					$(self.cssSelector.jPlayer).jPlayer("clearMedia");
 | 
			
		||||
				});
 | 
			
		||||
				return true;
 | 
			
		||||
			} else {
 | 
			
		||||
 | 
			
		||||
				if(this.removing) {
 | 
			
		||||
					return false;
 | 
			
		||||
				} else {
 | 
			
		||||
					index = (index < 0) ? self.original.length + index : index; // Negative index relates to end of array.
 | 
			
		||||
					if(0 <= index && index < this.playlist.length) {
 | 
			
		||||
						this.removing = true;
 | 
			
		||||
 | 
			
		||||
						$(this.cssSelector.playlist + " li:nth-child(" + (index + 1) + ")").slideUp(this.options.playlistOptions.removeTime, function() {
 | 
			
		||||
							$(this).remove();
 | 
			
		||||
 | 
			
		||||
							if(self.shuffled) {
 | 
			
		||||
								var item = self.playlist[index];
 | 
			
		||||
								$.each(self.original, function(i,v) {
 | 
			
		||||
									if(self.original[i] === item) {
 | 
			
		||||
										self.original.splice(i, 1);
 | 
			
		||||
										return false; // Exit $.each
 | 
			
		||||
									}
 | 
			
		||||
								});
 | 
			
		||||
								self.playlist.splice(index, 1);
 | 
			
		||||
							} else {
 | 
			
		||||
								self.original.splice(index, 1);
 | 
			
		||||
								self.playlist.splice(index, 1);
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							if(self.original.length) {
 | 
			
		||||
								if(index === self.current) {
 | 
			
		||||
									self.current = (index < self.original.length) ? self.current : self.original.length - 1; // To cope when last element being selected when it was removed
 | 
			
		||||
									self.select(self.current);
 | 
			
		||||
								} else if(index < self.current) {
 | 
			
		||||
									self.current--;
 | 
			
		||||
								}
 | 
			
		||||
							} else {
 | 
			
		||||
								$(self.cssSelector.jPlayer).jPlayer("clearMedia");
 | 
			
		||||
								self.current = 0;
 | 
			
		||||
								self.shuffled = false;
 | 
			
		||||
								self._updateControls();
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							self.removing = false;
 | 
			
		||||
						});
 | 
			
		||||
					}
 | 
			
		||||
					return true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		select: function(index) {
 | 
			
		||||
			index = (index < 0) ? this.original.length + index : index; // Negative index relates to end of array.
 | 
			
		||||
			if(0 <= index && index < this.playlist.length) {
 | 
			
		||||
				this.current = index;
 | 
			
		||||
				this._highlight(index);
 | 
			
		||||
				$(this.cssSelector.jPlayer).jPlayer("setMedia", this.playlist[this.current]);
 | 
			
		||||
			} else {
 | 
			
		||||
				this.current = 0;
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		play: function(index) {
 | 
			
		||||
			index = (index < 0) ? this.original.length + index : index; // Negative index relates to end of array.
 | 
			
		||||
			if(0 <= index && index < this.playlist.length) {
 | 
			
		||||
				if(this.playlist.length) {
 | 
			
		||||
					this.select(index);
 | 
			
		||||
					$(this.cssSelector.jPlayer).jPlayer("play");
 | 
			
		||||
				}
 | 
			
		||||
			} else if(index === undefined) {
 | 
			
		||||
				$(this.cssSelector.jPlayer).jPlayer("play");
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		pause: function() {
 | 
			
		||||
			$(this.cssSelector.jPlayer).jPlayer("pause");
 | 
			
		||||
		},
 | 
			
		||||
		next: function() {
 | 
			
		||||
			var index = (this.current + 1 < this.playlist.length) ? this.current + 1 : 0;
 | 
			
		||||
 | 
			
		||||
			if(this.loop) {
 | 
			
		||||
				// See if we need to shuffle before looping to start, and only shuffle if more than 1 item.
 | 
			
		||||
				if(index === 0 && this.shuffled && this.options.playlistOptions.shuffleOnLoop && this.playlist.length > 1) {
 | 
			
		||||
					this.shuffle(true, true); // playNow
 | 
			
		||||
				} else {
 | 
			
		||||
					this.play(index);
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				// The index will be zero if it just looped round
 | 
			
		||||
				if(index > 0) {
 | 
			
		||||
					this.play(index);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		previous: function() {
 | 
			
		||||
			var index = (this.current - 1 >= 0) ? this.current - 1 : this.playlist.length - 1;
 | 
			
		||||
 | 
			
		||||
			if(this.loop && this.options.playlistOptions.loopOnPrevious || index < this.playlist.length - 1) {
 | 
			
		||||
				this.play(index);
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		shuffle: function(shuffled, playNow) {
 | 
			
		||||
			var self = this;
 | 
			
		||||
 | 
			
		||||
			if(shuffled === undefined) {
 | 
			
		||||
				shuffled = !this.shuffled;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if(shuffled || shuffled !== this.shuffled) {
 | 
			
		||||
 | 
			
		||||
				$(this.cssSelector.playlist + " ul").slideUp(this.options.playlistOptions.shuffleTime, function() {
 | 
			
		||||
					self.shuffled = shuffled;
 | 
			
		||||
					if(shuffled) {
 | 
			
		||||
						self.playlist.sort(function() {
 | 
			
		||||
							return 0.5 - Math.random();
 | 
			
		||||
						});
 | 
			
		||||
					} else {
 | 
			
		||||
						self._originalPlaylist();
 | 
			
		||||
					}
 | 
			
		||||
					self._refresh(true); // Instant
 | 
			
		||||
 | 
			
		||||
					if(playNow || !$(self.cssSelector.jPlayer).data("jPlayer").status.paused) {
 | 
			
		||||
						self.play(0);
 | 
			
		||||
					} else {
 | 
			
		||||
						self.select(0);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					$(this).slideDown(self.options.playlistOptions.shuffleTime);
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
})(jQuery);
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user