summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/media9/players/APlayer.mxml
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/media9/players/APlayer.mxml')
-rw-r--r--macros/latex/contrib/media9/players/APlayer.mxml429
1 files changed, 429 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>