diff options
Diffstat (limited to 'macros/latex/contrib/media9/players')
-rw-r--r-- | macros/latex/contrib/media9/players/APlayer.mxml | 429 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/APlayer.swf | bin | 0 -> 354878 bytes | |||
-rw-r--r-- | macros/latex/contrib/media9/players/APlayer9.mxml | 417 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/APlayer9.swf | bin | 0 -> 206165 bytes | |||
-rw-r--r-- | macros/latex/contrib/media9/players/BSD-License | 32 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/SMPfixes.patch | 158 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/SlideShow.mxml | 482 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/SlideShow.swf | bin | 0 -> 326715 bytes | |||
-rw-r--r-- | macros/latex/contrib/media9/players/StrobeMediaPlayback-license | 5 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/StrobeMediaPlayback.swf | bin | 0 -> 275747 bytes | |||
-rw-r--r-- | macros/latex/contrib/media9/players/VPlayer.mxml | 338 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/VPlayer.swf | bin | 0 -> 483412 bytes | |||
-rw-r--r-- | macros/latex/contrib/media9/players/VPlayer9.mxml | 318 | ||||
-rw-r--r-- | macros/latex/contrib/media9/players/VPlayer9.swf | bin | 0 -> 219242 bytes |
14 files changed, 2179 insertions, 0 deletions
diff --git a/macros/latex/contrib/media9/players/APlayer.mxml b/macros/latex/contrib/media9/players/APlayer.mxml new file mode 100644 index 0000000000..b03f04a4fc --- /dev/null +++ b/macros/latex/contrib/media9/players/APlayer.mxml @@ -0,0 +1,429 @@ +<?xml version="1.0"?> +<!-- --> +<!-- Apache Flex 4 source file of APlayer.swf, --> +<!-- a FlashPlayer-10 compatible component for playing --> +<!-- MP3 audio files and streams. --> +<!-- --> +<!-- version 20150601 --> +<!-- --> +<!-- --> +<!-- The free Apache Flex 4 SDK is required to compile --> +<!-- this file. Get it from --> +<!-- --> +<!-- http://flex.apache.org/download-binaries.html --> +<!-- --> +<!-- and run --> +<!-- --> +<!-- mxmlc -static-link-runtime-shared-libraries APlayer.mxml --> +<!-- --> +<!-- on the command line. --> +<!-- --> +<!-- --> +<!-- Copyright (C) 2012-today Alexander Grahn --> +<!-- --> +<!-- This work may be distributed and/or modified under the --> +<!-- conditions of the LaTeX Project Public License. --> +<!-- --> +<!-- The latest version of this license is in --> +<!-- http://www.latex-project.org/lppl.txt --> +<!-- --> +<!-- This work has the LPPL maintenance status `maintained'. --> +<!-- --> +<!-- The current maintainer of this work is A. Grahn. --> +<!-- --> + +<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + preinitialize="initialise(this.parameters);" + applicationComplete="initSound();addEventListeners(); + fadeTargets=new Array(playProgress, caption);" + creationComplete="initCallBacks();initContext();" + mouseDown="pause();setFocus();" + mouseUp="play();" + backgroundAlpha="0" +> + + <fx:Script> + <![CDATA[ + [Bindable] private var source:String; + [Bindable] private var policy:String=null; + [Bindable] private var autoPlay:Boolean=false; + [Bindable] private var loop:Boolean=false; + [Bindable] private var vol:Number=0.75; + [Bindable] private var pan:Number=0; + [Bindable] private var hideBar:Boolean=false; + [Bindable] private var fadeTargets:Array; + [Bindable] private var txtAlign:String; + + private var snd:Sound; + private var id3:ID3Info; + private var sndCh:SoundChannel; + private var sndTr:SoundTransform; + private var playResumePos:Number = 0; + private var pauseAtPos:Number = -1; + private var toBePaused:Boolean = false; + private var plyng:Boolean = false; + private var muted:Boolean = false; + private var lastVol:Number; + + private var deltaSeek:Number; + private var curTime:Number; + private var keyPressed:Boolean=false; + private var mouseIsOver:Boolean=false; + + private function initialise(flashVars:Object):void { + source=flashVars.source; + if(flashVars.policy) policy=flashVars.policy; + if(flashVars.autoPlay=='true') autoPlay=true; + if(flashVars.loop=='true') loop=true; + if(flashVars.volume) vol=Number(flashVars.volume); + if(flashVars.balance) pan=Number(flashVars.balance); + if(flashVars.hideBar=='true') hideBar=true; + } + + import mx.controls.Alert; + + private function initSound():void { + snd = new Sound(); id3=null; + sndTr = new SoundTransform(vol, pan); + snd.addEventListener(Event.ID3, onID3Info); + snd.addEventListener(IOErrorEvent.IO_ERROR, onError); + snd.addEventListener(ProgressEvent.PROGRESS, onProgress); + snd.addEventListener(Event.COMPLETE, onComplete); + if(policy) Security.loadPolicyFile(policy); + snd.load(new URLRequest(source), new SoundLoaderContext(1000, true)); + if(autoPlay) play(); + } + + private function onMouseOver(e:MouseEvent):void { + mouseIsOver=true; + fadeEffect.end(); + playProgress.alpha=caption.alpha=1.0; + } + + private function onMouseOut(e:MouseEvent):void { + mouseIsOver=false; + fadeEffect.play(); + } + + private function onKeyDown(e:KeyboardEvent):void { + switch(e.keyCode) { + case 32: //space bar + playPause(); + break; + case 36: //home + pause(); + playResumePos=(0); + break; + case 35: //end + if(playProgress.indeterminate) break; + pause(); + playResumePos=(snd.length); + break; + case 37: //<-- + fadeEffect.end(); + playProgress.alpha=caption.alpha=1.0; + if(e.ctrlKey){ + pan=Math.max(-1,pan-0.025); + balance(pan); + break; + } + if(!keyPressed){ + deltaSeek=Math.max(100,snd.length/10000); + if(plyng) + curTime=sndCh.position; + else + curTime=playResumePos; + } + keyPressed=true; + playResumePos=Math.max(0,curTime-deltaSeek); + if(plyng) seek(playResumePos/1000); + deltaSeek*=1.1; + break; + case 39: //--> + fadeEffect.end(); + playProgress.alpha=caption.alpha=1.0; + if(e.ctrlKey){ + pan=Math.min(1,pan+0.025); + balance(pan); + break; + } + if(!keyPressed){ + deltaSeek=Math.max(100,snd.length/10000); + if(plyng) + curTime=sndCh.position; + else + curTime=playResumePos; + } + keyPressed=true; + playResumePos=Math.min(snd.length-10,curTime+deltaSeek); + seek(playResumePos/1000); + deltaSeek*=1.1; + break; + case 38: + vol=Math.min(1,vol+0.025); + volume(vol); + break; + case 40: + if(e.ctrlKey){ + pan=0; + balance(pan); + break; + } + vol=Math.max(0,vol-0.025); + volume(vol); + break; + default: + if(e.charCode==109) mute(); //`m' + } + } + + private function onKeyUp(e:KeyboardEvent):void { + switch(e.keyCode) { + case 37: //<-- + case 39: //--> + deltaSeek=Math.max(100,snd.length/10000); + keyPressed=false; + if (!mouseIsOver) fadeEffect.play(); + break; + } + } + + private function formatLabel(s:Number):String { + s/=1000; + var hrs:Number = Math.floor(s / 3600); + var min:Number = Math.floor(s / 60 % 60); + var sec:Number = Math.floor(s % 60); + var fmtd:String=''; + if(hrs>0) fmtd = String(hrs)+':'; + if(hrs>0 && min <10) fmtd+='0'; + fmtd += String(min)+':'; + if(sec<10) fmtd+='0'; + fmtd += String(sec); + txtAlign="center"; + try{ + if(id3.songName) + fmtd += ' '+ String.fromCharCode(0x2014) + ' ' + id3.songName; + if(id3.artist) fmtd += ' | ' + id3.artist; + if(id3.album) fmtd += ' | ' + id3.album; + if(id3) txtAlign="start"; + }catch(e:Object){} + return fmtd; + } + + private function addEventListeners():void { + this.addEventListener(Event.ENTER_FRAME, onEnterFrame); + this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); + this.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); + this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); + this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); + } + + private function setSource(s:String):void { + pause(); + source=s; + initSound(); + pause();seek(0); + } + + private function loadPolicy(p:String):void {policy=p;} + + private function play(p:Number=-1):void { + if(p>=0) seek(p); + if(plyng) return; + try{sndCh = snd.play(playResumePos, 0, sndTr);} + catch(e:Error){Alert.show(e.message,'Error');} + sndCh.addEventListener(Event.SOUND_COMPLETE, onSoundComplete); + plyng = true; + } + + private function pause(p:Number=-1):void { + if(p>=0){pauseAtPos=p*1000;return;} + if(!plyng) return; + playResumePos = sndCh.position; + sndCh.stop(); + plyng = false; + } + + private function playPause():void { + if(plyng) pause(); else play(); + } + + private function seek(p:Number):void { + playResumePos = p*1000; + if(!plyng) return; + sndCh.stop(); + plyng = false; + play(); + } + + private function rewind():void { + seek(0); + } + + private function volume(v:Number):void { + sndTr.volume = v; + sndCh.soundTransform=sndTr; + } + + private function mute():void { + if(muted) { + if(lastVol==0) lastVol=0.75; + volume(lastVol); + muted=false; + } + else { + lastVol = sndTr.volume + volume(0); + muted=true; + } + } + + private function balance(p:Number):void { + sndTr.pan = p; + sndCh.soundTransform=sndTr; + } + + private function currentTime():Number { + return sndCh.position/1000; + } + + private function playing():Boolean { + return plyng; + } + + private function duration():Number { + return snd.length/1000; + } + + private function ismuted():Boolean { + return muted; + } + + private function initCallBacks():void { + ExternalInterface.addCallback("play", play); + ExternalInterface.addCallback("pause", pause); + ExternalInterface.addCallback("playPause", playPause); + ExternalInterface.addCallback("seek", seek); + ExternalInterface.addCallback("rewind", rewind); + ExternalInterface.addCallback("volume", volume); + ExternalInterface.addCallback("balance", balance); + ExternalInterface.addCallback("mute", mute); + ExternalInterface.addCallback("setSource", setSource); + ExternalInterface.addCallback("loadPolicy", loadPolicy); + ExternalInterface.addCallback("currentTime", currentTime); + ExternalInterface.addCallback("duration", duration); + ExternalInterface.addCallback("playing", playing); + ExternalInterface.addCallback("muted", ismuted); + } + + private function initContext():void { + this.contextMenu.hideBuiltInItems(); + + var itemPlayPause:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemPlayPause); + itemPlayPause.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{playPause();}); + + var itemRewind:ContextMenuItem = new ContextMenuItem("Rewind, [Home]"); + this.contextMenu.customItems.push(itemRewind); + itemRewind.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{pause();playResumePos=(0);}); + + var itemGotoEnd:ContextMenuItem=new ContextMenuItem("Goto End, [End]"); + this.contextMenu.customItems.push(itemGotoEnd); + itemGotoEnd.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{ + if(playProgress.indeterminate) return; + pause();playResumePos=(snd.length);}); + + var itemMute:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemMute); + itemMute.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{mute();}); + + this.contextMenu.customItems.push( + new ContextMenuItem("via keyboard:", true, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Seek, [\u2190]/[\u2192]", false, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Volume, [\u2191]/[\u2193]", false, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Balance, [Ctrl]+[\u2190]/[\u2193]/[\u2192]", + false, false, true)); + + this.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, + function(e:ContextMenuEvent):void{ + itemPlayPause.caption=(plyng ? "Pause" : "Play")+", [Space]"; + itemMute.caption=(muted ? "Unmute" : "Mute")+", [m]";} + ); + } + + private function onSoundComplete(e:Event):void { + plyng = false; + playResumePos = 0; + if(loop) play(); + } + + private function onComplete(e:Event):void { + playProgress.indeterminate=false; + } + + private function onProgress(e:ProgressEvent):void { + playProgress.indeterminate=true; + } + + private function onEnterFrame(e:Event):void { + if(!playProgress.indeterminate) { + if(plyng) { + playProgress.setProgress(sndCh.position,snd.length); + caption.text=formatLabel(sndCh.position); + } else { + playProgress.setProgress(playResumePos,snd.length); + caption.text=formatLabel(playResumePos); + } + }else{ + if(plyng) { + playProgress.setProgress(Math.random(),1); + caption.text=formatLabel(sndCh.position); + } else { + playProgress.setProgress(snd.bytesLoaded,snd.bytesTotal); + caption.text=formatLabel(playResumePos); + } + } + if(plyng&&pauseAtPos>=0&&sndCh.position<pauseAtPos) + toBePaused=true; + if( + plyng&&pauseAtPos>=0&& + sndCh.position>=pauseAtPos&&toBePaused + ){ + pause(); + pauseAtPos=-1; + toBePaused=false; + } + } + + private function onID3Info(e:Event):void {id3 = e.target.id3;} + + private function onError(e:ErrorEvent):void { + Alert.show(e.type, e.text); + } + ]]> + </fx:Script> + + <fx:Declarations> + <s:Fade id="fadeEffect" targets="{fadeTargets}" alphaFrom="1.0" alphaTo="0" + duration="2000"/> + </fx:Declarations> + + <mx:ProgressBar width="100%" height="100%" mode="manual" + labelPlacement="center" label="" id="playProgress" + visible="{!hideBar}" + /> + + <s:Label id="caption" width="100%" height="100%" verticalCenter="0" + paddingTop="2" fontWeight="bold" verticalAlign="middle" visible="{!hideBar}" + textAlign="{txtAlign}" paddingLeft="5" + /> +</s:Application> diff --git a/macros/latex/contrib/media9/players/APlayer.swf b/macros/latex/contrib/media9/players/APlayer.swf Binary files differnew file mode 100644 index 0000000000..7aea76a9d8 --- /dev/null +++ b/macros/latex/contrib/media9/players/APlayer.swf diff --git a/macros/latex/contrib/media9/players/APlayer9.mxml b/macros/latex/contrib/media9/players/APlayer9.mxml new file mode 100644 index 0000000000..9ea40902df --- /dev/null +++ b/macros/latex/contrib/media9/players/APlayer9.mxml @@ -0,0 +1,417 @@ +<?xml version="1.0"?> +<!-- --> +<!-- Adobe Flex 3 source file of APlayer9.swf, --> +<!-- a FlashPlayer-9 compatible component for playing --> +<!-- MP3 audio files and streams. --> +<!-- --> +<!-- version 20150601 --> +<!-- --> +<!-- Copyright (C) 2012-today Alexander Grahn --> +<!-- --> +<!-- This work may be distributed and/or modified under the --> +<!-- conditions of the LaTeX Project Public License. --> +<!-- --> +<!-- The latest version of this license is in --> +<!-- http://www.latex-project.org/lppl.txt --> +<!-- --> +<!-- This work has the LPPL maintenance status `maintained'. --> +<!-- --> +<!-- The current maintainer of this work is A. Grahn. --> +<!-- --> + +<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" + preinitialize="initialise(this.parameters);" + applicationComplete="initSound();addEventListeners();" + creationComplete="initCallBacks();initContext();" + mouseDown="pause();setFocus();" + mouseUp="play();" + backgroundAlpha="0" + paddingTop="0" paddingBottom="0" + paddingLeft="0" paddingRight="0" + layout="absolute" clipContent="false" +> + + <mx:Script> + <![CDATA[ + [Bindable] private var source:String; + [Bindable] private var policy:String=null; + [Bindable] private var autoPlay:Boolean=false; + [Bindable] private var loop:Boolean=false; + [Bindable] private var vol:Number=0.75; + [Bindable] private var pan:Number=0; + [Bindable] private var hideBar:Boolean=false; + [Bindable] private var txtAlign:String; + + private var snd:Sound; + private var id3:ID3Info; + private var sndCh:SoundChannel; + private var sndTr:SoundTransform; + private var playResumePos:Number = 0; + private var pauseAtPos:Number = -1; + private var toBePaused:Boolean = false; + private var plyng:Boolean = false; + private var muted:Boolean = false; + private var lastVol:Number; + + private var deltaSeek:Number; + private var curTime:Number; + private var keyPressed:Boolean=false; + private var mouseIsOver:Boolean=false; + + import flash.external.*; + private function initialise(flashVars:Object):void { + source=flashVars.source; + if(flashVars.policy) policy=flashVars.policy; + if(flashVars.autoPlay=='true') autoPlay=true; + if(flashVars.loop=='true') loop=true; + if(flashVars.volume) vol=Number(flashVars.volume); + if(flashVars.balance) pan=Number(flashVars.balance); + if(flashVars.hideBar=='true') hideBar=true; + } + + import mx.controls.Alert; + + private function initSound():void { + snd = new Sound(); id3=null; + sndTr = new SoundTransform(vol, pan); + snd.addEventListener(Event.ID3, onID3Info); + snd.addEventListener(IOErrorEvent.IO_ERROR, onError); + snd.addEventListener(ProgressEvent.PROGRESS, onProgress); + snd.addEventListener(Event.COMPLETE, onComplete); + if(policy) Security.loadPolicyFile(policy); + snd.load(new URLRequest(source), new SoundLoaderContext(1000, true)); + if(autoPlay) play(); + } + + private function onMouseOver(e:MouseEvent):void { + mouseIsOver=true; + fadeEffect.end(); + playProgress.alpha=caption.alpha=1.0; + caption.visible=!hideBar; + } + + private function onMouseOut(e:MouseEvent):void { + mouseIsOver=false; + fadeEffect.play(); + } + + private function onKeyDown(e:KeyboardEvent):void { + switch(e.keyCode) { + case 32: //space bar + playPause(); + break; + case 36: //home + pause(); + playResumePos=(0); + break; + case 35: //end + if(playProgress.indeterminate) break; + pause(); + playResumePos=(snd.length); + break; + case 37: //<-- + fadeEffect.end(); + playProgress.alpha=caption.alpha=1.0; + caption.visible=!hideBar; + if(e.ctrlKey){ + pan=Math.max(-1,pan-0.025); + balance(pan); + break; + } + if(!keyPressed){ + deltaSeek=Math.max(100,snd.length/10000); + if(plyng) + curTime=sndCh.position; + else + curTime=playResumePos; + } + keyPressed=true; + playResumePos=Math.max(0,curTime-deltaSeek); + if(plyng) seek(playResumePos/1000); + deltaSeek*=1.1; + break; + case 39: //--> + fadeEffect.end(); + playProgress.alpha=caption.alpha=1.0; + caption.visible=!hideBar; + if(e.ctrlKey){ + pan=Math.min(1,pan+0.025); + balance(pan); + break; + } + if(!keyPressed){ + deltaSeek=Math.max(100,snd.length/10000); + if(plyng) + curTime=sndCh.position; + else + curTime=playResumePos; + } + keyPressed=true; + playResumePos=Math.min(snd.length-10,curTime+deltaSeek); + seek(playResumePos/1000); + deltaSeek*=1.1; + break; + case 38: + vol=Math.min(1,vol+0.025); + volume(vol); + break; + case 40: + if(e.ctrlKey){ + pan=0; + balance(pan); + break; + } + vol=Math.max(0,vol-0.025); + volume(vol); + break; + default: + if(e.charCode==109) mute(); //`m' + } + } + + private function onKeyUp(e:KeyboardEvent):void { + switch(e.keyCode) { + case 37: //<-- + case 39: //--> + deltaSeek=Math.max(100,snd.length/10000); + keyPressed=false; + if (!mouseIsOver) fadeEffect.play(); + break; + } + } + + private function formatLabel(s:Number):String { + s/=1000; + var hrs:Number = Math.floor(s / 3600); + var min:Number = Math.floor(s / 60 % 60); + var sec:Number = Math.floor(s % 60); + var fmtd:String=''; + if(hrs>0) fmtd = String(hrs)+':'; + if(hrs>0 && min <10) fmtd+='0'; + fmtd += String(min)+':'; + if(sec<10) fmtd+='0'; + fmtd += String(sec); + txtAlign="center"; + try{ + if(id3.songName) + fmtd += ' '+ String.fromCharCode(0x2014) + ' ' + id3.songName; + if(id3.artist) fmtd += ' | ' + id3.artist; + if(id3.album) fmtd += ' | ' + id3.album; + if(id3) txtAlign="start"; + }catch(e:Object){} + return fmtd; + } + + private function addEventListeners():void { + this.addEventListener(Event.ENTER_FRAME, onEnterFrame); + this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); + this.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); + this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut); + this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver); + } + + private function setSource(s:String):void { + pause(); + source=s; + initSound(); + pause();seek(0); + } + + private function loadPolicy(p:String):void {policy=p;} + + private function play(p:Number=-1):void { + if(p>=0) seek(p); + if(plyng) return; + try{sndCh = snd.play(playResumePos, 0, sndTr);} + catch(e:Error){Alert.show(e.message,'Error');} + sndCh.addEventListener(Event.SOUND_COMPLETE, onSoundComplete); + plyng = true; + } + + private function pause(p:Number=-1):void { + if(p>=0){pauseAtPos=p*1000;return;} + if(!plyng) return; + playResumePos = sndCh.position; + sndCh.stop(); + plyng = false; + } + + private function playPause():void { + if(plyng) pause(); else play(); + } + + private function seek(p:Number):void { + playResumePos = p*1000; + if(!plyng) return; + sndCh.stop(); + plyng = false; + play(); + } + + private function rewind():void { + seek(0); + } + + private function volume(v:Number):void { + sndTr.volume = v; + sndCh.soundTransform=sndTr; + } + + private function mute():void { + if(muted) { + if(lastVol==0) lastVol=0.75; + volume(lastVol); + muted=false; + } + else { + lastVol = sndTr.volume + volume(0); + muted=true; + } + } + + private function balance(p:Number):void { + sndTr.pan = p; + sndCh.soundTransform=sndTr; + } + + private function currentTime():Number { + return sndCh.position/1000; + } + + private function playing():Boolean { + return plyng; + } + + private function duration():Number { + return snd.length/1000; + } + + private function ismuted():Boolean { + return muted; + } + + private function initCallBacks():void { + ExternalInterface.addCallback("play", play); + ExternalInterface.addCallback("pause", pause); + ExternalInterface.addCallback("playPause", playPause); + ExternalInterface.addCallback("seek", seek); + ExternalInterface.addCallback("rewind", rewind); + ExternalInterface.addCallback("volume", volume); + ExternalInterface.addCallback("balance", balance); + ExternalInterface.addCallback("mute", mute); + ExternalInterface.addCallback("setSource", setSource); + ExternalInterface.addCallback("loadPolicy", loadPolicy); + ExternalInterface.addCallback("currentTime", currentTime); + ExternalInterface.addCallback("duration", duration); + ExternalInterface.addCallback("playing", playing); + ExternalInterface.addCallback("muted", ismuted); + } + + private function initContext():void { + this.contextMenu.hideBuiltInItems(); + + var itemPlayPause:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemPlayPause); + itemPlayPause.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{playPause();}); + + var itemRewind:ContextMenuItem = new ContextMenuItem("Rewind, [Home]"); + this.contextMenu.customItems.push(itemRewind); + itemRewind.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{pause();playResumePos=(0);}); + + var itemGotoEnd:ContextMenuItem=new ContextMenuItem("Goto End, [End]"); + this.contextMenu.customItems.push(itemGotoEnd); + itemGotoEnd.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{ + if(playProgress.indeterminate) return; + pause();playResumePos=(snd.length);}); + + var itemMute:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemMute); + itemMute.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{mute();}); + + this.contextMenu.customItems.push( + new ContextMenuItem("via keyboard:", true, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Seek, [\u2190]/[\u2192]", false, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Volume, [\u2191]/[\u2193]", false, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Balance, [Ctrl]+[\u2190]/[\u2193]/[\u2192]", + false, false, true)); + + this.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, + function(e:ContextMenuEvent):void{ + itemPlayPause.caption=(plyng ? "Pause" : "Play")+", [Space]"; + itemMute.caption=(muted ? "Unmute" : "Mute")+", [m]";} + ); + } + + private function onSoundComplete(e:Event):void { + plyng = false; + playResumePos = 0; + if(loop) play(); + } + + private function onComplete(e:Event):void { + playProgress.indeterminate=false; + } + + private function onProgress(e:ProgressEvent):void { + playProgress.indeterminate=true; + } + + private function onEnterFrame(e:Event):void { + if(!playProgress.indeterminate) { + if(plyng) { + playProgress.setProgress(sndCh.position,snd.length); + caption.text=formatLabel(sndCh.position); + } else { + playProgress.setProgress(playResumePos,snd.length); + caption.text=formatLabel(playResumePos); + } + }else{ + if(plyng) { + playProgress.setProgress(Math.random(),1); + caption.text=formatLabel(sndCh.position); + } else { + playProgress.setProgress(snd.bytesLoaded,snd.bytesTotal); + caption.text=formatLabel(playResumePos); + } + } + if(plyng&&pauseAtPos>=0&&sndCh.position<pauseAtPos) + toBePaused=true; + if( + plyng&&pauseAtPos>=0&& + sndCh.position>=pauseAtPos&&toBePaused + ){ + pause(); + pauseAtPos=-1; + toBePaused=false; + } + } + + private function onID3Info(e:Event):void {id3 = e.target.id3;} + + private function onError(e:ErrorEvent):void { + Alert.show(e.type, e.text); + } + ]]> + </mx:Script> + + <mx:Fade id="fadeEffect" target="{playProgress}" alphaFrom="1.0" alphaTo="0" + effectEnd="caption.visible=false" duration="2000"/> + + <mx:ProgressBar width="100%" height="100%" mode="manual" + labelPlacement="center" label="" id="playProgress" + visible="{!hideBar}" + /> + + <mx:Label id="caption" width="100%" verticalCenter="0" + paddingTop="2" fontWeight="bold" visible="{!hideBar}" + textAlign="{txtAlign}" paddingLeft="5" + /> +</mx:Application> diff --git a/macros/latex/contrib/media9/players/APlayer9.swf b/macros/latex/contrib/media9/players/APlayer9.swf Binary files differnew file mode 100644 index 0000000000..eb26630025 --- /dev/null +++ b/macros/latex/contrib/media9/players/APlayer9.swf diff --git a/macros/latex/contrib/media9/players/BSD-License b/macros/latex/contrib/media9/players/BSD-License new file mode 100644 index 0000000000..67b0fe7164 --- /dev/null +++ b/macros/latex/contrib/media9/players/BSD-License @@ -0,0 +1,32 @@ +The BSD License + +Copyright (c) 2010, Adobe Systems Incorporated +All rights reserved. + +Redistribution and use in source and binary forms, with or +without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the name of Adobe Systems Incorporated, nor the names of its +contributors may be used to endorse or promote products derived from this +software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/macros/latex/contrib/media9/players/SMPfixes.patch b/macros/latex/contrib/media9/players/SMPfixes.patch new file mode 100644 index 0000000000..04e48f4128 --- /dev/null +++ b/macros/latex/contrib/media9/players/SMPfixes.patch @@ -0,0 +1,158 @@ +--- ./player/StrobeMediaPlayback/src/org/osmf/player/chrome/widgets/PlayButtonOverlay.as.orig 2012-11-14 15:48:22.000000000 +0100 ++++ ./player/StrobeMediaPlayback/src/org/osmf/player/chrome/widgets/PlayButtonOverlay.as 2012-11-20 15:14:02.000000000 +0100 +@@ -98,6 +98,11 @@ + override protected function onMouseClick(event:MouseEvent):void + { + var playable:PlayTrait = media.getTrait(MediaTraitType.PLAY) as PlayTrait; ++ var seekable:SeekTrait = media.getTrait(MediaTraitType.SEEK) as SeekTrait; ++ if(playable.playState == PlayState.STOPPED) ++ { ++ try{seekable.seek(0);}catch(e:Object){} ++ } + playable.play(); + } + +@@ -134,4 +139,4 @@ + /* static */ + private static const VISIBILITY_DELAY:int = 500; + } +-} +\ No newline at end of file ++} +--- ./player/StrobeMediaPlayback/src/org/osmf/player/chrome/widgets/Slider.as.orig 2012-11-14 15:48:22.000000000 +0100 ++++ ./player/StrobeMediaPlayback/src/org/osmf/player/chrome/widgets/Slider.as 2012-11-14 15:42:53.000000000 +0100 +@@ -106,7 +106,7 @@ + if (_enabled && _sliding == false) + { + _sliding = true; +- stage.addEventListener(MouseEvent.MOUSE_UP, onStageExitDrag); ++ stage.addEventListener(MouseEvent.MOUSE_UP, onStageExitDrag, true); + updateFace(down); + scrubTimer.start(); + dispatchEvent(new ScrubberEvent(ScrubberEvent.SCRUB_START)); +--- ./player/StrobeMediaPlayback/src/org/osmf/player/chrome/widgets/PlayButton.as.orig 2012-11-14 15:48:22.000000000 +0100 ++++ ./player/StrobeMediaPlayback/src/org/osmf/player/chrome/widgets/PlayButton.as 2012-11-14 15:42:53.000000000 +0100 +@@ -26,6 +26,7 @@ + import org.osmf.traits.MediaTraitType; + import org.osmf.traits.PlayState; + import org.osmf.traits.PlayTrait; ++ import org.osmf.traits.SeekTrait; + + public class PlayButton extends PlayableButton + { +@@ -44,6 +45,11 @@ + override protected function onMouseClick(event:MouseEvent):void + { + var playable:PlayTrait = media.getTrait(MediaTraitType.PLAY) as PlayTrait; ++ var seekable:SeekTrait = media.getTrait(MediaTraitType.SEEK) as SeekTrait; ++ if(playable.playState == PlayState.STOPPED) ++ { ++ try{seekable.seek(0);}catch(e:Object){} ++ } + playable.play(); + event.stopImmediatePropagation(); + } +@@ -58,4 +64,4 @@ + } + } + } +-} +\ No newline at end of file ++} +--- ./player/StrobeMediaPlayback/src/StrobeMediaPlayback.as.orig 2012-11-14 15:48:22.000000000 +0100 ++++ ./player/StrobeMediaPlayback/src/StrobeMediaPlayback.as 2012-11-14 15:42:54.000000000 +0100 +@@ -52,6 +52,7 @@ + import org.osmf.traits.MediaTraitType; + import org.osmf.traits.PlayState; + import org.osmf.traits.PlayTrait; ++ import org.osmf.traits.SeekTrait; + import org.osmf.utils.OSMFSettings; + import org.osmf.utils.OSMFStrings; + +@@ -152,6 +153,7 @@ + + player.addEventListener(TimeEvent.COMPLETE, onComplete); + player.addEventListener(MediaErrorEvent.MEDIA_ERROR, onMediaError); ++ player.addEventListener(MediaPlayerCapabilityChangeEvent.CAN_PLAY_CHANGE, onCanPlayChange); + + // Add DRM error handler + var drmManager:DRMManager = DRMManager.getDRMManager(); +@@ -338,6 +340,8 @@ + mainContainer.backgroundAlpha = 0; + mainContainer.addEventListener(MouseEvent.DOUBLE_CLICK, onFullScreenRequest); + mainContainer.addEventListener(MouseEvent.CLICK, onMainClick, false); ++ mainContainer.addEventListener(MouseEvent.MOUSE_DOWN, onMainDown, false); ++ mainContainer.addEventListener(MouseEvent.MOUSE_UP, onMainUp, false); + mainContainer.doubleClickEnabled = true; + + addChild(mainContainer); +@@ -415,6 +419,9 @@ + } + + player.addEventListener(PlayEvent.PLAY_STATE_CHANGE, onSetAutoHide); ++ ++ controlBarContainer.addEventListener(MouseEvent.MOUSE_DOWN, onControlBarAny, false); ++ controlBarContainer.addEventListener(MouseEvent.MOUSE_UP, onControlBarAny, false); + + layout(); + +@@ -757,6 +764,38 @@ + } + } + ++ private function onMainDown(event:MouseEvent):void ++ { ++ var playable:PlayTrait = player.media.getTrait(MediaTraitType.PLAY) as PlayTrait; ++ if (playable.playState == PlayState.PLAYING) ++ { ++ playable.pause(); ++ } ++ } ++ ++ private function onMainUp(event:MouseEvent):void ++ { ++ var playable:PlayTrait = player.media.getTrait(MediaTraitType.PLAY) as PlayTrait; ++ var seekable:SeekTrait = player.media.getTrait(MediaTraitType.SEEK) as SeekTrait; ++ if(playable.playState == PlayState.STOPPED) ++ { ++ if(player.canSeek){seekable.seek(0);} ++ playable.play(); ++ } ++ else if(playable.playState == PlayState.PAUSED) ++ { ++ playable.play(); ++ } ++ } ++ ++ private function onControlBarAny(event:MouseEvent):void ++ { ++ if(event.eventPhase == EventPhase.BUBBLING_PHASE) ++ { ++ event.stopImmediatePropagation(); ++ } ++ } ++ + /** + * Toggles full screen state. + */ +@@ -1036,12 +1075,20 @@ + && configuration.endOfVideoOverlay != "" + && player.loop == false + && player.playing == false ++ && player.autoRewind == true + ) + { + processPoster(configuration.endOfVideoOverlay); + } + } + ++ private function onCanPlayChange(event:MediaPlayerCapabilityChangeEvent):void ++ { ++ // Make sure this event gets handled only once: ++ player.removeEventListener(event.type, arguments.callee); ++ player.play(); player.stop(); ++ } ++ + private function onMediaError(event:MediaErrorEvent):void + { + // Make sure this event gets handled only once: diff --git a/macros/latex/contrib/media9/players/SlideShow.mxml b/macros/latex/contrib/media9/players/SlideShow.mxml new file mode 100644 index 0000000000..c55c41fd13 --- /dev/null +++ b/macros/latex/contrib/media9/players/SlideShow.mxml @@ -0,0 +1,482 @@ +<?xml version="1.0"?> +<!-- --> +<!-- Apache Flex 4 source file of SlideShow.swf, --> +<!-- a FlashPlayer-10 compatible component for --> +<!-- JPEG/PNG/GIF slideshows. --> +<!-- --> +<!-- version 20150718 --> +<!-- --> +<!-- --> +<!-- The free Apache Flex 4 SDK is required to compile --> +<!-- this file. Get it from --> +<!-- --> +<!-- http://flex.apache.org/download-binaries.html --> +<!-- --> +<!-- and run --> +<!-- --> +<!-- mxmlc -static-link-runtime-shared-libraries SlideShow.mxml --> +<!-- --> +<!-- on the command line. --> +<!-- --> +<!-- --> +<!-- Copyright (C) 2015-today Alexander Grahn --> +<!-- --> +<!-- This work may be distributed and/or modified under the --> +<!-- conditions of the LaTeX Project Public License. --> +<!-- --> +<!-- The latest version of this license is in --> +<!-- http://www.latex-project.org/lppl.txt --> +<!-- --> +<!-- This work has the LPPL maintenance status `maintained'. --> +<!-- --> +<!-- The current maintainer of this work is A. Grahn. --> +<!-- --> +<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + preinitialize="initialise(this.parameters);" + applicationComplete="initApp();" + resize="if(dynResolution){dynResolution=false;forcedByUsr=true;setImgSrc();}" + backgroundAlpha="0" +> + <fx:Script> + <![CDATA[ + import mx.managers.CursorManager; + + private var slideshowXML:XML; + private var setXMLDone:Boolean; + private var isEnabled:Boolean=true; + + private function setXML(s:String):void { + var loader:URLLoader = new URLLoader(); + loader.addEventListener(Event.COMPLETE, onURLLoaderComplete); + loader.addEventListener(IOErrorEvent.IO_ERROR, onAnyError); + loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onAnyError); + isEnabled=false; + slideshowXML=null; + setXMLDone=false; + isIOError=true; + CursorManager.setBusyCursor(); + timeoutTimer.start(); + loader.load(new URLRequest(s)); + } + + private function onURLLoaderComplete(event:Event):void + { + CursorManager.removeBusyCursor(); + isEnabled=true; + var loader:URLLoader = event.target as URLLoader; + if (loader != null) + { + slideshowXML = new XML(loader.data); + setXMLDone=true; + rotations=new Object(); + seek(0); + if(autoPlay) play(); + } + } + + [Bindable] private var delay:Number=5; + [Bindable] private var autoPlay:Boolean=false; + private var xmlfile:String=null; + + private function initialise(flashVars:Object):void { + xmlfile=flashVars.xml; + if(flashVars.delay){delay=flashVars.delay} + if(flashVars.autoPlay=='true'){autoPlay=true} + } + + private var reloadTimer:Timer = null; + private var playTimer:Timer = null; + private var timeoutTimer:Timer; + private var curFile:String; + + private var idx:Number=0; + private var urlIdx:Number=0; + [Bindable] private var src1:String; + [Bindable] private var src2:String; + + private var rotations:Object; + + private function rotate(n:Number=1):void { + if(Img1.visible){ + n==0 ? Img1.rotation=0 : Img1.rotation+=90*Math.floor(n); + Img1.rotation%=360; + rotations[slideshowXML.Img[idx].URL[urlIdx].toString()]= + Img1.rotation/90; + } else { + n==0 ? Img2.rotation=0 : Img2.rotation+=90*Math.floor(n); + Img2.rotation%=360; + rotations[slideshowXML.Img[idx].URL[urlIdx].toString()]= + Img2.rotation/90; + } + } + + import mx.collections.ArrayCollection; + import spark.collections.Sort; + import spark.collections.SortField; + + private var forcedByUsr:Boolean; + private var dynResolution:Boolean; + + private function setImgSrc():void { + if(reloadTimer && reloadTimer.hasEventListener(TimerEvent.TIMER)){ + reloadTimer.removeEventListener(TimerEvent.TIMER, reloadImg); + reloadTimer=null; + } + if(setXMLDone && slideshowXML && (isEnabled||forcedByUsr)){ + isEnabled=false; + forcedByUsr=false; + CursorManager.removeBusyCursor(); + CursorManager.setBusyCursor(); + timeoutTimer.start(); + isIOError=true; + + urlIdx=0; + if(slideshowXML.Img[idx].URL.length()>1){ + var sizes:ArrayCollection = new ArrayCollection(); + for(var i:Number=0; i<slideshowXML.Img[idx].URL.length(); i++){ + var sizeStr:String=slideshowXML.Img[idx].URL[i].attribute("size"); + if(sizeStr.match(/^\s*[0-9]+x[0-9]+\s*$/)){ + var xsize:Number=Number(sizeStr.replace(/x[0-9]+/, "")); + var ysize:Number=Number(sizeStr.replace(/[0-9]+x/, "")); + sizes.addItem( + {size: xsize*ysize, index: i, x: xsize, y: ysize}); + } + } + if(sizes.length>0){ + dynResolution=true; + var sort:Sort = new Sort(); + sort.fields=[new SortField("size",true,true)]; + sizes.sort=sort;// ^--descending order + sizes.refresh(); + + urlIdx=sizes.getItemAt(0).index; + for(i=0; i<sizes.length; i++){ + if( + sizes.getItemAt(i).x >= this.width || + sizes.getItemAt(i).y >= this.height + ) urlIdx=sizes.getItemAt(i).index; + } + } + } + + curFile=slideshowXML.Img[idx].URL[urlIdx].toString(); + + var pattern:RegExp; + if(slideshowXML.Img[idx].URL[urlIdx].attribute('height').length() > 0){ + pattern = new RegExp( + slideshowXML.Img[idx].URL[urlIdx].attribute('height'), "g"); + if(curFile.search(pattern)>-1){ + dynResolution=true; + curFile=curFile.replace(pattern, this.height.toString()); + } + } + + if(slideshowXML.Img[idx].URL[urlIdx].attribute('width').length() > 0){ + pattern = new RegExp( + slideshowXML.Img[idx].URL[urlIdx].attribute('width'), "g"); + if(curFile.search(pattern)>-1){ + dynResolution=true; + curFile=curFile.replace(pattern, this.width.toString()); + } + } + + if(Img1.visible) { + src2=null; src2=curFile; + } else { + src1=null; src1=curFile; + } + } + if(slideshowXML.Img[idx].attribute('live')>0){ + reloadTimer=new Timer(slideshowXML.Img[idx].attribute('live')*1000,1); + reloadTimer.addEventListener(TimerEvent.TIMER, reloadImg); + reloadTimer.start(); + } + } + + private var isReload:Boolean; + private function reloadImg(e:TimerEvent):void { + isReload=true; setImgSrc(); + } + + private var isPlaying:Boolean=false; + + private function playPause():void { + if(isPlaying) pause(); else play(); + } + + private function play():void { + if(!isPlaying && slideshowXML.Img.length()>1) { + if(!playTimer){ + playTimer=new Timer(delay*1000, 0); + playTimer.addEventListener(TimerEvent.TIMER, nextSlide); + } + isPlaying=true; + playTimer.start(); + } + } + + private function pause():void { + if(isPlaying) { + isPlaying=false; + playTimer.stop(); + } + } + + private function nextSlide(e:Event=null):void { + if(!isEnabled && !forcedByUsr) return; + if(isPlaying) playTimer.stop(); + var evnt:MouseEvent = e as MouseEvent; + if(evnt && evnt.type=="mouseUp" && evnt.shiftKey) { + prevSlide(); + } else { + idx++; + if(idx==slideshowXML.Img.length()) idx=0; + isReload=false; + setImgSrc(); + } + } + + private function prevSlide(e:MouseEvent=null):void { + if(!isEnabled && !forcedByUsr) return; + if(isPlaying) playTimer.stop(); + idx--; + if(idx<0) idx=slideshowXML.Img.length()-1; + isReload=false; + setImgSrc(); + } + + private function seek(i:Number):void { + if(!isEnabled && !forcedByUsr) return; + if(isPlaying) playTimer.stop(); + if(i<0 || i>=slideshowXML.Img.length()) + idx=slideshowXML.Img.length()-1; + else + idx=Math.floor(i); + isReload=false; + setImgSrc(); + } + + private function onKeyDown(e:KeyboardEvent):void { + forcedByUsr=true; + switch(e.keyCode) { + case 32: //space bar + playPause(); + break; + case 36: //home + if(isPlaying) pause(); + seek(0); + break; + case 35: //end + if(isPlaying) pause(); + seek(-1); + break; + case 37: //<-- + prevSlide(); + break; + case 39: //--> + nextSlide(); + break; + case 82: //`r' + e.shiftKey ? rotate(-1) : rotate(); + break; + } + } + + private function slideNum():Number {return idx;} + + private function numSlides():Number {return slideshowXML.Img.length();} + + private function playing():Boolean {return isPlaying;} + + private function initApp():void { + this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); + ExternalInterface.addCallback("setXML", setXML); + ExternalInterface.addCallback("play", + function():void{forcedByUsr=true;play();}); + ExternalInterface.addCallback("pause", + function():void{forcedByUsr=true;pause();}); + ExternalInterface.addCallback("playPause", + function():void{forcedByUsr=true;playPause();}); + ExternalInterface.addCallback("seek", + function(i:Number):void{forcedByUsr=true;seek(i);}); + ExternalInterface.addCallback("slideNum", slideNum); + ExternalInterface.addCallback("numSlides", numSlides); + ExternalInterface.addCallback("playing", playing); + ExternalInterface.addCallback("rotate", rotate); + + var itemNextSlide:ContextMenuItem = + new ContextMenuItem("Next Slide, [\u2192]"); + this.contextMenu.customItems.push(itemNextSlide); + itemNextSlide.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{forcedByUsr=true;nextSlide();}); + + var itemPrevSlide:ContextMenuItem = + new ContextMenuItem("Previous Slide, [\u2190]"); + this.contextMenu.customItems.push(itemPrevSlide); + itemPrevSlide.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{forcedByUsr=true;prevSlide();}); + + var itemPlayPause:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemPlayPause); + itemPlayPause.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{forcedByUsr=true;playPause();}); + + var itemFirstSlide:ContextMenuItem = + new ContextMenuItem("First Slide, [Home]"); + this.contextMenu.customItems.push(itemFirstSlide); + itemFirstSlide.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{ + forcedByUsr=true;if(isPlaying) pause();seek(0);}); + + var itemLastSlide:ContextMenuItem = + new ContextMenuItem("Last Slide, [End]"); + this.contextMenu.customItems.push(itemLastSlide); + itemLastSlide.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{ + forcedByUsr=true;if(isPlaying) pause();seek(-1);}); + + var itemRotRight:ContextMenuItem = + new ContextMenuItem("Rotate Right, [r]"); + this.contextMenu.customItems.push(itemRotRight); + itemRotRight.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{forcedByUsr=true;rotate();}); + + var itemRotLeft:ContextMenuItem = + new ContextMenuItem("Rotate Left, [\u21e7]+[r]"); + this.contextMenu.customItems.push(itemRotLeft); + itemRotLeft.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{forcedByUsr=true;rotate(-1);}); + + this.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, + function(e:ContextMenuEvent):void{ + itemPlayPause.caption=(isPlaying ? "Pause" : "Play")+", [Space]"; + itemPlayPause.visible=itemNextSlide.visible=itemPrevSlide.visible= + itemFirstSlide.visible=itemLastSlide.visible=false; + if(slideshowXML.Img.length()>1){ + itemPlayPause.visible=itemNextSlide.visible=itemPrevSlide.visible= + itemFirstSlide.visible=itemLastSlide.visible=true; + } + }); + + timeoutTimer=new Timer(30000, 1); + timeoutTimer.addEventListener(TimerEvent.TIMER, onAnyError); + curFile=xmlfile; if(xmlfile) setXML(xmlfile); + CursorManager.hideCursor(); + } + + private var isIOError:Boolean; + private function onAnyError(e:Event):void { + if(e.type!=IOErrorEvent.IO_ERROR || setXMLDone==false){ + isIOError=false; + setXMLDone=true; + if(Img1.visible){ + src2=null; src2="/dev/null" + }else{ + src1=null; src1="/dev/null" + } + caption.text=e.type+': '+curFile; + if(e.type==TimerEvent.TIMER) + caption.text="timeout after 30 s: "+curFile; + CursorManager.removeBusyCursor(); + }else{ + if(isIOError) caption.text=e.type+': '+curFile; + onImgDone(e); + } + caption.visible=true; + if(reloadTimer && reloadTimer.hasEventListener(TimerEvent.TIMER)){ + reloadTimer.removeEventListener(TimerEvent.TIMER, reloadImg); + reloadTimer=null; isReload=false; + } + } + + private function onImgDone(e:Event):void { + timeoutTimer.reset(); + if(e.target==Img1){ + Img1.visible=true;Img2.visible=false; + } else { + Img2.visible=true;Img1.visible=false; + } + if(slideshowXML.Img.length()>1){ + slideNo.text=String(idx+1)+"/"+slideshowXML.Img.length().toString(); + slideNo.visible=slideNo.includeInLayout=true; + } else { + slideNo.visible=slideNo.includeInLayout=false; + } + var curRot:Number=0; + if (rotations.hasOwnProperty(slideshowXML.Img[idx].URL[urlIdx].toString())) + curRot=rotations[slideshowXML.Img[idx].URL[urlIdx].toString()]; + else + curRot=Number(slideshowXML.Img[idx].attribute('rot90')); + rotate(0); + if(e.type==FlexEvent.READY) { + rotate(curRot); + if(slideshowXML.Img[idx].caption.toString()!=""){ + caption.text=slideshowXML.Img[idx].caption.toString(); + caption.visible=true; + } else { + caption.text=""; + caption.visible=false; + } + if(!isReload) anim.play(); + if(slideshowXML.Img[idx].attribute('live')>0) + cache.removeCacheEntry(curFile); + } + CursorManager.removeBusyCursor(); + isEnabled=true; + if(isPlaying && !playTimer.running) playTimer.start(); + } + ]]> + </fx:Script> + + <fx:Declarations> + <s:Animate id="anim" target="{grpCaption}"> + <s:motionPaths> + <s:SimpleMotionPath property="bottom" + valueFrom="{-grpCaption.height}" valueTo="0"/> + </s:motionPaths> + </s:Animate> + <s:ContentCache id="cache"/> + </fx:Declarations> + + <s:Image id="Img1" source="{src1}" visible="false" + width="100%" height="100%" + horizontalCenter="0" verticalCenter="0" + contentLoader="{cache}" + ready="onImgDone(event)" + ioError="onAnyError(event)" + securityError="onAnyError(event)" + smooth="true" + /> + + <s:Image id="Img2" source="{src2}" visible="true" + width="100%" height="100%" + horizontalCenter="0" verticalCenter="0" + contentLoader="{cache}" + ready="onImgDone(event)" + ioError="onAnyError(event)" + securityError="onAnyError(event)" + smooth="true" + /> + + <s:Group id="grpCaption" width="100%" bottom="{-grpCaption.height}"> + <s:Label id="caption" left="0" bottom="0" visible="false" + paddingLeft="2" paddingBottom="2" paddingRight="2" paddingTop="4" + backgroundColor="0xdddddd" backgroundAlpha="0.7" + maxWidth="{grpCaption.width-slideNo.width}" + maxDisplayedLines="{-1}" lineBreak="toFit" + /> + <s:Label id="slideNo" right="0" bottom="0" visible="false" + paddingLeft="2" paddingBottom="2" paddingRight="2" paddingTop="4" + backgroundColor="0xdddddd" backgroundAlpha="0.7" + /> + </s:Group> + + <s:Button alpha="0" width="100%" height="100%" + mouseUp="forcedByUsr=true;nextSlide(event);" + mouseOver="anim.play();CursorManager.showCursor();" + mouseOut="if(anim.isPlaying) anim.reverse(); else anim.play(null,true); + CursorManager.hideCursor();" + /> +</s:Application> diff --git a/macros/latex/contrib/media9/players/SlideShow.swf b/macros/latex/contrib/media9/players/SlideShow.swf Binary files differnew file mode 100644 index 0000000000..acd00c7a03 --- /dev/null +++ b/macros/latex/contrib/media9/players/SlideShow.swf diff --git a/macros/latex/contrib/media9/players/StrobeMediaPlayback-license b/macros/latex/contrib/media9/players/StrobeMediaPlayback-license new file mode 100644 index 0000000000..4a3d2ec8c0 --- /dev/null +++ b/macros/latex/contrib/media9/players/StrobeMediaPlayback-license @@ -0,0 +1,5 @@ +Strobe Media Playback is covered under the BSD Licence. See file BSD-License + +OSMF and NetMocker are covered under version 1.1 of the MPL Licence. You may obtain a copy of the License at http://www.mozilla.org/MPL/ + +The font we used by the player, Playback Sans, is released under the SIL Open Font License - see file player/StrobeMediaPlayback/assets/font/PlaybackSansEULA.txt diff --git a/macros/latex/contrib/media9/players/StrobeMediaPlayback.swf b/macros/latex/contrib/media9/players/StrobeMediaPlayback.swf Binary files differnew file mode 100644 index 0000000000..58e4170588 --- /dev/null +++ b/macros/latex/contrib/media9/players/StrobeMediaPlayback.swf diff --git a/macros/latex/contrib/media9/players/VPlayer.mxml b/macros/latex/contrib/media9/players/VPlayer.mxml new file mode 100644 index 0000000000..347a1058eb --- /dev/null +++ b/macros/latex/contrib/media9/players/VPlayer.mxml @@ -0,0 +1,338 @@ +<?xml version="1.0"?> +<!-- --> +<!-- Apache Flex 4 source file of VPlayer.swf, --> +<!-- a FlashPlayer-10 compatible component for playing --> +<!-- FLV and MP4/H.264 video files and streams. --> +<!-- --> +<!-- version 20180118 --> +<!-- --> +<!-- --> +<!-- The free Apache Flex 4 SDK is required to compile --> +<!-- this file. Get it from --> +<!-- --> +<!-- http://flex.apache.org/download-binaries.html --> +<!-- --> +<!-- and run --> +<!-- --> +<!-- mxmlc -static-link-runtime-shared-libraries VPlayer.mxml --> +<!-- --> +<!-- on the command line. --> +<!-- --> +<!-- --> +<!-- Copyright (C) 2012-today Alexander Grahn --> +<!-- --> +<!-- This work may be distributed and/or modified under the --> +<!-- conditions of the LaTeX Project Public License. --> +<!-- --> +<!-- The latest version of this license is in --> +<!-- http://www.latex-project.org/lppl.txt --> +<!-- --> +<!-- This work has the LPPL maintenance status `maintained'. --> +<!-- --> +<!-- The current maintainer of this work is A. Grahn. --> +<!-- --> + +<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" + xmlns:s="library://ns.adobe.com/flex/spark" + xmlns:mx="library://ns.adobe.com/flex/mx" + preinitialize="initialise(this.parameters);" + applicationComplete="initApp();" + backgroundAlpha="0" +> + <fx:Script> + <![CDATA[ + [Bindable] private var scaleMode:String='letterbox'; + [Bindable] private var source:String; + [Bindable] private var autoPlay:Boolean=false; + [Bindable] private var autoRewind:Boolean=false; + [Bindable] private var loop:Boolean=false; + [Bindable] private var vol:Number=0.75; + private var vidComplete:Boolean=false; + private var deltaSeek:Number; + private var curTime:Number; + private var newPos:Number; + private var keyPressed:Boolean=false; + private var pauseAtPos:Number = -1; + private var toBePaused:Boolean = false; + + private function initialise(flashVars:Object):void { + source=flashVars.source; + if(flashVars.autoPlay=='true'){autoPlay=true} + if(flashVars.autoRewind=='true'){autoRewind=true} + if(flashVars.loop=='true'){loop=true} + if(flashVars.volume){vol=Number(flashVars.volume)} + if(flashVars.scaleMode){scaleMode=flashVars.scaleMode} + } + + private function onProgress(event:ProgressEvent):void { + if (event.bytesTotal) event.target.visible=true; + else event.target.visible=false; + } + + import org.osmf.events.MediaPlayerStateChangeEvent; + import org.osmf.media.MediaPlayerState; + import mx.controls.Alert; + private function onStateChange(event:MediaPlayerStateChangeEvent):void { + vidComplete=false; + switch(event.state) { + case MediaPlayerState.PLAYBACK_ERROR: // ('playbackError') + Alert.show('Unable to play \''+event.target.source+'\'','Error'); + break; + //case MediaPlayerState.READY: + // if(autoPlay) vidDisp.play(); + // break; + //MediaPlayerState.BUFFERING + //MediaPlayerState.LOADING + //MediaPlayerState.PAUSED + //MediaPlayerState.PLAYING + //MediaPlayerState.UNINITIALIZED + } + } + + private function onKeyDown(e:KeyboardEvent):void { + switch(e.keyCode) { + case 32: //space bar + playPause(); + break; + case 36: //home + vidDisp.pause(); + vidDisp.seek(0); + break; + case 35: //end + if(vidDisp.bytesTotal){ + vidDisp.pause(); + vidDisp.seek(vidDisp.duration-0.1); + } + break; + case 37: //<-- + fadeEffect.end(); + playProgress.alpha=0.5; + playProgress.visible=true; + if(!keyPressed){ + deltaSeek=Math.max(1,vidDisp.duration/1000); + curTime=vidDisp.currentTime; + } + keyPressed=true; + newPos=Math.max(0,curTime-deltaSeek); + playProgress.setProgress(newPos,vidDisp.duration); + playProgress.label=formatTime(newPos); + vidDisp.seek(newPos); + deltaSeek*=1.1; + break; + case 39: //--> + fadeEffect.end(); + playProgress.alpha=0.5; + playProgress.visible=true; + if(!keyPressed){ + deltaSeek=Math.max(1,vidDisp.duration/1000); + curTime=vidDisp.currentTime; + } + keyPressed=true; + newPos=Math.min(vidDisp.duration-0.1,curTime+deltaSeek); + playProgress.setProgress(newPos,vidDisp.duration); + playProgress.label=formatTime(newPos); + vidDisp.seek(newPos); + deltaSeek*=1.1; + break; + case 38: + vol=Math.min(1,vol+0.025); + volume(vol); + break; + case 40: + vol=Math.max(0,vol-0.025); + volume(vol); + break; + default: + if(e.charCode==109) mute(); //`m' + } + } + + private function onKeyUp(e:KeyboardEvent):void { + switch(e.keyCode) { + case 37: //<-- + case 39: //--> + deltaSeek=Math.max(1,vidDisp.duration/1000); + keyPressed=false; + fadeEffect.play(); + break; + } + } + + private function onCurrentTimeChange(e:Event):void { + if(vidDisp.playing&&pauseAtPos>=0&&vidDisp.currentTime<pauseAtPos) + toBePaused=true; + if( + vidDisp.playing&&pauseAtPos>=0&& + vidDisp.currentTime>=pauseAtPos&&toBePaused + ){ + pause(); + pauseAtPos=-1; + toBePaused=false; + } + } + + private function play(p:Number=-1):void { + if(p>=0) seek(p); + if(vidComplete){seek(0);}vidDisp.play(); + } + + private function pause(p:Number=-1):void { + if(p>=0){pauseAtPos=p;return;} + vidDisp.pause(); + } + + private function playPause():void { + if(vidDisp.playing) vidDisp.pause(); else vidDisp.play(); + } + + private function seek(p:Number):void { + vidDisp.seek(p); + } + + private function rewind():void { + vidDisp.seek(0); + } + + private function volume(v:Number):void { + vidDisp.muted=false; + vidDisp.volume = v; + } + + private function mute():void { + if(vidDisp.muted) { + vidDisp.muted=false; + if (vidDisp.volume==0) volume(0.75); + } + else { + vidDisp.muted=true; + } + } + + private function setSource(s:Object):void { + vidDisp.source = s; + } + + private function formatTime(s:Number):String { + var hrs:Number = Math.floor(s / 3600); + var min:Number = Math.floor(s / 60 % 60); + var sec:Number = Math.floor(s % 60); + + var fmtd:String=''; + + if (hrs>0) fmtd = String(hrs)+':'; + + if (hrs>0 && min <10) fmtd+='0'; + fmtd += String(min)+':'; + + if (sec<10) fmtd+='0'; + fmtd += String(sec); + + return fmtd; + } + + private function currentTime():Number { + return vidDisp.currentTime; + } + + private function playing():Boolean { + return vidDisp.playing; + } + + private function duration():Number { + return vidDisp.duration; + } + + private function muted():Boolean { + return vidDisp.muted; + } + + private function initApp():void { + this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); + this.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); + ExternalInterface.addCallback("play", play); + ExternalInterface.addCallback("pause", pause); + ExternalInterface.addCallback("playPause", playPause); + ExternalInterface.addCallback("seek", seek); + ExternalInterface.addCallback("rewind", rewind); + ExternalInterface.addCallback("volume", volume); + ExternalInterface.addCallback("mute", mute); + ExternalInterface.addCallback("setSource", setSource); + ExternalInterface.addCallback("currentTime", currentTime); + ExternalInterface.addCallback("duration", duration); + ExternalInterface.addCallback("playing", playing); + ExternalInterface.addCallback("muted", muted); + + var itemPlayPause:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemPlayPause); + itemPlayPause.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{playPause();}); + + var itemRewind:ContextMenuItem = new ContextMenuItem("Rewind, [Home]"); + this.contextMenu.customItems.push(itemRewind); + itemRewind.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{vidDisp.pause();vidDisp.seek(0);}); + + var itemGotoEnd:ContextMenuItem = new ContextMenuItem("Goto End, [End]"); + this.contextMenu.customItems.push(itemGotoEnd); + itemGotoEnd.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{vidDisp.pause(); + vidDisp.seek(vidDisp.duration-0.1);}); + + var itemMute:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemMute); + itemMute.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{mute();}); + + this.contextMenu.customItems.push( + new ContextMenuItem("via keyboard:", true, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Seek, [\u2190]/[\u2192]", false, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Volume, [\u2191]/[\u2193]", false, false, true)); + + this.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, + function(e:ContextMenuEvent):void{ + itemPlayPause.caption=(vidDisp.playing ? "Pause" : "Play")+", [Space]"; + itemMute.caption=(vidDisp.muted ? "Unmute" : "Mute")+", [m]";} + ); + } + ]]> + </fx:Script> + + <fx:Declarations> + <s:Fade id="fadeEffect" target="{playProgress}" alphaFrom="0.5" alphaTo="0" + duration="2000"/> + </fx:Declarations> + + <!-- autoPlay setting (autoPlay="{autoPlay}") is not reliable; + we handle this in MediaPlayerStateChange event --> + <s:VideoDisplay + id="vidDisp" + width="100%" height="100%" scaleMode="{scaleMode}" + source="{source}" volume="{vol}" + autoPlay="{autoPlay}" + autoRewind="{autoRewind}" loop="{loop}" + mediaPlayerStateChange="onStateChange(event);" + complete="vidComplete=true;" + durationChange="vidDisp.seek(0);" + currentTimeChange="onCurrentTimeChange(event);" + /> + + <mx:ProgressBar width="100%" mode="polled" source="vidDisp" + horizontalCenter="0" bottom="0" labelPlacement="center" + id="loadingProgress" alpha="0.5" + complete="loadingProgress.visible=false;" + progress="onProgress(event)" + /> + + <mx:ProgressBar width="100%" mode="manual" + horizontalCenter="0" bottom="0" labelPlacement="center" + id="playProgress" alpha="0.5" + visible="false" + /> + + <s:Button alpha="0" width="100%" height="100%" + mouseDown="vidDisp.pause();" + mouseUp="if(vidComplete) vidDisp.seek(0);vidDisp.play();" + /> +</s:Application> diff --git a/macros/latex/contrib/media9/players/VPlayer.swf b/macros/latex/contrib/media9/players/VPlayer.swf Binary files differnew file mode 100644 index 0000000000..835c290837 --- /dev/null +++ b/macros/latex/contrib/media9/players/VPlayer.swf diff --git a/macros/latex/contrib/media9/players/VPlayer9.mxml b/macros/latex/contrib/media9/players/VPlayer9.mxml new file mode 100644 index 0000000000..6741267f10 --- /dev/null +++ b/macros/latex/contrib/media9/players/VPlayer9.mxml @@ -0,0 +1,318 @@ +<?xml version="1.0"?> +<!-- --> +<!-- Adobe Flex 3 source file of VPlayer9.swf, --> +<!-- a FlashPlayer-9 compatible component for playing --> +<!-- FLV and MP4/H.264 video files and streams. --> +<!-- --> +<!-- version 20150729 --> +<!-- --> +<!-- Copyright (C) 2012-today Alexander Grahn --> +<!-- --> +<!-- This work may be distributed and/or modified under the --> +<!-- conditions of the LaTeX Project Public License. --> +<!-- --> +<!-- The latest version of this license is in --> +<!-- http://www.latex-project.org/lppl.txt --> +<!-- --> +<!-- This work has the LPPL maintenance status `maintained'. --> +<!-- --> +<!-- The current maintainer of this work is A. Grahn. --> +<!-- --> + +<mx:Application + xmlns:mx="http://www.adobe.com/2006/mxml" + preinitialize="initialise(this.parameters);" + applicationComplete="initApp();" + backgroundAlpha="0" + paddingTop="0" paddingBottom="0" + paddingLeft="0" paddingRight="0" + layout="absolute" clipContent="false" +> + <mx:Script> + <![CDATA[ + [Bindable] private var source:String; + [Bindable] private var autoPlay:Boolean=false; + [Bindable] private var loop:Boolean=false; + [Bindable] private var vol:Number=0.75; + [Bindable] private var keepAspect:Boolean=true; + private var vidComplete:Boolean=false; + private var deltaSeek:Number; + private var playheadTime:Number; + private var newPos:Number; + private var keyPressed:Boolean=false; + private var muted:Boolean=false; + private var lastVolume:Number; + private var pauseAtPos:Number = -1; + private var toBePaused:Boolean = false; + + import flash.external.*; + private function initialise(flashVars:Object):void { + source=flashVars.source; + if(flashVars.autoPlay=='true') autoPlay=true; + if(flashVars.loop=='true') loop=true; + if(flashVars.volume) vol=Number(flashVars.volume); + if(flashVars.scaleMode && flashVars.scaleMode!='letterbox') keepAspect=false; + } + + private function onProgress(event:ProgressEvent):void { + if (event.bytesTotal) event.target.visible=true; + else event.target.visible=false; + } + + import mx.events.VideoEvent; + //import flash.events.VideoEvent; + import mx.controls.Alert; + private function onStateChange(event:mx.events.VideoEvent):void { + vidComplete=false; + if(event.state=='connectionError') + Alert.show('Unable to play \''+event.target.source+'\'','Error'); + } + + private function onKeyDown(e:KeyboardEvent):void { + switch(e.keyCode) { + case 32: //space bar + playPause(); + break; + case 36: //home + vidDisp.pause(); + vidDisp.playheadTime=0; + break; + case 35: //end + if(vidDisp.bytesTotal){ + vidDisp.pause(); + vidDisp.playheadTime=vidDisp.totalTime-0.1; + } + break; + case 37: //<-- + fadeEffect.end(); + playProgress.alpha=0.5; + playProgress.visible=true; + if(!keyPressed){ + deltaSeek=Math.max(1,vidDisp.totalTime/1000); + playheadTime=vidDisp.playheadTime; + } + keyPressed=true; + newPos=Math.max(0,playheadTime-deltaSeek); + playProgress.setProgress(newPos,vidDisp.totalTime); + playProgress.label=formatTime(newPos); + vidDisp.playheadTime=newPos; + deltaSeek*=1.1; + break; + case 39: //--> + fadeEffect.end(); + playProgress.alpha=0.5; + playProgress.visible=true; + if(!keyPressed){ + deltaSeek=Math.max(1,vidDisp.totalTime/1000); + playheadTime=vidDisp.playheadTime; + } + keyPressed=true; + newPos=Math.min(vidDisp.totalTime-0.1,playheadTime+deltaSeek); + playProgress.setProgress(newPos,vidDisp.totalTime); + playProgress.label=formatTime(newPos); + vidDisp.playheadTime=newPos; + deltaSeek*=1.1; + break; + case 38: + vol=Math.min(1,vol+0.025); + volume(vol); + break; + case 40: + vol=Math.max(0,vol-0.025); + volume(vol); + break; + default: + if(e.charCode==109) mute(); //`m' + } + } + + private function onKeyUp(e:KeyboardEvent):void { + switch(e.keyCode) { + case 37: //<-- + case 39: //--> + deltaSeek=Math.max(1,vidDisp.totalTime/1000); + keyPressed=false; + fadeEffect.play(); + break; + } + } + + private function onPlayheadUpdate(e:Event):void { + if(vidDisp.playing&&pauseAtPos>=0&&vidDisp.playheadTime<pauseAtPos) + toBePaused=true; + if( + vidDisp.playing&&pauseAtPos>=0&& + vidDisp.playheadTime>=pauseAtPos&&toBePaused + ){ + pause(); + pauseAtPos=-1; + toBePaused=false; + } + } + + private function play(p:Number=-1):void { + if(p>=0) seek(p); + if(vidComplete){seek(0);}vidDisp.play(); + } + + private function pause(p:Number=-1):void { + if(p>=0){pauseAtPos=p;return;} + vidDisp.pause(); + } + + private function playPause():void { + if(vidDisp.playing) vidDisp.pause(); else vidDisp.play(); + } + + private function seek(p:Number):void { + vidDisp.playheadTime=p; + } + + private function rewind():void { + vidDisp.playheadTime=0; + } + + private function volume(v:Number):void { + muted=false; + vidDisp.volume = v; + } + + private function mute():void { + if(muted) { + if (lastVolume==0) volume(0.75); + else volume(lastVolume); + } + else { + muted=true;lastVolume=vidDisp.volume;vidDisp.volume=0; + } + } + + private function setSource(s:String):void { + vidDisp.pause();vidDisp.source = s; + vidDisp.play();vidDisp.pause(); + vidDisp.playheadTime=0; + } + + private function formatTime(s:Number):String { + var hrs:Number = Math.floor(s / 3600); + var min:Number = Math.floor(s / 60 % 60); + var sec:Number = Math.floor(s % 60); + + var fmtd:String=''; + + if (hrs>0) fmtd = String(hrs)+':'; + + if (hrs>0 && min <10) fmtd+='0'; + fmtd += String(min)+':'; + + if (sec<10) fmtd+='0'; + fmtd += String(sec); + + return fmtd; + } + + private function currentTime():Number { + return vidDisp.playheadTime; + } + + private function playing():Boolean { + return vidDisp.playing; + } + + private function duration():Number { + return vidDisp.totalTime; + } + + private function ismuted():Boolean { + return muted; + } + + private function initApp():void { + this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); + this.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); + ExternalInterface.addCallback("play", play); + ExternalInterface.addCallback("pause", pause); + ExternalInterface.addCallback("playPause", playPause); + ExternalInterface.addCallback("seek", seek); + ExternalInterface.addCallback("rewind", rewind); + ExternalInterface.addCallback("volume", volume); + ExternalInterface.addCallback("mute", mute); + ExternalInterface.addCallback("setSource", setSource); + ExternalInterface.addCallback("currentTime", currentTime); + ExternalInterface.addCallback("duration", duration); + ExternalInterface.addCallback("playing", playing); + ExternalInterface.addCallback("muted", ismuted); + + var itemPlayPause:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemPlayPause); + itemPlayPause.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{playPause();}); + + var itemRewind:ContextMenuItem = new ContextMenuItem("Rewind, [Home]"); + this.contextMenu.customItems.push(itemRewind); + itemRewind.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{vidDisp.pause();seek(0);}); + + var itemGotoEnd:ContextMenuItem = new ContextMenuItem("Goto End, [End]"); + this.contextMenu.customItems.push(itemGotoEnd); + itemGotoEnd.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{if(vidDisp.bytesTotal){ + vidDisp.pause(); + vidDisp.playheadTime=vidDisp.totalTime-0.1;}}); + + var itemMute:ContextMenuItem = new ContextMenuItem("N.N."); + this.contextMenu.customItems.push(itemMute); + itemMute.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, + function(e:ContextMenuEvent):void{mute();}); + + this.contextMenu.customItems.push( + new ContextMenuItem("via keyboard:", true, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Seek, [\u2190]/[\u2192]", false, false, true)); + this.contextMenu.customItems.push( + new ContextMenuItem("Volume, [\u2191]/[\u2193]", false, false, true)); + + this.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, + function(e:ContextMenuEvent):void{ + itemPlayPause.caption=(vidDisp.playing ? "Pause" : "Play")+", [Space]"; + itemMute.caption=(muted ? "Unmute" : "Mute")+", [m]";} + ); + } + ]]> + </mx:Script> + + <mx:Fade id="fadeEffect" target="{playProgress}" alphaFrom="0.5" alphaTo="0" duration="2000" + effectEnd="playProgress.label=''" + /> + + <mx:VideoDisplay + id="vidDisp" + width="100%" height="100%" maintainAspectRatio="{keepAspect}" + backgroundAlpha="0" borderThickness="0" + source="{source}" volume="{vol}" + autoPlay="{autoPlay}" autoRewind="{loop}" + stateChange="onStateChange(event);" + complete="vidComplete=true;" + rewind="vidDisp.play();" + playheadUpdate="onPlayheadUpdate(event);" + /> + + <mx:ProgressBar width="100%" mode="polled" source="vidDisp" + horizontalCenter="0" bottom="0" labelPlacement="center" + id="loadingProgress" alpha="0.5" + complete="loadingProgress.visible=false;" + progress="onProgress(event)" + /> + + <mx:ProgressBar width="100%" mode="manual" + horizontalCenter="0" bottom="0" labelPlacement="center" + id="playProgress" alpha="0.5" + visible="false" + /> + + <mx:Button alpha="0" width="100%" height="100%" cornerRadius="0" + paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0" + mouseDown="vidDisp.pause();" + mouseUp="if(vidComplete) vidDisp.playheadTime=0;vidDisp.play();" + /> +</mx:Application> diff --git a/macros/latex/contrib/media9/players/VPlayer9.swf b/macros/latex/contrib/media9/players/VPlayer9.swf Binary files differnew file mode 100644 index 0000000000..c99e5a23f4 --- /dev/null +++ b/macros/latex/contrib/media9/players/VPlayer9.swf |