gyorgy@0:  gyorgy@0: package htmlelements gyorgy@0: { gyorgy@0: import flash.events.Event; gyorgy@0: import flash.events.IOErrorEvent; gyorgy@0: import flash.events.ProgressEvent; gyorgy@0: import flash.events.TimerEvent; gyorgy@0: import flash.media.ID3Info; gyorgy@0: import flash.media.Sound; gyorgy@0: import flash.media.SoundChannel; gyorgy@0: import flash.media.SoundLoaderContext; gyorgy@0: import flash.media.SoundTransform; gyorgy@0: import flash.net.URLRequest; gyorgy@0: import flash.utils.Timer; gyorgy@0: gyorgy@0: gyorgy@0: gyorgy@0: /** gyorgy@0: * ... gyorgy@0: * @author DefaultUser (Tools -> Custom Arguments...) gyorgy@0: */ gyorgy@0: public class AudioElement implements IMediaElement gyorgy@0: { gyorgy@0: gyorgy@0: private var _sound:Sound; gyorgy@0: private var _soundTransform:SoundTransform; gyorgy@0: private var _soundChannel:SoundChannel; gyorgy@0: private var _soundLoaderContext:SoundLoaderContext; gyorgy@0: gyorgy@0: private var _volume:Number = 1; gyorgy@0: private var _preMuteVolume:Number = 0; gyorgy@0: private var _isMuted:Boolean = false; gyorgy@0: private var _isPaused:Boolean = true; gyorgy@0: private var _isEnded:Boolean = false; gyorgy@0: private var _isLoaded:Boolean = false; gyorgy@0: private var _currentTime:Number = 0; gyorgy@0: private var _duration:Number = 0; gyorgy@0: private var _bytesLoaded:Number = 0; gyorgy@0: private var _bytesTotal:Number = 0; gyorgy@0: private var _bufferedTime:Number = 0; gyorgy@0: gyorgy@0: private var _currentUrl:String = ""; gyorgy@0: private var _autoplay:Boolean = true; gyorgy@0: private var _preload:String = ""; gyorgy@0: gyorgy@0: private var _element:FlashMediaElement; gyorgy@0: private var _timer:Timer; gyorgy@0: private var _firedCanPlay:Boolean = false; gyorgy@0: gyorgy@0: public function duration():Number { gyorgy@0: return _duration; gyorgy@0: } gyorgy@0: gyorgy@0: public function currentTime():Number { gyorgy@0: return _currentTime; gyorgy@0: } gyorgy@0: gyorgy@0: public function AudioElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number) gyorgy@0: { gyorgy@0: _element = element; gyorgy@0: _autoplay = autoplay; gyorgy@0: _volume = startVolume; gyorgy@0: _preload = preload; gyorgy@0: gyorgy@0: _timer = new Timer(timerRate); gyorgy@0: _timer.addEventListener(TimerEvent.TIMER, timerEventHandler); gyorgy@0: gyorgy@0: _soundTransform = new SoundTransform(_volume); gyorgy@0: _soundLoaderContext = new SoundLoaderContext(); gyorgy@0: } gyorgy@0: gyorgy@0: // events gyorgy@0: function progressHandler(e:ProgressEvent):void { gyorgy@0: gyorgy@0: _bytesLoaded = e.bytesLoaded; gyorgy@0: _bytesTotal = e.bytesTotal; gyorgy@0: gyorgy@0: sendEvent(HtmlMediaEvent.PROGRESS); gyorgy@0: } gyorgy@0: gyorgy@0: function id3Handler(e:Event):void { gyorgy@0: sendEvent(HtmlMediaEvent.LOADEDMETADATA); gyorgy@0: gyorgy@0: try { gyorgy@0: var id3:ID3Info = _sound.id3; gyorgy@0: var obj = { gyorgy@0: type:'id3', gyorgy@0: album:id3.album, gyorgy@0: artist:id3.artist, gyorgy@0: comment:id3.comment, gyorgy@0: genre:id3.genre, gyorgy@0: songName:id3.songName, gyorgy@0: track:id3.track, gyorgy@0: year:id3.year gyorgy@0: } gyorgy@0: } catch (err:Error) {} gyorgy@0: gyorgy@0: gyorgy@0: } gyorgy@0: gyorgy@0: function timerEventHandler(e:TimerEvent) { gyorgy@0: _currentTime = _soundChannel.position/1000; gyorgy@0: gyorgy@0: // calculate duration gyorgy@0: var duration = Math.round(_sound.length * _sound.bytesTotal/_sound.bytesLoaded/100) / 10; gyorgy@0: gyorgy@0: // check to see if the estimated duration changed gyorgy@0: if (_duration != duration && !isNaN(duration)) { gyorgy@0: gyorgy@0: _duration = duration; gyorgy@0: sendEvent(HtmlMediaEvent.LOADEDMETADATA); gyorgy@0: } gyorgy@0: gyorgy@0: // send timeupdate gyorgy@0: sendEvent(HtmlMediaEvent.TIMEUPDATE); gyorgy@0: gyorgy@0: // sometimes the ended event doesn't fire, here's a fake one gyorgy@0: if (_duration > 0 && _currentTime >= _duration-0.2) { gyorgy@0: handleEnded(); gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: function soundCompleteHandler(e:Event) { gyorgy@0: handleEnded(); gyorgy@0: } gyorgy@0: gyorgy@0: function handleEnded():void { gyorgy@0: _timer.stop(); gyorgy@0: _currentTime = 0; gyorgy@0: _isEnded = true; gyorgy@0: gyorgy@0: sendEvent(HtmlMediaEvent.ENDED); gyorgy@0: } gyorgy@0: gyorgy@0: //events gyorgy@0: gyorgy@0: gyorgy@0: // METHODS gyorgy@0: public function setSrc(url:String):void { gyorgy@0: _currentUrl = url; gyorgy@0: _isLoaded = false; gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: public function load():void { gyorgy@0: gyorgy@0: if (_currentUrl == "") gyorgy@0: return; gyorgy@0: gyorgy@0: _sound = new Sound(); gyorgy@0: //sound.addEventListener(IOErrorEvent.IO_ERROR,errorHandler); gyorgy@0: _sound.addEventListener(ProgressEvent.PROGRESS,progressHandler); gyorgy@0: _sound.addEventListener(Event.ID3,id3Handler); gyorgy@0: _sound.load(new URLRequest(_currentUrl)); gyorgy@0: _currentTime = 0; gyorgy@0: gyorgy@0: sendEvent(HtmlMediaEvent.LOADSTART); gyorgy@0: gyorgy@0: _isLoaded = true; gyorgy@0: gyorgy@0: sendEvent(HtmlMediaEvent.LOADEDDATA); gyorgy@0: sendEvent(HtmlMediaEvent.CANPLAY); gyorgy@0: _firedCanPlay = true; gyorgy@0: gyorgy@0: if (_playAfterLoading) { gyorgy@0: _playAfterLoading = false; gyorgy@0: play(); gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: private var _playAfterLoading:Boolean= false; gyorgy@0: gyorgy@0: public function play():void { gyorgy@0: gyorgy@0: if (!_isLoaded) { gyorgy@0: _playAfterLoading = true; gyorgy@0: load(); gyorgy@0: return; gyorgy@0: } gyorgy@0: gyorgy@0: _timer.stop(); gyorgy@0: gyorgy@0: _soundChannel = _sound.play(_currentTime*1000, 0, _soundTransform); gyorgy@0: _soundChannel.removeEventListener(Event.SOUND_COMPLETE, soundCompleteHandler); gyorgy@0: _soundChannel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler); gyorgy@0: gyorgy@0: _timer.start(); gyorgy@0: gyorgy@0: didStartPlaying(); gyorgy@0: } gyorgy@0: gyorgy@0: public function pause():void { gyorgy@0: gyorgy@0: _timer.stop(); gyorgy@0: if (_soundChannel != null) { gyorgy@0: _currentTime = _soundChannel.position/1000; gyorgy@0: _soundChannel.stop(); gyorgy@0: } gyorgy@0: gyorgy@0: _isPaused = true; gyorgy@0: sendEvent(HtmlMediaEvent.PAUSE); gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: public function stop():void { gyorgy@0: if (_timer != null) { gyorgy@0: _timer.stop(); gyorgy@0: } gyorgy@0: if (_soundChannel != null) { gyorgy@0: _soundChannel.stop(); gyorgy@0: _sound.close(); gyorgy@0: } gyorgy@0: unload(); gyorgy@0: sendEvent(HtmlMediaEvent.STOP); gyorgy@0: } gyorgy@0: gyorgy@0: public function setCurrentTime(pos:Number):void { gyorgy@0: sendEvent(HtmlMediaEvent.SEEKING); gyorgy@0: _timer.stop(); gyorgy@0: _currentTime = pos; gyorgy@0: _soundChannel.stop(); gyorgy@0: _sound.length gyorgy@0: _soundChannel = _sound.play(_currentTime * 1000, 0, _soundTransform); gyorgy@0: sendEvent(HtmlMediaEvent.SEEKED); gyorgy@0: gyorgy@0: _timer.start(); gyorgy@0: gyorgy@0: didStartPlaying(); gyorgy@0: } gyorgy@0: gyorgy@0: private function didStartPlaying():void { gyorgy@0: _isPaused = false; gyorgy@0: sendEvent(HtmlMediaEvent.PLAY); gyorgy@0: sendEvent(HtmlMediaEvent.PLAYING); gyorgy@0: if (!_firedCanPlay) { gyorgy@0: sendEvent(HtmlMediaEvent.LOADEDDATA); gyorgy@0: sendEvent(HtmlMediaEvent.CANPLAY); gyorgy@0: _firedCanPlay = true; gyorgy@0: } gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: public function setVolume(volume:Number):void { gyorgy@0: gyorgy@0: _volume = volume; gyorgy@0: _soundTransform.volume = volume; gyorgy@0: gyorgy@0: if (_soundChannel != null) { gyorgy@0: _soundChannel.soundTransform = _soundTransform; gyorgy@0: } gyorgy@0: gyorgy@0: sendEvent(HtmlMediaEvent.VOLUMECHANGE); gyorgy@0: } gyorgy@0: gyorgy@0: gyorgy@0: public function setMuted(muted:Boolean):void { gyorgy@0: gyorgy@0: // ignore if already set gyorgy@0: if ( (muted && _isMuted) || (!muted && !_isMuted)) gyorgy@0: return; gyorgy@0: gyorgy@0: if (muted) { gyorgy@0: _preMuteVolume = _soundTransform.volume; gyorgy@0: setVolume(0); gyorgy@0: } else { gyorgy@0: setVolume(_preMuteVolume); gyorgy@0: } gyorgy@0: gyorgy@0: _isMuted = muted; gyorgy@0: } gyorgy@0: gyorgy@0: public function unload():void { gyorgy@0: _sound = null; gyorgy@0: _isLoaded = false; gyorgy@0: } gyorgy@0: gyorgy@0: private function sendEvent(eventName:String) { gyorgy@0: gyorgy@0: // calculate this to mimic HTML5 gyorgy@0: _bufferedTime = _bytesLoaded / _bytesTotal * _duration; gyorgy@0: gyorgy@0: // build JSON gyorgy@0: var values:String = "duration:" + _duration + gyorgy@0: ",currentTime:" + _currentTime + gyorgy@0: ",muted:" + _isMuted + gyorgy@0: ",paused:" + _isPaused + gyorgy@0: ",ended:" + _isEnded + gyorgy@0: ",volume:" + _volume + gyorgy@0: ",src:\"" + _currentUrl + "\"" + gyorgy@0: ",bytesTotal:" + _bytesTotal + gyorgy@0: ",bufferedBytes:" + _bytesLoaded + gyorgy@0: ",bufferedTime:" + _bufferedTime + gyorgy@0: ""; gyorgy@0: gyorgy@0: _element.sendEvent(eventName, values); gyorgy@0: } gyorgy@0: gyorgy@0: } gyorgy@0: gyorgy@0: }