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: }