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