source: trunk/as3/com/jeroenwijering/models/YoutubeModel.as @ 166

Revision 166, 5.7 KB checked in by jeroen, 4 years ago (diff)

fixed bug in FP9.0.28 WIN that stalled the player

  • Property svn:executable set to *
Line 
1/**
2* Wrapper for load and playback of Youtube videos through their API.
3**/
4package com.jeroenwijering.models {
5
6
7import com.jeroenwijering.events.*;
8import com.jeroenwijering.models.AbstractModel;
9import com.jeroenwijering.player.Model;
10
11import flash.display.Loader;
12import flash.events.*;
13import flash.net.LocalConnection;
14import flash.net.URLRequest;
15import flash.system.Security;
16
17
18public class YoutubeModel extends AbstractModel {
19
20
21        /** Loader for loading the YouTube proxy **/
22        private var loader:Loader;
23        /** 'Unique' string to use for proxy connection. **/
24        private var unique:String;
25        /** Connection towards the YT proxy. **/
26        private var outgoing:LocalConnection;
27        /** connection from the YT proxy. **/
28        private var inbound:LocalConnection;
29        /** Save that the meta has been sent. **/
30        private var metasent:Boolean;
31        /** Save that a load call has been sent. **/
32        private var loading:Boolean;
33        /** Save the connection state. **/
34        private var connected:Boolean;
35        /** URL of a custom youtube swf. **/
36        private var location:String;
37
38
39        /** Setup YouTube connections and load proxy. **/
40        public function YoutubeModel(mod:Model):void {
41                super(mod);
42                Security.allowDomain('*');
43                var url:String = model.display.loaderInfo.url;
44                if(url.indexOf('http://') == 0) {
45                        unique = Math.random().toString().substr(2);
46                        var str:String = url.substr(0,url.indexOf('.swf'));
47                        location = str.substr(0,str.lastIndexOf('/')+1)+'yt.swf?unique='+unique;
48                } else {
49                        unique = '1';
50                        location = 'yt.swf';
51                }
52                outgoing = new LocalConnection();
53                outgoing.allowDomain('*');
54                outgoing.allowInsecureDomain('*');
55                outgoing.addEventListener(StatusEvent.STATUS,onLocalConnectionStatusChange);
56                inbound = new LocalConnection();
57                inbound.allowDomain('*');
58                inbound.allowInsecureDomain('*');
59                inbound.addEventListener(StatusEvent.STATUS,onLocalConnectionStatusChange);
60                //inbound.addEventListener(AsyncErrorEvent.ASYNC_ERROR,errorHandler);
61                inbound.client = this;
62                loader = new Loader();
63                loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler);
64        };
65
66
67        /** Catch load errors. **/
68        private function errorHandler(evt:ErrorEvent):void {
69                stop();
70                model.sendEvent(ModelEvent.ERROR,{message:evt.text});
71        };
72
73
74        /** xtract the current ID from a youtube URL **/
75        private function getID(url:String):String {
76                var arr = url.split('?');
77                var str = '';
78                for (var i in arr) {
79                        if(arr[i].substr(0,2) == 'v=') {
80                                str = arr[i].substr(2);
81                        }
82                }
83                if(str == '') { str = url.substr(url.indexOf('/v/')+3); }
84                if(str.indexOf('&') > -1) {
85                        str = str.substr(0,str.indexOf('&'));
86                }
87                return str;
88        };
89
90
91        /** Load the YouTube movie. **/
92        override public function load(itm:Object):void {
93                item = itm;
94                position = 0;
95                loading = true;
96                if(connected) {
97                        if(outgoing) {
98                                var gid = getID(item['file']);
99                                outgoing.send('AS3_'+unique,"loadVideoById",gid,0);
100                                model.mediaHandler(loader);
101                        }
102                        model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING});
103                        model.sendEvent(ModelEvent.BUFFER,{percentage:0});
104                } else {
105                        inbound.connect('AS2_'+unique);
106                        loader.load(new URLRequest(location));
107                }
108        };
109
110
111        /** Pause the YouTube movie. **/
112        override public function pause():void {
113                outgoing.send('AS3_'+unique,"pauseVideo");
114                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PAUSED});
115        };
116
117
118
119        /** Play or pause the video. **/
120        override public function play():void {
121                outgoing.send('AS3_'+unique,"playVideo");
122                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING});
123        };
124
125
126        /** SWF loaded; add it to the tree **/
127        public function onSwfLoadComplete():void {
128                outgoing.send('AS3_'+unique,"setSize",400,300);
129                model.config['mute'] == true ? volume(0): volume(model.config['volume']);
130                connected = true;
131                if(loading) { load(item); }
132        };
133
134
135        /** error was thrown without this handler **/
136        public function onLocalConnectionStatusChange(evt:StatusEvent):void {
137                // model.sendEvent(ModelEvent.META,{status:evt.code});
138        };
139
140
141        /** Catch youtube errors. **/
142        public function onError(erc:String):void {
143                model.sendEvent(ModelEvent.ERROR,{message:"YouTube error (video not found?):\n"+item['file']});
144                stop();
145        };
146
147
148        /** Catch youtube state changes. **/
149        public function onStateChange(stt:Number):void {
150                switch(Number(stt)) {
151                        case -1:
152                                // model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.IDLE});
153                                break;
154                        case 0:
155                                if(model.config['state'] != ModelStates.BUFFERING && model.config['state'] != ModelStates.IDLE) {
156                                        model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.COMPLETED});
157                                }
158                                break;
159                        case 1:
160                                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PLAYING});
161                                break;
162                        case 2:
163                                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.PAUSED});
164                                break;
165                        case 3:
166                                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.BUFFERING});
167                                model.sendEvent(ModelEvent.BUFFER,{percentage:0});
168                                break;
169                }
170        };
171
172
173        /** Catch Youtube load changes **/
174        public function onLoadChange(ldd:Number,ttl:Number,off:Number):void {
175                model.sendEvent(ModelEvent.LOADED,{loaded:ldd,total:ttl,offset:off});
176        };
177
178
179        /** Catch Youtube position changes **/
180        public function onTimeChange(pos:Number,dur:Number):void {
181                model.sendEvent(ModelEvent.TIME,{position:pos,duration:dur});
182                if(!metasent) {
183                        model.sendEvent(ModelEvent.META,{width:320,height:240,duration:dur});
184                        metasent = true;
185                }
186        };
187
188
189        /** Seek to position. **/
190        override public function seek(pos:Number):void {
191                outgoing.send('AS3_'+unique,"seekTo",pos);
192                play();
193        };
194
195
196        /** Destroy the youtube video. **/
197        override public function stop():void {
198                metasent = false;
199                outgoing.send('AS3_'+unique,"stopVideo");
200                position = 0;
201                model.sendEvent(ModelEvent.STATE,{newstate:ModelStates.IDLE});
202        };
203
204
205
206        /** Set the volume level. **/
207        override public function volume(pct:Number):void {
208                outgoing.send('AS3_'+unique,"setVolume",pct);
209        };
210
211
212}
213
214
215}
Note: See TracBrowser for help on using the repository browser.