4
import flash.events.Event;
5
import flash.events.IOErrorEvent;
6
import flash.events.ProgressEvent;
7
import flash.events.TimerEvent;
8
import flash.media.ID3Info;
9
import flash.media.Sound;
10
import flash.media.SoundChannel;
11
import flash.media.SoundLoaderContext;
12
import flash.media.SoundTransform;
13
import flash.net.URLRequest;
14
import flash.utils.Timer;
20
* @author DefaultUser (Tools -> Custom Arguments...)
22
public class AudioElement implements IMediaElement
25
private var _sound:Sound;
26
private var _soundTransform:SoundTransform;
27
private var _soundChannel:SoundChannel;
28
private var _soundLoaderContext:SoundLoaderContext;
30
private var _volume:Number = 1;
31
private var _preMuteVolume:Number = 0;
32
private var _isMuted:Boolean = false;
33
private var _isPaused:Boolean = true;
34
private var _isEnded:Boolean = false;
35
private var _isLoaded:Boolean = false;
36
private var _currentTime:Number = 0;
37
private var _duration:Number = 0;
38
private var _bytesLoaded:Number = 0;
39
private var _bytesTotal:Number = 0;
40
private var _bufferedTime:Number = 0;
41
private var _bufferingChanged:Boolean = false;
43
private var _currentUrl:String = "";
44
private var _autoplay:Boolean = true;
45
private var _preload:String = "";
47
private var _element:FlashMediaElement;
48
private var _timer:Timer;
49
private var _firedCanPlay:Boolean = false;
51
public function setSize(width:Number, height:Number):void {
55
public function duration():Number {
59
public function currentTime():Number {
63
public function currentProgress():Number {
64
return Math.round(_bytesLoaded/_bytesTotal*100);
67
public function AudioElement(element:FlashMediaElement, autoplay:Boolean, preload:String, timerRate:Number, startVolume:Number)
71
_volume = startVolume;
74
_timer = new Timer(timerRate);
75
_timer.addEventListener(TimerEvent.TIMER, timerEventHandler);
77
_soundTransform = new SoundTransform(_volume);
78
_soundLoaderContext = new SoundLoaderContext();
82
function progressHandler(e:ProgressEvent):void {
84
_bytesLoaded = e.bytesLoaded;
85
_bytesTotal = e.bytesTotal;
87
// this happens too much to send every time
88
//sendEvent(HtmlMediaEvent.PROGRESS);
90
// so now we just trigger a flag and send with the timer
91
_bufferingChanged = true;
94
function id3Handler(e:Event):void {
95
sendEvent(HtmlMediaEvent.LOADEDMETADATA);
98
var id3:ID3Info = _sound.id3;
105
songName:id3.songName,
109
} catch (err:Error) {}
114
function timerEventHandler(e:TimerEvent) {
115
_currentTime = _soundChannel.position/1000;
117
// calculate duration
118
var duration = Math.round(_sound.length * _sound.bytesTotal/_sound.bytesLoaded/100) / 10;
120
// check to see if the estimated duration changed
121
if (_duration != duration && !isNaN(duration)) {
123
_duration = duration;
124
sendEvent(HtmlMediaEvent.LOADEDMETADATA);
127
// check for progress
128
if (_bufferingChanged) {
130
sendEvent(HtmlMediaEvent.PROGRESS);
132
_bufferingChanged = false;
136
sendEvent(HtmlMediaEvent.TIMEUPDATE);
138
// sometimes the ended event doesn't fire, here's a fake one
139
if (_duration > 0 && _currentTime >= _duration-0.2) {
144
function soundCompleteHandler(e:Event) {
148
function handleEnded():void {
153
sendEvent(HtmlMediaEvent.ENDED);
160
public function setSrc(url:String):void {
166
public function load():void {
168
if (_currentUrl == "")
171
_sound = new Sound();
172
//sound.addEventListener(IOErrorEvent.IO_ERROR,errorHandler);
173
_sound.addEventListener(ProgressEvent.PROGRESS,progressHandler);
174
_sound.addEventListener(Event.ID3,id3Handler);
175
_sound.load(new URLRequest(_currentUrl));
178
sendEvent(HtmlMediaEvent.LOADSTART);
182
sendEvent(HtmlMediaEvent.LOADEDDATA);
183
sendEvent(HtmlMediaEvent.CANPLAY);
184
_firedCanPlay = true;
186
if (_playAfterLoading) {
187
_playAfterLoading = false;
192
private var _playAfterLoading:Boolean= false;
194
public function play():void {
197
_playAfterLoading = true;
204
_soundChannel = _sound.play(_currentTime*1000, 0, _soundTransform);
205
_soundChannel.removeEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
206
_soundChannel.addEventListener(Event.SOUND_COMPLETE, soundCompleteHandler);
213
public function pause():void {
216
if (_soundChannel != null) {
217
_currentTime = _soundChannel.position/1000;
218
_soundChannel.stop();
222
sendEvent(HtmlMediaEvent.PAUSE);
226
public function stop():void {
227
if (_timer != null) {
230
if (_soundChannel != null) {
231
_soundChannel.stop();
235
sendEvent(HtmlMediaEvent.STOP);
238
public function setCurrentTime(pos:Number):void {
239
sendEvent(HtmlMediaEvent.SEEKING);
242
_soundChannel.stop();
244
_soundChannel = _sound.play(_currentTime * 1000, 0, _soundTransform);
245
sendEvent(HtmlMediaEvent.SEEKED);
252
private function didStartPlaying():void {
254
sendEvent(HtmlMediaEvent.PLAY);
255
sendEvent(HtmlMediaEvent.PLAYING);
256
if (!_firedCanPlay) {
257
sendEvent(HtmlMediaEvent.LOADEDDATA);
258
sendEvent(HtmlMediaEvent.CANPLAY);
259
_firedCanPlay = true;
264
public function setVolume(volume:Number):void {
267
_soundTransform.volume = volume;
269
if (_soundChannel != null) {
270
_soundChannel.soundTransform = _soundTransform;
273
_isMuted = (_volume == 0);
275
sendEvent(HtmlMediaEvent.VOLUMECHANGE);
278
public function getVolume():Number {
287
public function setMuted(muted:Boolean):void {
289
// ignore if already set
290
if ( (muted && _isMuted) || (!muted && !_isMuted))
294
_preMuteVolume = _soundTransform.volume;
297
setVolume(_preMuteVolume);
303
public function unload():void {
308
private function sendEvent(eventName:String) {
310
// calculate this to mimic HTML5
311
_bufferedTime = _bytesLoaded / _bytesTotal * _duration;
314
var values:String = "duration:" + _duration +
315
",currentTime:" + _currentTime +
316
",muted:" + _isMuted +
317
",paused:" + _isPaused +
318
",ended:" + _isEnded +
319
",volume:" + _volume +
320
",src:\"" + _currentUrl + "\"" +
321
",bytesTotal:" + _bytesTotal +
322
",bufferedBytes:" + _bytesLoaded +
323
",bufferedTime:" + _bufferedTime +
326
_element.sendEvent(eventName, values);