source: trunk/fl5/src/com/longtailvideo/jwplayer/media/VideoMediaProvider.as @ 818

Revision 818, 7.5 KB checked in by pablo, 3 years ago (diff)
Line 
1package com.longtailvideo.jwplayer.media {
2        import com.longtailvideo.jwplayer.events.MediaEvent;
3        import com.longtailvideo.jwplayer.model.PlayerConfig;
4        import com.longtailvideo.jwplayer.model.PlaylistItem;
5        import com.longtailvideo.jwplayer.player.PlayerState;
6        import com.longtailvideo.jwplayer.utils.NetClient;
7       
8        import flash.events.*;
9        import flash.media.*;
10        import flash.net.*;
11        import flash.utils.*;
12
13
14        /**
15         * Wrapper for playback of progressively downloaded _video.
16         **/
17        public class VideoMediaProvider extends MediaProvider {
18                /** Video object to be instantiated. **/
19                protected var _video:Video;
20                /** NetConnection object for setup of the video _stream. **/
21                protected var _connection:NetConnection;
22                /** NetStream instance that handles the stream IO. **/
23                protected var _stream:NetStream;
24                /** Sound control object. **/
25                protected var _transformer:SoundTransform;
26                /** ID for the position interval. **/
27                protected var _positionInterval:Number;
28                /** Whether the buffer has filled **/
29                private var _bufferFull:Boolean;
30                /** Whether the enitre video has been buffered **/
31                private var _bufferingComplete:Boolean;
32                /** Whether we have checked the bandwidth. **/
33                private var _bandwidthChecked:Boolean;
34                /** Whether to switch on bandwidth detection **/
35                private var _bandwidthSwitch:Boolean = true;
36                /** Bandwidth check interval **/
37                private var _bandwidthTimeout:Number = 2000;
38
39
40                /** Constructor; sets up the connection and display. **/
41                public function VideoMediaProvider() {
42                        super('video');
43                }
44
45
46                public override function initializeMediaProvider(cfg:PlayerConfig):void {
47                        super.initializeMediaProvider(cfg);
48                        _connection = new NetConnection();
49                        _connection.connect(null);
50                        _stream = new NetStream(_connection);
51                        _stream.addEventListener(NetStatusEvent.NET_STATUS, statusHandler);
52                        _stream.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
53                        _stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, errorHandler);
54                        _stream.bufferTime = config.bufferlength;
55                        _stream.client = new NetClient(this);
56                        _transformer = new SoundTransform();
57                        _video = new Video(320, 240);
58                        _video.smoothing = config.smoothing;
59                        _video.attachNetStream(_stream);
60                }
61
62
63                /** Catch security errors. **/
64                protected function errorHandler(evt:ErrorEvent):void {
65                        error(evt.text);
66                }
67
68
69                /** Load content. **/
70                override public function load(itm:PlaylistItem):void {
71                        var replay:Boolean;
72                        _bufferFull = false;
73                        _bufferingComplete = false;
74                        if (itm.levels.length > 0) {
75                                itm.setLevel(itm.getLevel(config.bandwidth, config.width));
76                                _bandwidthChecked = false;
77                        } else {
78                                _bandwidthChecked = true;
79                        }
80                       
81                        if (!item
82                                        || item.file != itm.file
83                                        || _stream.bytesLoaded == 0
84                                        || (_stream.bytesLoaded < _stream.bytesTotal > 0))
85                        {
86                                media = _video;
87                                _stream.checkPolicyFile = true;
88                                _stream.play(itm.file);
89                                _stream.pause();
90                        } else {
91                                replay = true;
92                        }
93
94                        setState(PlayerState.BUFFERING);
95                        sendBufferEvent(0);
96                        config.mute == true ? setVolume(0) : setVolume(config.volume);
97                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_LOADED);
98
99                        if (replay){
100                                if (itm.duration <= 0) { itm.duration = item.duration; }
101                                seekStream(itm.start, false);
102                        }
103
104                        _item = itm;
105                       
106                        clearInterval(_positionInterval);
107                        _positionInterval = setInterval(positionHandler, 200);
108
109                }
110
111                /** Get metadata information from netstream class. **/
112                public function onClientData(dat:Object):void {
113                        if (dat.width) {
114                                _video.width = dat.width;
115                                _video.height = dat.height;
116                                resize(_width, _height);
117                        }
118                        if (dat.duration && item.duration < 0) {
119                                item.duration = dat.duration;
120                        }
121                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: dat});
122                }
123
124
125                /** Pause playback. **/
126                override public function pause():void {
127                        _stream.pause();
128                        super.pause();
129                }
130
131
132                /** Resume playing. **/
133                override public function play():void {
134                        if (!_positionInterval) {
135                                _positionInterval = setInterval(positionHandler, 100);
136                        }
137                        _stream.resume();
138                        super.play();
139                }
140
141
142                /** Interval for the position progress **/
143                protected function positionHandler():void {
144                        if (!_bandwidthChecked && _stream.bytesLoaded > 0) {
145                                _bandwidthChecked = true;
146                                setTimeout(checkBandwidth, _bandwidthTimeout, _stream.bytesLoaded);
147                        }
148                       
149                        var _streamTime:Number = Math.min(_stream.time, item.duration);
150                        _position = Math.round(_streamTime * 10) / 10;
151                        var bufferPercent:Number = _stream.bytesLoaded / _stream.bytesTotal * 100;
152                        var bufferTime:Number = _stream.bufferTime < (item.duration - _streamTime) ? _stream.bufferTime : Math.floor(Math.abs(item.duration - _streamTime));
153                        var bufferFill:Number = bufferTime == 0 ? 100 : Math.floor(_stream.bufferLength / bufferTime * 100);
154
155                       
156                        if (bufferFill < 25 && state == PlayerState.PLAYING) {
157                                _bufferFull = false;
158                                _stream.pause();
159                                setState(PlayerState.BUFFERING);
160                        } else if (bufferFill > 95 && state == PlayerState.BUFFERING && _bufferFull == false && bufferTime > 0) {
161                                _bufferFull = true;
162                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL);
163                        }
164
165                        if (!_bufferingComplete) {
166                                if (bufferPercent == 100 && _bufferingComplete == false) {
167                                        _bufferingComplete = true;
168                                }
169                                sendBufferEvent(bufferPercent);
170                        }
171
172                        if (position < item.duration) {
173                                if (state == PlayerState.PLAYING && position >= 0) {
174                                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: position, duration: item.duration});
175                                }
176                        } else if (item.duration > 0) {
177                                complete();
178                        }
179                }
180
181                private function checkBandwidth(lastLoaded:Number):void {
182                        var currentLoaded:Number = _stream.bytesLoaded;
183                        var bandwidth:Number = Math.ceil((currentLoaded - lastLoaded) / 1024) * 8 / (_bandwidthTimeout / 1000);
184                        if (currentLoaded < _stream.bytesTotal) {
185                                if (bandwidth > 0) {
186                                        config.bandwidth = bandwidth;
187                                        var obj:Object = {bandwidth:bandwidth};
188                                        if (item.duration > 0) {
189                                                obj.bitrate = Math.ceil(_stream.bytesTotal / 1024 * 8 / item.duration);
190                                        }
191                                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: obj});
192                                }
193                                if (_bandwidthSwitch) {
194                                        _bandwidthSwitch = false;
195                                        if (item.currentLevel != item.getLevel(config.bandwidth, config.width)) {
196                                                load(item);
197                                                return;
198                                        }
199                                }
200                        }
201                        setTimeout(checkBandwidth, _bandwidthTimeout, currentLoaded);
202                }
203
204                /** Seek to a new position. **/
205                override public function seek(pos:Number):void {
206                        seekStream(pos);
207                }
208               
209                private function seekStream(pos:Number, ply:Boolean=true):void {
210                        var bufferLength:Number = _stream.bytesLoaded / _stream.bytesTotal * item.duration;
211                        if (pos <= bufferLength) {
212                                super.seek(pos);
213                                clearInterval(_positionInterval);
214                                _positionInterval = undefined;
215                                _stream.seek(position);
216                                if (ply){
217                                        play();
218                                }
219                        }
220                }
221
222
223                /** Receive NetStream status updates. **/
224                protected function statusHandler(evt:NetStatusEvent):void {
225                        switch (evt.info.code) {
226                                case "NetStream.Play.Stop":
227                                        complete();
228                                        break;
229                                case "NetStream.Play.StreamNotFound":
230                                        error('Video not found or access denied: ' + item.file);
231                                        break;
232                        }
233                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META, {metadata: {status: evt.info.code}});
234                }
235
236
237                /** Destroy the video. **/
238                override public function stop():void {
239                        if (_stream.bytesLoaded < _stream.bytesTotal) {
240                                _stream.close();
241                        } else {
242                                _stream.pause();
243                                _stream.seek(0);
244                        }
245                        clearInterval(_positionInterval);
246                        _positionInterval = undefined;
247                        super.stop();
248                }
249
250
251                /** Set the volume level. **/
252                override public function setVolume(vol:Number):void {
253                        _transformer.volume = vol / 100;
254                        _stream.soundTransform = _transformer;
255                        super.setVolume(vol);
256                }
257        }
258}
Note: See TracBrowser for help on using the repository browser.