PageRenderTime 60ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 1ms

/src/actionscript/Jplayer.as

http://github.com/happyworm/jPlayer
ActionScript | 629 lines | 515 code | 76 blank | 38 comment | 73 complexity | 2baf0a62ad808f9daf3902c9677193d6 MD5 | raw file
  1. /*
  2. * jPlayer Plugin for jQuery JavaScript Library
  3. * http://www.jplayer.org
  4. *
  5. * Copyright (c) 2009 - 2014 Happyworm Ltd
  6. * Licensed under the MIT license.
  7. * http://opensource.org/licenses/MIT
  8. *
  9. * Author: Mark J Panaghiston
  10. * Version: 2.8.0
  11. * Date: 11th November 2014
  12. *
  13. * FlashVars expected: (AS3 property of: loaderInfo.parameters)
  14. * id: (URL Encoded: String) Id of jPlayer instance
  15. * vol: (Number) Sets the initial volume
  16. * muted: (Boolean in a String) Sets the initial muted state
  17. * jQuery: (URL Encoded: String) Sets the jQuery var name. Used with: someVar = jQuery.noConflict(true); The someVar name must contain jQuery in it.
  18. *
  19. * Compiled using: Adobe Flex Compiler (mxmlc) Version 4.6
  20. * mxmlc Jplayer.as -static-link-runtime-shared-libraries=true
  21. */
  22. package {
  23. import flash.system.Security;
  24. import flash.external.ExternalInterface;
  25. import flash.utils.Timer;
  26. import flash.events.TimerEvent;
  27. import flash.text.TextField;
  28. import flash.text.TextFormat;
  29. import flash.events.KeyboardEvent;
  30. import flash.display.Sprite;
  31. import happyworm.jPlayer.*;
  32. import flash.display.StageAlign;
  33. import flash.display.StageScaleMode;
  34. import flash.events.Event;
  35. import flash.net.LocalConnection;
  36. import flash.events.StatusEvent;
  37. import flash.events.MouseEvent;
  38. import flash.ui.ContextMenu;
  39. import flash.ui.ContextMenuItem;
  40. import flash.events.ContextMenuEvent;
  41. import flash.net.URLRequest;
  42. import flash.net.navigateToURL;
  43. import flash.media.Video;
  44. public class Jplayer extends Sprite {
  45. private var jQuery:String;
  46. private var sentNumberFractionDigits:uint = 2;
  47. public var commonStatus:JplayerStatus = new JplayerStatus(); // Used for inital ready event so volume is correct.
  48. private var myInitTimer:Timer = new Timer(100, 0);
  49. private var myMp3Player:JplayerMp3;
  50. private var myMp4Player:JplayerMp4;
  51. private var myRtmpPlayer:JplayerRtmp;
  52. private var isRtmp:Boolean = false;
  53. private var isMp4:Boolean = false;
  54. private var isMp3:Boolean = false;
  55. private var isVideo:Boolean = false;
  56. private var securityIssue:Boolean = false; // On direct access and when SWF parameters contain illegal characters
  57. private var contextMenuFix:Sprite = new Sprite(); // A sprite that will be on top and fix the content menu over video bug. (A Flash plugin bug.)
  58. private var txLog:TextField;
  59. private var debug:Boolean = false; // Set debug to false for release compile!
  60. public function Jplayer() {
  61. flash.system.Security.allowDomain("*");
  62. flash.system.Security.allowInsecureDomain("*");
  63. // Fix to the security exploit reported by Jason Calvert http://appsec.ws/
  64. checkFlashVars(loaderInfo.parameters);
  65. stage.scaleMode = StageScaleMode.NO_SCALE;
  66. stage.align = StageAlign.TOP_LEFT;
  67. if(!securityIssue) {
  68. // The jQuery param is the primary cause of security concerns.
  69. jQuery = loaderInfo.parameters.jQuery + "('#" + loaderInfo.parameters.id + "').jPlayer";
  70. commonStatus.volume = Number(loaderInfo.parameters.vol);
  71. commonStatus.muted = loaderInfo.parameters.muted == "true";
  72. stage.addEventListener(Event.RESIZE, resizeHandler);
  73. stage.addEventListener(MouseEvent.CLICK, clickHandler);
  74. var initialVolume:Number = commonStatus.volume;
  75. if(commonStatus.muted) {
  76. initialVolume = 0;
  77. }
  78. myMp3Player = new JplayerMp3(initialVolume);
  79. addChild(myMp3Player);
  80. myMp4Player = new JplayerMp4(initialVolume);
  81. addChild(myMp4Player);
  82. myRtmpPlayer = new JplayerRtmp(initialVolume);
  83. addChild(myRtmpPlayer);
  84. switchType("mp3"); // set default state to mp3
  85. }
  86. // The ContextMenu only partially works. The menu select events never occur.
  87. // Investigated and it is something to do with the way jPlayer inserts the Flash on the page.
  88. // A simple test inserting the Jplayer.swf on a page using: 1) SWFObject 2.2 works. 2) AC_FL_RunContent() works.
  89. // 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.
  90. var myContextMenu:ContextMenu = new ContextMenu();
  91. myContextMenu.hideBuiltInItems();
  92. var menuItem_jPlayer:ContextMenuItem = new ContextMenuItem("jPlayer " + JplayerStatus.VERSION);
  93. var menuItem_happyworm:ContextMenuItem = new ContextMenuItem("© 2009-2014 Happyworm Ltd", true);
  94. menuItem_jPlayer.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuSelectHandler_jPlayer);
  95. menuItem_happyworm.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, menuSelectHandler_happyworm);
  96. myContextMenu.customItems.push(menuItem_jPlayer, menuItem_happyworm);
  97. contextMenu = myContextMenu;
  98. // Log console for dev compile option: debug
  99. if(debug || securityIssue) {
  100. txLog = new TextField();
  101. txLog.x = 5;
  102. txLog.y = 5;
  103. txLog.width = stage.stageWidth - 10;
  104. txLog.height = stage.stageHeight - 10;
  105. txLog.backgroundColor = 0xEEEEFF;
  106. txLog.border = true;
  107. txLog.background = true;
  108. txLog.multiline = true;
  109. txLog.text = "jPlayer " + JplayerStatus.VERSION;
  110. if(securityIssue) {
  111. txLog.visible = true;
  112. } else if(debug) {
  113. txLog.visible = false;
  114. }
  115. this.addChild(txLog);
  116. if(debug && !securityIssue) {
  117. this.stage.addEventListener(KeyboardEvent.KEY_UP, keyboardHandler);
  118. myMp3Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler);
  119. myMp4Player.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler);
  120. myRtmpPlayer.addEventListener(JplayerEvent.DEBUG_MSG, debugMsgHandler);
  121. }
  122. }
  123. // Known Flash problem with contextMenu over video player.
  124. // Add a transparent rectangle into the sprite.
  125. contextMenuFix.graphics.beginFill(0x000000, 0); // Transparent black
  126. contextMenuFix.graphics.drawRect(0, 0, 10, 10); // Arbitary rectangle
  127. contextMenuFix.graphics.endFill();
  128. addChild(contextMenuFix); // Put the sprite on the top layer.
  129. if(!securityIssue) {
  130. // Delay init() because Firefox 3.5.7+ developed a bug with local testing in Firebug.
  131. myInitTimer.addEventListener(TimerEvent.TIMER, init);
  132. myInitTimer.start();
  133. }
  134. }
  135. private function switchType(playType:String):void {
  136. switch(playType) {
  137. case "rtmpa":
  138. isRtmp=true;
  139. isMp3=false;
  140. isMp4=false;
  141. isVideo=false;
  142. break;
  143. case "rtmpv":
  144. isRtmp=true;
  145. isMp3=false;
  146. isMp4=false;
  147. isVideo=true;
  148. break;
  149. case "mp3":
  150. isRtmp=false;
  151. isMp3=true;
  152. isMp4=false;
  153. isVideo=false;
  154. break;
  155. case "mp4":
  156. isRtmp=false;
  157. isMp3=false;
  158. isMp4=true;
  159. isVideo=false;
  160. break;
  161. case "m4v":
  162. isRtmp=false;
  163. isMp3=false;
  164. isMp4=true;
  165. isVideo=true;
  166. break;
  167. }
  168. listenToMp3(isMp3);
  169. listenToMp4(isMp4);
  170. listenToRtmp(isRtmp);
  171. }
  172. private function init(e:TimerEvent):void {
  173. myInitTimer.stop();
  174. if(ExternalInterface.available && !securityIssue) {
  175. ExternalInterface.addCallback("fl_setAudio_mp3", fl_setAudio_mp3);
  176. ExternalInterface.addCallback("fl_setAudio_m4a", fl_setAudio_m4a);
  177. ExternalInterface.addCallback("fl_setVideo_m4v", fl_setVideo_m4v);
  178. ExternalInterface.addCallback("fl_setAudio_rtmp", fl_setAudio_rtmp);
  179. ExternalInterface.addCallback("fl_setVideo_rtmp", fl_setVideo_rtmp);
  180. ExternalInterface.addCallback("fl_clearMedia", fl_clearMedia);
  181. ExternalInterface.addCallback("fl_load", fl_load);
  182. ExternalInterface.addCallback("fl_play", fl_play);
  183. ExternalInterface.addCallback("fl_pause", fl_pause);
  184. ExternalInterface.addCallback("fl_play_head", fl_play_head);
  185. ExternalInterface.addCallback("fl_volume", fl_volume);
  186. ExternalInterface.addCallback("fl_mute", fl_mute);
  187. ExternalInterface.call(jQuery, "jPlayerFlashEvent", JplayerEvent.JPLAYER_READY, extractStatusData(commonStatus)); // See JplayerStatus() class for version number.
  188. }
  189. }
  190. private function checkFlashVars(p:Object):void {
  191. // Check for direct access. Inspired by mediaelement.js - Also added name to HTML object for non-IE browsers.
  192. if(ExternalInterface.objectID != null && ExternalInterface.objectID.toString() != "") {
  193. for each (var s:String in p) {
  194. if(illegalChar(s)) {
  195. securityIssue = true; // Found a security concern.
  196. }
  197. }
  198. if(!securityIssue) {
  199. if(jQueryIllegal(p.jQuery)) {
  200. securityIssue = true; // Found a security concern.
  201. }
  202. }
  203. } else {
  204. securityIssue = true; // Direct access disables the callbacks, which were a security concern.
  205. }
  206. }
  207. private function illegalChar(s:String):Boolean {
  208. // A whitelist of accepted chars.
  209. var validParam:RegExp = /^[-A-Za-z0-9_.]+$/;
  210. return !validParam.test(s);
  211. }
  212. private function jQueryIllegal(s:String):Boolean {
  213. // Check param contains the term jQuery.
  214. var validParam:RegExp = /(jQuery)/;
  215. return !validParam.test(s);
  216. }
  217. // switchType() here
  218. private function listenToMp3(active:Boolean):void {
  219. if(active) {
  220. myMp3Player.addEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
  221. myMp3Player.addEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
  222. myMp3Player.addEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
  223. myMp3Player.addEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
  224. myMp3Player.addEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
  225. myMp3Player.addEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
  226. myMp3Player.addEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
  227. myMp3Player.addEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
  228. myMp3Player.addEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
  229. myMp3Player.addEventListener(JplayerEvent.JPLAYER_WAITING, jPlayerFlashEvent); // only MP3 atm
  230. myMp3Player.addEventListener(JplayerEvent.JPLAYER_PLAYING, jPlayerFlashEvent); // only MP3 atm
  231. myMp3Player.addEventListener(JplayerEvent.JPLAYER_CANPLAY, jPlayerFlashEvent); // only MP3 atm
  232. myMp3Player.addEventListener(JplayerEvent.JPLAYER_CANPLAYTHROUGH, jPlayerFlashEvent); // only MP3 atm
  233. myMp3Player.addEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerFlashEvent);
  234. myMp3Player.addEventListener(JplayerEvent.JPLAYER_DURATIONCHANGE, jPlayerFlashEvent); // only MP3 atm
  235. } else {
  236. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
  237. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
  238. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
  239. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
  240. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
  241. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
  242. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
  243. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
  244. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
  245. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_WAITING, jPlayerFlashEvent); // only MP3 atm
  246. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_PLAYING, jPlayerFlashEvent); // only MP3 atm
  247. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_CANPLAY, jPlayerFlashEvent); // only MP3 atm
  248. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_CANPLAYTHROUGH, jPlayerFlashEvent); // only MP3 atm
  249. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerFlashEvent);
  250. myMp3Player.removeEventListener(JplayerEvent.JPLAYER_DURATIONCHANGE, jPlayerFlashEvent); // only MP3 atm
  251. }
  252. }
  253. private function listenToMp4(active:Boolean):void {
  254. if(active) {
  255. myMp4Player.addEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
  256. myMp4Player.addEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
  257. myMp4Player.addEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
  258. myMp4Player.addEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
  259. myMp4Player.addEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
  260. myMp4Player.addEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
  261. myMp4Player.addEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
  262. myMp4Player.addEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
  263. myMp4Player.addEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
  264. myMp4Player.addEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerMetaDataHandler); // Note the unique handler
  265. } else {
  266. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
  267. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
  268. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
  269. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
  270. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
  271. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
  272. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
  273. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
  274. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
  275. myMp4Player.removeEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerMetaDataHandler); // Note the unique handler
  276. }
  277. }
  278. private function listenToRtmp(active:Boolean):void {
  279. if(active) {
  280. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
  281. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
  282. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
  283. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
  284. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
  285. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
  286. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
  287. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_CANPLAY, jPlayerFlashEvent);
  288. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
  289. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
  290. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerMetaDataHandler); // Note the unique handler
  291. } else {
  292. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_ERROR, jPlayerFlashEvent);
  293. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_PROGRESS, jPlayerFlashEvent);
  294. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_TIMEUPDATE, jPlayerFlashEvent);
  295. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_ENDED, jPlayerFlashEvent);
  296. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_PLAY, jPlayerFlashEvent);
  297. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_PAUSE, jPlayerFlashEvent);
  298. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_LOADSTART, jPlayerFlashEvent);
  299. myRtmpPlayer.addEventListener(JplayerEvent.JPLAYER_CANPLAY, jPlayerFlashEvent);
  300. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_SEEKING, jPlayerFlashEvent);
  301. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_SEEKED, jPlayerFlashEvent);
  302. myRtmpPlayer.removeEventListener(JplayerEvent.JPLAYER_LOADEDMETADATA, jPlayerMetaDataHandler); // Note the unique handler
  303. }
  304. }
  305. private function fl_setAudio_mp3(src:String):Boolean {
  306. if (src != null) {
  307. log("fl_setAudio_mp3: "+src);
  308. switchType("mp3");
  309. myMp4Player.clearFile();
  310. myRtmpPlayer.clearFile();
  311. myMp3Player.setFile(src);
  312. return true;
  313. } else {
  314. log("fl_setAudio_mp3: null");
  315. return false;
  316. }
  317. }
  318. private function fl_setAudio_rtmp(src:String):Boolean {
  319. if (src != null) {
  320. log("fl_setAudio_rtmp: "+src);
  321. switchType("rtmpa");
  322. myMp4Player.clearFile();
  323. myMp3Player.clearFile();
  324. myRtmpPlayer.setFile(src,false);
  325. return true;
  326. } else {
  327. log("fl_setAudio_rtmp: null");
  328. return false;
  329. }
  330. }
  331. private function fl_setVideo_rtmp(src:String):Boolean {
  332. if (src != null) {
  333. log("fl_setVideo_rtmp: "+src);
  334. switchType("rtmpv");
  335. myMp4Player.clearFile();
  336. myMp3Player.clearFile();
  337. myRtmpPlayer.setFile(src,true);
  338. return true;
  339. } else {
  340. log("fl_setVideo_rtmp: null");
  341. return false;
  342. }
  343. }
  344. private function fl_setAudio_m4a(src:String):Boolean {
  345. if (src != null) {
  346. log("fl_setAudio_m4a: "+src);
  347. switchType("mp4")
  348. myMp3Player.clearFile();
  349. myRtmpPlayer.clearFile();
  350. myMp4Player.setFile(src);
  351. return true;
  352. } else {
  353. log("fl_setAudio_m4a: null");
  354. return false;
  355. }
  356. }
  357. private function fl_setVideo_m4v(src:String):Boolean {
  358. if (src != null) {
  359. log("fl_setVideo_m4v: "+src);
  360. switchType("m4v");
  361. myMp3Player.clearFile();
  362. myRtmpPlayer.clearFile();
  363. myMp4Player.setFile(src);
  364. return true;
  365. } else {
  366. log("fl_setVideo_m4v: null");
  367. return false;
  368. }
  369. }
  370. private function fl_clearMedia():void {
  371. log("clearMedia.");
  372. myMp3Player.clearFile();
  373. myMp4Player.clearFile();
  374. myRtmpPlayer.clearFile();
  375. }
  376. private function getType():Object {
  377. var returnType:Object;
  378. if(isMp3) {
  379. returnType=myMp3Player;
  380. }
  381. if(isRtmp) {
  382. returnType=myRtmpPlayer;
  383. }
  384. if(isMp4) {
  385. returnType=myMp4Player;
  386. }
  387. return returnType;
  388. }
  389. private function fl_load():Boolean {
  390. log("load.");
  391. var returnType:Object = getType();
  392. return returnType.load();
  393. }
  394. private function fl_play(time:Number = NaN):Boolean {
  395. log("play: time = " + time);
  396. var returnType:Object = getType();
  397. return returnType.play(time * 1000); // Flash uses milliseconds
  398. }
  399. private function fl_pause(time:Number = NaN):Boolean {
  400. log("pause: time = " + time);
  401. var returnType:Object = getType();
  402. return returnType.pause(time * 1000); // Flash uses milliseconds
  403. }
  404. private function fl_play_head(percent:Number):Boolean {
  405. log("play_head: "+percent+"%");
  406. var returnType:Object = getType();
  407. return returnType.playHead(percent);
  408. }
  409. private function fl_volume(v:Number):void {
  410. log("volume: "+v);
  411. commonStatus.volume = v;
  412. if(!commonStatus.muted) {
  413. myMp3Player.setVolume(v);
  414. myMp4Player.setVolume(v);
  415. myRtmpPlayer.setVolume(v);
  416. }
  417. }
  418. private function fl_mute(mute:Boolean):void {
  419. log("mute: "+mute);
  420. commonStatus.muted = mute;
  421. if(mute) {
  422. myMp3Player.setVolume(0);
  423. myMp4Player.setVolume(0);
  424. myRtmpPlayer.setVolume(0);
  425. } else {
  426. myMp3Player.setVolume(commonStatus.volume);
  427. myMp4Player.setVolume(commonStatus.volume);
  428. myRtmpPlayer.setVolume(commonStatus.volume);
  429. }
  430. }
  431. private function jPlayerFlashEvent(e:JplayerEvent):void {
  432. log("jPlayer Flash Event: " + e.type + ": " + e.target);
  433. if(ExternalInterface.available && !securityIssue) {
  434. ExternalInterface.call(jQuery, "jPlayerFlashEvent", e.type, extractStatusData(e.data));
  435. }
  436. }
  437. private function extractStatusData(data:JplayerStatus):Object {
  438. var myStatus:Object = {
  439. version: JplayerStatus.VERSION,
  440. src: data.src,
  441. paused: !data.isPlaying, // Changing this name requires inverting all assignments and conditional statements.
  442. srcSet: data.srcSet,
  443. seekPercent: data.seekPercent,
  444. currentPercentRelative: data.currentPercentRelative,
  445. currentPercentAbsolute: data.currentPercentAbsolute,
  446. currentTime: data.currentTime / 1000, // JavaScript uses seconds
  447. duration: data.duration / 1000, // JavaScript uses seconds
  448. videoWidth: data.videoWidth,
  449. videoHeight: data.videoHeight,
  450. volume: commonStatus.volume,
  451. muted: commonStatus.muted
  452. };
  453. log("extractStatusData: sp="+myStatus.seekPercent+" cpr="+myStatus.currentPercentRelative+" cpa="+myStatus.currentPercentAbsolute+" ct="+myStatus.currentTime+" d="+myStatus.duration);
  454. return myStatus;
  455. }
  456. private function jPlayerMetaDataHandler(e:JplayerEvent):void {
  457. log("jPlayerMetaDataHandler:" + e.target);
  458. if(ExternalInterface.available && !securityIssue) {
  459. resizeHandler(new Event(Event.RESIZE));
  460. ExternalInterface.call(jQuery, "jPlayerFlashEvent", e.type, extractStatusData(e.data));
  461. }
  462. }
  463. private function resizeHandler(e:Event):void {
  464. log("resizeHandler: stageWidth = " + stage.stageWidth + " | stageHeight = " + stage.stageHeight);
  465. var mediaX:Number = 0;
  466. var mediaY:Number = 0;
  467. var mediaWidth:Number = 0;
  468. var mediaHeight:Number = 0;
  469. var aspectRatioStage:Number = 0;
  470. var aspectRatioVideo:Number = 0;
  471. var videoItem:*;
  472. if(isRtmp) {
  473. videoItem = myRtmpPlayer;
  474. }
  475. if(isMp4) {
  476. videoItem = myMp4Player;
  477. }
  478. if(videoItem) {
  479. if(stage.stageWidth > 0 && stage.stageHeight > 0 && videoItem.myVideo.width > 0 && videoItem.myVideo.height > 0) {
  480. aspectRatioStage = stage.stageWidth / stage.stageHeight;
  481. aspectRatioVideo = videoItem.myVideo.width / videoItem.myVideo.height;
  482. if(aspectRatioStage < aspectRatioVideo) {
  483. mediaWidth = stage.stageWidth;
  484. mediaHeight = stage.stageWidth / aspectRatioVideo;
  485. mediaX = 0;
  486. mediaY = (stage.stageHeight - mediaHeight) / 2;
  487. } else {
  488. mediaWidth = stage.stageHeight * aspectRatioVideo;
  489. mediaHeight = stage.stageHeight;
  490. mediaX = (stage.stageWidth - mediaWidth) / 2;
  491. mediaY = 0;
  492. }
  493. resizeEntity(videoItem, mediaX, mediaY, mediaWidth, mediaHeight);
  494. }
  495. }
  496. if((debug || securityIssue) && stage.stageWidth > 20 && stage.stageHeight > 20) {
  497. txLog.width = stage.stageWidth - 10;
  498. txLog.height = stage.stageHeight - 10;
  499. }
  500. // Resize the sprite so it covers the entire stage area
  501. contextMenuFix.x = 0;
  502. contextMenuFix.y = 0;
  503. contextMenuFix.width = stage.stageWidth;
  504. contextMenuFix.height = stage.stageHeight;
  505. }
  506. private function resizeEntity(entity:Sprite, mediaX:Number, mediaY:Number, mediaWidth:Number, mediaHeight:Number):void {
  507. entity.x = mediaX;
  508. entity.y = mediaY;
  509. entity.width = mediaWidth;
  510. entity.height = mediaHeight;
  511. }
  512. private function clickHandler(e:MouseEvent):void {
  513. // This needs to work with RTMP format too!
  514. if(isMp3) {
  515. jPlayerFlashEvent(new JplayerEvent(JplayerEvent.JPLAYER_CLICK, myMp3Player.myStatus, "click"))
  516. } else {
  517. jPlayerFlashEvent(new JplayerEvent(JplayerEvent.JPLAYER_CLICK, myMp4Player.myStatus, "click"))
  518. }
  519. }
  520. // Handlers for context menu
  521. private function menuSelectHandler_jPlayer(e:ContextMenuEvent):void {
  522. navigateToURL(new URLRequest("http://jplayer.org/"), "_blank");
  523. }
  524. private function menuSelectHandler_happyworm(e:ContextMenuEvent):void {
  525. navigateToURL(new URLRequest("http://happyworm.com/"), "_blank");
  526. }
  527. private function log(t:String):void {
  528. if(debug) {
  529. txLog.text = t + "\n" + txLog.text;
  530. if(ExternalInterface.available && !securityIssue) {
  531. ExternalInterface.call("console.log", t);
  532. }
  533. }
  534. }
  535. private function debugMsgHandler(e:JplayerEvent):void {
  536. log(e.msg);
  537. }
  538. private function keyboardHandler(e:KeyboardEvent):void {
  539. log("keyboardHandler: e.keyCode = " + e.keyCode);
  540. switch(e.keyCode) {
  541. case 68 : // d
  542. txLog.visible = !txLog.visible;
  543. log("Toggled log display: " + txLog.visible);
  544. break;
  545. case 76 : // l
  546. if(e.ctrlKey && e.shiftKey) {
  547. txLog.text = "Cleared log.";
  548. }
  549. break;
  550. }
  551. }
  552. }
  553. }