source: trunk/fl5/src/com/longtailvideo/jwplayer/media/YouTubeMediaProvider.as @ 819

Revision 819, 6.6 KB checked in by pablo, 3 years ago (diff)
  • Fixed bug in HTTP and YouTube where seeking could result in strange buffering behavior in the controlbar.
  • Try/catch Arthropod log.
  • MediaProviders send position w/ jwplayerMediaBuffer events
  • Fixed bug in PNG Skins where the buffer wouldn't show correctly with a seek/offset.
Line 
1/**
2 * Wrapper for load and playback of Youtube videos through their API.
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.RootReference;
11       
12        import flash.display.Loader;
13        import flash.events.*;
14        import flash.net.LocalConnection;
15        import flash.net.URLRequest;
16        import flash.system.Security;
17
18
19        public class YouTubeMediaProvider extends MediaProvider {
20                /** Loader for loading the YouTube proxy **/
21                private var _loader:Loader;
22                /** 'Unique' string to use for proxy connection. **/
23                private var _unique:String;
24                /** Connection towards the YT proxy. **/
25                private var _outgoing:LocalConnection;
26                /** connection from the YT proxy. **/
27                private var _inbound:LocalConnection;
28                /** Save that a load call has been sent. **/
29                private var _loading:Boolean;
30                /** Save the connection state. **/
31                private var _connected:Boolean;
32                /** Buffer percent **/
33                private var _bufferPercent:Number;
34                /** Time offset **/
35                private var _offset:Number = 0;
36
37
38                /** Setup YouTube connections and load proxy. **/
39                public function YouTubeMediaProvider() {
40                        super('youtube');
41                }
42
43
44                public override function initializeMediaProvider(cfg:PlayerConfig):void {
45                        super.initializeMediaProvider(cfg);
46                        Security.allowDomain('*');
47                        _outgoing = new LocalConnection();
48                        _outgoing.allowDomain('*');
49                        _outgoing.allowInsecureDomain('*');
50                        _outgoing.addEventListener(StatusEvent.STATUS, onLocalConnectionStatusChange);
51                        _inbound = new LocalConnection();
52                        _inbound.allowDomain('*');
53                        _inbound.allowInsecureDomain('*');
54                        _inbound.addEventListener(StatusEvent.STATUS, onLocalConnectionStatusChange);
55                        _inbound.client = this;
56                        _loader = new Loader();
57                        _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
58                }
59
60
61                /** Catch load errors. **/
62                private function errorHandler(evt:ErrorEvent):void {
63                        error(evt.text);
64                }
65
66
67                /** xtract the current ID from a youtube URL **/
68                private function getID(url:String):String {
69                        var arr:Array = url.split('?');
70                        var str:String = '';
71                        for (var i:String in arr) {
72                                if (arr[i].substr(0, 2) == 'v=') {
73                                        str = arr[i].substr(2);
74                                }
75                        }
76                        if (str == '') {
77                                str = url.substr(url.indexOf('/v/') + 3);
78                        }
79                        if (str.indexOf('&') > -1) {
80                                str = str.substr(0, str.indexOf('&'));
81                        }
82                        return str;
83                }
84
85
86                /** Get the location of yt.swf. **/
87                private function getLocation():String {
88                        var loc:String;
89                        var url:String = RootReference.stage.loaderInfo.url;
90                        if (url.indexOf('http://') == 0) {
91                                _unique = Math.random().toString().substr(2);
92                                loc = url.substr(0, url.indexOf('.swf'));
93                                loc = loc.substr(0, loc.lastIndexOf('/') + 1) + 'yt.swf?unique=' + _unique;
94                        } else {
95                                _unique = '1';
96                                loc = 'yt.swf';
97                        }
98                        return loc;
99                }
100
101
102                /** Load the YouTube movie. **/
103                override public function load(itm:PlaylistItem):void {
104                        _item = itm;
105                        _position = _offset = 0;
106                        _loading = true;
107                        setState(PlayerState.BUFFERING);
108                        sendBufferEvent(0);
109                        if (_connected) {
110                                completeLoad(itm);
111                        } else {
112                                _loader.load(new URLRequest(getLocation()));
113                                _inbound.connect('AS2_' + _unique);
114                        }
115                }
116
117
118                /** SWF loaded; add it to the tree **/
119                public function onSwfLoadComplete():void {
120                        _connected = true;
121                        if (_loading) {
122                                completeLoad(_item);
123                        }
124                }
125
126
127                /** Everything loaded - play the video **/
128                private function completeLoad(itm:PlaylistItem):void {
129                        if (_outgoing) {
130                                var gid:String = getID(_item.file);
131                                _outgoing.send('AS3_' + _unique, "cueVideoById", gid, _item.start);
132                                resize(config.width, config.width / 4 * 3);
133                                media = _loader;
134                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_LOADED);
135                                config.mute == true ? setVolume(0) : setVolume(config.volume);
136                                sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_BUFFER_FULL);
137                        }
138                }
139
140
141                /** Pause the YouTube movie. **/
142                override public function pause():void {
143                        _outgoing.send('AS3_' + _unique, "pauseVideo");
144                        super.pause();
145                }
146
147
148                /** Play or pause the video. **/
149                override public function play():void {
150                        _outgoing.send('AS3_' + _unique, "playVideo");
151//                      super.play();
152                }
153
154
155                /** error was thrown without this handler **/
156                public function onLocalConnectionStatusChange(evt:StatusEvent):void {
157                        // sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_META,{status:evt.code});
158                }
159
160
161                /** Catch youtube errors. **/
162                public function onError(erc:Number):void {
163                        var msg:String = 'Video not found or deleted: ' + getID(item['file']);
164                        if (erc == 101 || erc == 150) {
165                                msg = 'Embedding this video is disabled by its owner.';
166                        }
167                        error(msg);
168                }
169
170
171                /** Catch youtube state changes. **/
172                public function onStateChange(stt:Number):void {
173                        switch (Number(stt)) {
174                                case -1:
175                                        // setState(PlayerState.IDLE);
176                                        break;
177                                case 0:
178                                        if (state != PlayerState.BUFFERING && state != PlayerState.IDLE) {
179                                                complete();
180                                                _offset = 0;
181                                        }
182                                        break;
183                                case 1:
184                                        super.play();
185                                        break;
186                                case 2:
187//                                      super.pause();
188                                        break;
189                                case 3:
190                                        setState(PlayerState.BUFFERING);
191                                        break;
192                        }
193                }
194
195
196                /** Catch Youtube load changes **/
197                public function onLoadChange(ldd:Number, ttl:Number, off:Number):void {
198                        _bufferPercent = Math.round(ldd / ttl * 100);
199                        _offset = off / ttl * item.duration;
200                        sendBufferEvent(_bufferPercent, _offset);
201                }
202
203
204                /** Catch Youtube _position changes **/
205                public function onTimeChange(pos:Number, dur:Number):void {
206                        _position = pos;
207                        if (item.duration < 0) {
208                                item.duration = dur;
209                        }
210                        if (state != PlayerState.PLAYING){
211                                super.play();
212                        }
213                        sendMediaEvent(MediaEvent.JWPLAYER_MEDIA_TIME, {position: pos, duration: item.duration, offset: _offset});
214                        if (pos > item.duration) {
215                                complete();
216                        }
217                }
218
219
220                /** Resize the YT player. **/
221                public override function resize(wid:Number, hei:Number):void {
222                        _outgoing.send('AS3_' + _unique, "setSize", wid, hei);
223                }
224
225
226                /** Seek to _position. **/
227                override public function seek(pos:Number):void {
228                        super.seek(pos);
229                        _outgoing.send('AS3_' + _unique, "seekTo", pos);
230                        play();
231                }
232
233
234                /** Destroy the youtube video. **/
235                override public function stop():void {
236                        if (_connected) {
237                                _outgoing.send('AS3_' + _unique, "stopVideo");
238                        } else {
239                                _loading = false;
240                        }
241                        _position = _offset = 0;
242                        super.stop();
243                }
244
245
246                /** Set the volume level. **/
247                override public function setVolume(pct:Number):void {
248                        _outgoing.send('AS3_' + _unique, "setVolume", pct);
249                        super.setVolume(pct);
250                }
251        }
252}
Note: See TracBrowser for help on using the repository browser.