import com.adobe.gettext.GetText; import com.adobe.crypto.SHA1; import mx.events.ListEvent; import mx.rpc.events.ResultEvent; import mx.controls.Alert; // shortcuts private var alert:Function = mx.controls.Alert.show; private var _:Function = GetText.translate; public var aSongs:Array = new Array(); private var nSongIndex:Number = 0; public var sSong:Sound; public var scChannel:SoundChannel; private var nSongPosition:Number = 0; private var bPlaying:Boolean = false; private var username:String = "atom"; private var password:String = "mota"; private var nonce:String; // not known yet, shouldn't private var cnonce:String; // generated in the init private var counter:int = 0; private var qop:String; private var realm:String; // Elements that exits in the movie /* public var lTitle:Label; public var liSongs:List; public var bPlay:Button; public var bStop:Button; //public var bDownload:Button; public var bPrevious:Button; public var bNext:Button; */ private function formatInt(value:int, padding:int):String { var size:int = int(Math.log(value)/Math.log(10)); var ret:String = ""; for(var i:int = 1; i<(padding-size); i++) { ret += "0"; } return ret + value; } private function init(event:ResultEvent):void { // Define the event handlers bPlay.addEventListener(MouseEvent.CLICK, onPlayPause); bStop.addEventListener(MouseEvent.CLICK, onStop); //bDownload.addEventListener(MouseEvent.CLICK, onDownload); bPrevious.addEventListener(MouseEvent.CLICK, onPrevious); bNext.addEventListener(MouseEvent.CLICK, onNext); liSongs.addEventListener(ListEvent.ITEM_CLICK, onSongSelected); // (should) generate a unique cnonce cnonce = "cnonce"; // load the shit loaded(event); } // act when the RSS is loaded private function loaded(event:ResultEvent):void { if(typeof(event.result.rss) === "xml") { // empty the current songs if(aSongs.length == 0) { aSongs = new Array(); } // fill with the new ones for each(var item:XML in event.result..item) { var enclosures:XMLList = item..enclosure.(@type == 'audio/mpeg'); if(enclosures.length()) { aSongs.push({ // ComboBox data: aSongs.length, label: truncate(item.title, 50) + " - " + truncate(item.description, 30), // Meta data title: item.title, description: item.description, url: enclosures[0].@url, length: enclosures[0].@length }); } } liSongs.dataProvider = aSongs; liSongs.selectedIndex = nSongIndex; play(); } else { info(_("Result isn't well formed")); } } private function onPlayPause(event:MouseEvent):void { if(!bPlaying) play(); else pause(); } private function onStop(event:MouseEvent):void { stop(); } //private function onDownload(event:MouseEvent):void { // download(); //} private function onNext(event:MouseEvent):void { next(); } private function onPrevious(event:MouseEvent):void { previous(); } private function onSongSelected(event:ListEvent):void { stop(); nSongIndex = event.currentTarget.selectedItem.data; play(); } private function onSoundComplete(event:Event):void { next(); } private function getChallenge():void { if(aSongs[nSongIndex].url) { var url:String = aSongs[nSongIndex].url; var request:URLRequest = new URLRequest(url); request.method = URLRequestMethod.GET; // very specific var uri:String = url.substring("http://yoan.org:8080".length, url.length); var loader:URLLoader = new URLLoader(); loader.addEventListener(Event.COMPLETE, function(event:Event):void{ var data:XML = new XML(loader.data); loader.close(); if(data..challenge.@algorithm == "SHA") { realm = data..challenge.@realm; nonce = data..challenge.@nonce; qop = data..challenge.@qop; counter = 0; // got the data, no let's play it! play(); } else { info("Algorithm not supported."); } }); loader.load(request); } } public function play():void { if(!nonce) { getChallenge(); } else { if(!sSong || sSong.url != aSongs[nSongIndex].url) { // load the new song var url:String = aSongs[nSongIndex].url; var request:URLRequest = new URLRequest(url); request.method = URLRequestMethod.GET;; counter += 1; var nc:String = formatInt(counter, 8); var a1:String = username+":"+realm+":"+password; var a2:String = request.method+":"+url; var response:String = SHA1.hash(SHA1.hash(a1)+":"+nonce+":"+nc+":"+cnonce+":"+qop+":"+SHA1.hash(a2)); request.data = "user="+username+"&realm="+realm+"&nc="+nc+"&cnonce="+cnonce+"&nonce="+nonce+"&response="+response; sSong = new Sound(); sSong.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent):void { nonce = null; play(); }); sSong.addEventListener(Event.OPEN, function(event:Event):void { scChannel = sSong.play(nSongPosition); scChannel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete); bPlaying = true; bPlay.label = _("Pause"); }) sSong.load(request); return; } // nothing to load, continue scChannel = sSong.play(nSongPosition); scChannel.addEventListener(Event.SOUND_COMPLETE, onSoundComplete); bPlaying = true; bPlay.label = _("Pause"); } } public function pause():void { nSongPosition = scChannel.position; scChannel.stop(); bPlaying = false; bPlay.label = _("Play"); } public function stop():void { nSongPosition = 0; scChannel.stop(); bPlaying = false; bPlay.label = _("Play"); } //public function download():void { // navigateToURL(new URLRequest(aSongs[nSongIndex].url), "_blank"); //} public function next():void { stop(); nSongIndex = (nSongIndex + 1) % aSongs.length; liSongs.selectedIndex = nSongIndex; play(); } public function previous():void { stop(); nSongIndex -= 1; if(nSongIndex < 0) nSongIndex = aSongs.length - 1; liSongs.selectedIndex = nSongIndex; play(); } public function info(text:String):void { alert(text); } public function truncate(sValue:String, nMax:Number):String { return (sValue.length > nMax) ? sValue.substring(0, nMax-3) + "..." : sValue; }