diff options
Diffstat (limited to 'macros/latex/contrib/media9/players/VPlayer.mxml')
-rw-r--r-- | macros/latex/contrib/media9/players/VPlayer.mxml | 338 |
1 files changed, 338 insertions, 0 deletions
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> |