root/trunk/fl5/src/com/longtailvideo/jwplayer/media/SoundMediaProvider.as

Revision 1246, 6.4 kB (checked in by pablo, 9 days ago)

Bug fixes:

  • Fixes loading "0" plugin when plugin flashvar is blank (1025)
  • Fixes blank screen on PLAY from JavaScript API (1001)
  • Fixes sound files being truncated if STOP is called before loading is complete (982)
  • Fixes item events not being forwarded to JS after playerReady (1029)
Line 
1/**
2 * Wrapper for playback of mp3 sounds.
3 **/
4package com.longtailvideo.jwplayer.media {
5        import com.jeroenwijering.events.*;
6        import com.longtailvideo.jwplayer.events.MediaEvent;
7        import com.longtailvideo.jwplayer.model.PlayerConfig;
8        import com.longtailvideo.jwplayer.model.PlaylistItem;
9        import com.longtailvideo.jwplayer.player.PlayerState;
10        import com.longtailvideo.jwplayer.utils.Logger;
11       
12        import flash.events.*;
13        import flash.media.*;
14        import flash.net.URLRequest;
15        import flash.utils.*;
16
17
18        public class SoundMediaProvider extends MediaProvider {
19                /** _sound object to be instantiated. **/
20                private var _sound:Sound;
21                /** Sound control object. **/
22                private var _transformer:SoundTransform;
23                /** Sound _channel object. **/
24                private var _channel:SoundChannel;
25                /** Sound _context object. **/
26                private var _context:SoundLoaderContext;
27                /** ID for the position interval. **/
28                protected var _positionInterval:Number;
29                /** Whether the buffer has filled **/
30                private var _bufferFull:Boolean;
31                /** Whether the enitre sound file has been buffered **/
32                private var _bufferingComplete:Boolean;
33                /** User-defined item duration **/
34                private var _userDuration:Number = -1;
35               
36                /** Constructor; sets up the connection and display. **/
37                public function SoundMediaProvider() {
38                        super('_sound');
39
40                }
41
42
43                public override function initializeMediaProvider(cfg:PlayerConfig):void {
44                        super.initializeMediaProvider(cfg);
45                        _transformer = new SoundTransform();
46                        _context = new SoundLoaderContext(config.bufferlength * 1000, true);
47                }
48
49
50                /** Sound completed; send event. **/
51                private function completeHandler(evt:Event):void {
52                        complete();
53                }
54
55
56                /** Catch errors. **/
57                private function errorHandler(evt:ErrorEvent):void {
58                        stop();
59                        error(evt.text);
60                }
61
62
63                /** Forward ID3 data from the _sound. **/
64                private function id3Handler(evt:Event):void {
65                        try {
66                                var id3:ID3Info = _sound.id3;
67                                var obj:Object = {type: 'id3', album: id3.album,
68                                                artist: id3.artist, comment: id3.comment,
69                                                genre: id3.genre, name: id3.songName, track: id3.track,
70                                                year: id3.year}
71                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata:obj});
72                        } catch (err:Error) {
73                        }
74                }
75
76
77                /** Load the _sound. **/
78                override public function load(itm:PlaylistItem):void {
79                        _position = 0;
80                        _bufferFull = false;
81                        _userDuration = itm.duration > 0 ? itm.duration : -1;
82                        if (!_item || _item.file != itm.file || !_bufferingComplete) {
83                                _bufferingComplete = false;
84                                _item = itm;
85                                _sound = new Sound();
86                                _sound.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
87                                _sound.addEventListener(Event.ID3, id3Handler);
88                                _sound.addEventListener(ProgressEvent.PROGRESS, positionHandler);
89                                _sound.load(new URLRequest(encodeURI(_item.file)), _context);
90                        }
91                        if (!_positionInterval) {
92                                _positionInterval = setInterval(positionHandler, 100);
93                        }
94
95                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_LOADED);
96                        setState(PlayerState.BUFFERING);
97                        sendBufferEvent(0);
98                        streamVolume(config.mute ? 0 : config.volume);
99                }
100
101
102                /** Pause the _sound. **/
103                override public function pause():void {
104                        if (_positionInterval){
105                                clearInterval(_positionInterval);
106                                _positionInterval = undefined;
107                        }
108                        if (_channel) {
109                                _channel.stop();
110                        }
111                        super.pause();
112                }
113
114
115                /** Play the _sound. **/
116                override public function play():void {
117                        if (position == 0 && _item.start > 0) {
118                                seek(item.start);
119                                return;
120                        }
121                        if (!_positionInterval) {
122                                _positionInterval = setInterval(positionHandler, 100);
123                        }
124                        if (_channel){
125                                _channel.stop();
126                                _channel = null;
127                        }
128                        _channel = _sound.play(_position * 1000, 0, _transformer);
129                        _channel.addEventListener(Event.SOUND_COMPLETE, completeHandler);
130                        super.play();
131                }
132
133
134                /** Interval for the _position progress **/
135                protected function positionHandler(progressEvent:ProgressEvent=null):void {
136                        var bufferPercent:Number = 0;
137                       
138                        if (_item.duration <= 0 || _userDuration < 0) {
139                                if (_sound.bytesTotal > 0 && _sound.bytesLoaded / _sound.bytesTotal > 0.1) {
140                                        _item.duration = _sound.length / 1000 / _sound.bytesLoaded * _sound.bytesTotal;
141                                } else if (_sound.length > 0) {
142                                        _item.duration = _sound.length / 1000;
143                                }
144                        }
145                       
146                        if (_channel && _sound) {
147                                _position = Math.round(_channel.position / 100) / 10;
148                                if (_sound.bytesTotal > 0) {
149                                        bufferPercent = Math.floor(_sound.bytesLoaded / _sound.bytesTotal * 100);
150                                }
151                        } else if (!_channel && progressEvent && progressEvent.bytesTotal > 0) {
152                                bufferPercent = Math.floor(progressEvent.bytesLoaded / progressEvent.bytesTotal * 100);
153                        }
154
155                       
156                        if (state == PlayerState.PLAYING && _sound.isBuffering == true) {
157                                // Buffer underrun condition
158                                _bufferFull = false;
159                                setState(PlayerState.BUFFERING);
160                                return
161                        } else if (state == PlayerState.BUFFERING && _sound.bytesLoaded > 0 && !_bufferFull) {
162                                _bufferFull = true;
163                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL);
164                        }
165                       
166                        if (!isNaN(bufferPercent) && !_bufferingComplete){
167                                if (bufferPercent == 100 && _bufferingComplete == false) {
168                                        _bufferingComplete = true;
169                                }
170                                sendBufferEvent(bufferPercent, 0, {loaded:_sound.bytesLoaded, total:_sound.bytesTotal});
171                        }
172                       
173                        if (state != PlayerState.PLAYING) {
174                                return;
175                        }
176                       
177                        if (_position < _item.duration) {
178                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: _position, duration: _item.duration});
179                        } else if (_item.duration > 0) {
180                                complete();
181                        }
182                }
183
184
185                /** Seek in the _sound. **/
186                override public function seek(pos:Number):void {
187                        if (_sound && _sound.bytesTotal > 0 && (pos < (_sound.bytesLoaded / _sound.bytesTotal) * item.duration) || item.start) {
188                                clearInterval(_positionInterval);
189                                _positionInterval = undefined;
190                                if (_channel) {
191                                        _channel.stop();
192                                }
193                                _position = pos;
194                                play();
195                        }
196                }
197
198
199                /** Destroy the _sound. **/
200                override public function stop():void {
201                        clearInterval(_positionInterval);
202                        _positionInterval = undefined;
203                        super.stop();
204                        if (_channel) {
205                                _channel.stop();
206                                _channel = null;
207                        }
208                        try {
209                                _sound.close();
210                        } catch (err:Error) {
211                        }
212                }
213
214
215                /** Set the volume level. **/
216                override public function setVolume(vol:Number):void {
217                        streamVolume(vol);
218                        super.setVolume(vol);
219                }
220               
221
222                /** Set the stream's volume, without sending a volume event **/
223                protected function streamVolume(level:Number):void {
224                        _transformer.volume = level / 100;
225                        if (_channel) {
226                                _channel.soundTransform = _transformer;
227                        }
228                }
229        }
230}
Note: See TracBrowser for help on using the browser.