summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/media9/players/VPlayer.mxml
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/media9/players/VPlayer.mxml')
-rw-r--r--macros/latex/contrib/media9/players/VPlayer.mxml338
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>