<?xml version="1.0"?>
<!--                                                               -->
<!-- Adobe Flex 4 source file of APlayer.swf,                      -->
<!-- a FlashPlayer-10 compatible component for playing             -->
<!-- MP3 audio files and streams.                                  -->
<!--                                                               -->
<!-- version 20120425                                              -->
<!--                                                               -->
<!--                                                               -->
<!-- The free Adobe Flex 4 SDK is required to compile              -->
<!-- this file. Get it from                                        -->
<!--                                                               -->
<!--        http://www.adobe.com/products/flex/                    -->
<!--                                                               -->
<!-- and run                                                       -->
<!--                                                               -->
<!-- mxmlc -static-link-runtime-shared-libraries APlayer.mxml      -->
<!--                                                               -->
<!-- on the command line.                                          -->
<!--                                                               -->
<!--                                                               -->
<!-- Copyright (C) 2012 Alexander Grahn                            -->
<!--                                                               -->
<!-- This work may be distributed and/or modified under the        -->
<!-- conditions of the LaTeX Project Public License, either        -->
<!-- version 1.3 of this license or (at your option) any later     -->
<!-- version.                                                      -->
<!--                                                               -->
<!-- The latest version of this license is in                      -->
<!--   http://www.latex-project.org/lppl.txt                       -->
<!-- and version 1.3 or later is part of all distributions of      -->
<!-- LaTeX version 2005/12/01 or later.                            -->
<!--                                                               -->
<!-- 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(FlexGlobals.topLevelApplication.parameters);"
  applicationComplete="initSound();addEventListener(Event.ENTER_FRAME, onEnterFrame);"
  creationComplete="initCallBacks();"
  mouseDown="pause();"
  mouseUp="play();"
>

    <fx: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 balance:Number=0;

            private var snd:Sound;
            private var sndCh:SoundChannel;
            private var sndTr:SoundTransform;
            private var playResumePosition:Number = 0;
            private var playing:Boolean = false;
            private var muted:Boolean = false;
            private var lastVol:Number;

            import mx.core.FlexGlobals;
            private function initialise(flashVars:Object):void {
              source=flashVars.source;
              if(flashVars.autoPlay){autoPlay=(flashVars.autoPlay=='true')}
              if(flashVars.loop){loop=(flashVars.loop=='true')}
              if(flashVars.volume){vol=Number(flashVars.volume)}
              if(flashVars.balance){balance=Number(flashVars.balance)}
            }

            import mx.controls.Alert;
            private function initSound():void {
              snd = new Sound(new URLRequest(source));
              sndTr = new SoundTransform(vol, balance);

              snd.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
              snd.addEventListener(ProgressEvent.PROGRESS, progressHandler);
              snd.addEventListener(Event.COMPLETE, completeHandler);

              if(autoPlay) play();
            }

            private function setSource(src:String):void {
              pause();
              snd = new Sound(new URLRequest(src));
              if(autoPlay) play();
            }

            private function play():void {
              if (!playing) {
                try{sndCh = snd.play(playResumePosition, 0, sndTr);}
                catch(err:Error){Alert.show(err.message,'Error');}
                sndCh.addEventListener(Event.SOUND_COMPLETE, sndCompleteHandler);
                playing = true;
              }
            }

            private function pause():void {
              if (playing) {
                playResumePosition = sndCh.position;
                sndCh.stop();
                playing = false;
              }
            }

            private function playPause():void {
              if (playing) pause(); else play();
            }

            private function seek(p:Number):void {
              playResumePosition = p*1000;
              if (playing) {
                sndCh.stop();
                playing = false;
                play();
              }
            }

            private function rewind():void {
              seek(0);
            }

            private function volume(v:Number):void {
              sndTr.volume = v;
              if (playing) {
                pause();
                play();
              }
            }

            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 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("mute", mute);
              ExternalInterface.addCallback("setSource", setSource);
            }

            private function sndCompleteHandler(event:Event):void {
              playing = false;
              playResumePosition = 0;
              if(loop) play();
            }

            private function completeHandler(event:Event):void {
              playProgress.indeterminate=false;
            }

            import flash.events.ProgressEvent;
            private function progressHandler(event:ProgressEvent):void {
              playProgress.indeterminate=true;
              if(playing) {
                playProgress.setProgress(0.5,1);
              }
            }

            private function onEnterFrame(event:Event):void {
              if(playProgress.indeterminate==false && playing) {
                playProgress.setProgress(sndCh.position,snd.length);
              }
            }

            import flash.events.IOErrorEvent;
            private function errorHandler(errorEvent:IOErrorEvent):void {
               Alert.show(errorEvent.text + '\ncould not be loaded','Error');
            }
        ]]>
    </fx:Script>

    <mx:ProgressBar width="100%" mode="manual"
        horizontalCenter="0" verticalCenter="0" labelPlacement="center"
        label="" id="playProgress"
    />
</s:Application>
