root/trunk/as3/com/jeroenwijering/player/Controller.as @ 42

Revision 42, 10.4 kB (checked in by jeroen, 16 months ago)

tagged the 1.1 wmvplayer and started the air player

  • Property svn:executable set to *
Line 
1/**
2* Process all input from the views and modifies the model.
3**/
4package com.jeroenwijering.player {
5
6
7import com.jeroenwijering.events.*;
8import com.jeroenwijering.player.*;
9import com.jeroenwijering.utils.*;
10import flash.display.MovieClip;
11import flash.events.*;
12import flash.geom.Rectangle;
13import flash.net.*;
14import flash.system.Capabilities;
15
16
17public class Controller extends EventDispatcher {
18
19
20        /** Configuration object **/
21        private var config:Object;
22        /** Reference to the skin; for stage event subscription. **/
23        private var skin:MovieClip;
24        /** Object that manages the playlist. **/
25        private var playlister:Playlister;
26        /** Reference to the player's model. **/
27        private var model:Model;
28        /** Reference to the player's view. **/
29        private var view:View;
30        /** object that provides randomization. **/
31        private var randomizer:Randomizer;
32
33
34        /** Constructor, set up stage and playlist listeners. **/
35        public function Controller(cfg:Object,skn:MovieClip) {
36                config = cfg;
37                skin = skn;
38                playlister = new Playlister();
39                playlister.addEventListener(Event.COMPLETE,playlistHandler);
40                playlister.addEventListener(ErrorEvent.ERROR,errorHandler);
41                resizeHandler(new ViewEvent(ViewEvent.RESIZE,{
42                        width:skin.stage.stageWidth,
43                        height:skin.stage.stageHeight
44                }));
45        };
46
47
48        /** Register view and model with controller, start loading playlist. **/
49        public function start(mdl:Model,vie:View) {
50                model= mdl;
51                model.addEventListener(ModelEvent.META,metaHandler);
52                model.addEventListener(ModelEvent.TIME,metaHandler);
53                model.addEventListener(ModelEvent.STATE,stateHandler);
54                view = vie;
55                view.addEventListener(ViewEvent.CAPTION,captionHandler);
56                view.addEventListener(ViewEvent.FULLSCREEN,fullscreenHandler);
57                view.addEventListener(ViewEvent.ITEM,itemHandler);
58                view.addEventListener(ViewEvent.LINK,linkHandler);
59                view.addEventListener(ViewEvent.LOAD,loadHandler);
60                view.addEventListener(ViewEvent.MUTE,muteHandler);
61                view.addEventListener(ViewEvent.NEXT,nextHandler);
62                view.addEventListener(ViewEvent.PLAY,playHandler);
63                view.addEventListener(ViewEvent.PREV,prevHandler);
64                view.addEventListener(ViewEvent.QUALITY,qualityHandler);
65                view.addEventListener(ViewEvent.RESIZE,resizeHandler);
66                view.addEventListener(ViewEvent.SEEK,seekHandler);
67                view.addEventListener(ViewEvent.STOP,stopHandler);
68                view.addEventListener(ViewEvent.VOLUME,volumeHandler);
69                resizeHandler(new ViewEvent(ViewEvent.RESIZE, {
70                        width:skin.stage.stageWidth,
71                        height:skin.stage.stageHeight
72                }));
73                if(config['file']) {
74                        playlister.load(config);
75                }
76        };
77
78
79        /** Save new state of the dub/caption switches. **/
80        private function captionHandler(evt:ViewEvent) {
81                if(evt.data.state != undefined) {
82                        if(evt.data.state == config['caption']) {
83                                return;
84                        } else {
85                                config['caption'] = evt.data.state;
86                        }
87                } else {
88                        config['caption'] = !config['caption'];
89                }
90                Configger.saveCookie('caption',config['caption']);
91                dispatchEvent(new ControllerEvent(ControllerEvent.CAPTION,{state:config['caption']}));
92        };
93
94
95        /** Catch errors dispatched by the playlister. **/
96        private function errorHandler(evt:ErrorEvent) {
97                dispatchEvent(new ControllerEvent(ControllerEvent.ERROR,{message:evt.text}));
98        };
99
100
101        /** Switch fullscreen state. **/
102        private function fullscreenHandler(evt:ViewEvent) {
103                if(skin.stage['displayState'] == 'fullScreen') {
104                        skin.stage['displayState'] = 'normal';
105                } else {
106                        fullscreenrect();
107                        skin.stage['displayState'] = 'fullScreen';
108                }
109        };
110
111
112        /** Set the fullscreen rectangle **/
113        private function fullscreenrect() {
114                var dif = 1;
115                if(config['quality'] == false) { dif = 2; }
116                try {
117                        skin.stage["fullScreenSourceRect"] = new Rectangle(0,0,
118                                Capabilities.screenResolutionX/dif,Capabilities.screenResolutionY/dif);
119                } catch (err:Error) {}
120        };
121
122
123        /** Jump to a userdefined item in the playlist. **/
124        private function itemHandler(evt:ViewEvent) {
125                if(playlist[config['item']]['author'] == 'commercial') { return; }
126                var itm = evt.data.index;
127                if (itm < 0) {
128                        playItem(0);
129                } else if (itm > playlist.length-1) {
130                        playItem(playlist.length-1);
131                } else if (!isNaN(itm)) {
132                        playItem(itm);
133                }
134        };
135
136
137        /** Jump to the link of a playlistitem. **/
138        private function linkHandler(evt:ViewEvent) {
139                var itm = evt.data.index;
140                if (itm  == undefined) {
141                        itm = config['item'];
142                }
143                var lnk = playlist[itm]['link'];
144                if(lnk != undefined) {
145                        navigateToURL(new URLRequest(lnk),config['linktarget']);
146                }
147        };
148
149
150        /** Load a new playlist. **/
151        private function loadHandler(evt:ViewEvent) {
152                stopHandler();
153                try {
154                        playlister.load(evt.data.object);
155                } catch (err:Error) {
156                        dispatchEvent(new ControllerEvent(ControllerEvent.ERROR,{message:err.message}));
157                }
158        };
159
160
161
162        /** Update playlist item duration. **/
163        private function metaHandler(evt:ModelEvent) {
164                if(evt.data.duration) {
165                        var dur = Math.round(evt.data.duration*10)/10
166                        playlister.update(config['item'],'duration',dur);
167                }
168        };
169
170
171        /** Save new state of the mute switch and send volume. **/
172        private function muteHandler(evt:ViewEvent) {
173                if(evt.data.state) {
174                        if(evt.data.state == config['mute']) {
175                                return;
176                        } else {
177                                config['mute'] = evt.data.state;
178                        }
179                } else {
180                        config['mute'] = !config['mute'];
181                }
182                Configger.saveCookie('mute',config['mute']);
183                dispatchEvent(new ControllerEvent(ControllerEvent.MUTE,{state:config['mute']}));
184        };
185
186
187        /** Jump to the next item in the playlist. **/
188        private function nextHandler(evt:ViewEvent) {
189                if(playlist[config['item']]['author'] == 'commercial') { return; }
190                if(config['shuffle'] == true) {
191                        playItem(randomizer.pick());
192                } else if (config['item'] == playlist.length-1) {
193                        playItem(0);
194                } else {
195                        playItem(config['item']+1);
196                }
197        };
198
199
200        /** Change the playback state. **/
201        private function playHandler(evt:ViewEvent) {
202                if(playlist.length == 0) { return; }
203                if(evt.data.state != false && config['state'] == ModelStates.PAUSED) {
204                        dispatchEvent(new ControllerEvent(ControllerEvent.PLAY,{state:true}));
205                } else if (evt.data.state != false && config['state'] == ModelStates.COMPLETED) {
206                        dispatchEvent(new ControllerEvent(ControllerEvent.SEEK,{position:playlist[config['item']]['start']}));
207                } else if(evt.data.state != false && config['state'] == ModelStates.IDLE) {
208                        playItem();
209                } else if (evt.data.state != true &&
210                        (config['state'] == ModelStates.PLAYING || config['state'] == ModelStates.BUFFERING)) {
211                        dispatchEvent(new ControllerEvent(ControllerEvent.PLAY,{state:false}));
212                }
213        };
214
215
216        /** Direct the model to play a new item. **/
217        private function playItem(nbr:Number=undefined) {
218                if(nbr > -1) {
219                        if(playlist[nbr]['file'] == playlist[config['item']]['file']) {
220                                playlist[nbr]['duration'] = playlist[config['item']]['duration'];
221                        }
222                        config['item'] = nbr;
223                }
224                dispatchEvent(new ControllerEvent(ControllerEvent.ITEM,{index:config['item']}));
225        };
226
227
228        /** Manage loading of a new playlist. **/
229        private function playlistHandler(evt:Event) {
230                if(config['shuffle'] == true) {
231                        randomizer = new Randomizer(playlist.length);
232                        config['item'] = randomizer.pick();
233                } else if (config['item'] > playlist.length) {
234                        config['item'] = playlist.length-1;
235                }
236                dispatchEvent(new ControllerEvent(ControllerEvent.PLAYLIST,{playlist:playlist}));
237                if(config['autostart'] == true) {
238                        playItem();
239                }
240        };
241
242
243        /** Jump to the previous item in the playlist. **/
244        private function prevHandler(evt:ViewEvent) {
245                if(playlist[config['item']]['author'] == 'commercial') { return; }
246                if (config['item'] == 0) {
247                        playItem(playlist.length-1);
248                } else {
249                        playItem(config['item']-1);
250                }
251        };
252
253
254        /** Switch playback quality. **/
255        private function qualityHandler(evt:ViewEvent=null) {
256                if(evt.data.state != undefined) {
257                        if(evt.data.state == config['quality']) {
258                                return;
259                        } else {
260                                config['quality'] = evt.data.state;
261                        }
262                } else {
263                        config['quality'] = !config['quality'];
264                }
265                Configger.saveCookie('quality',config['quality']);
266                fullscreenrect();
267                dispatchEvent(new ControllerEvent(ControllerEvent.QUALITY,{state:config['quality']}));
268        };
269
270
271        /** Forward a resizing of the stage. **/
272        private function resizeHandler(evt:ViewEvent) {
273                var mgn = config['margins'].split(',');
274                var dat = {
275                        height:evt.data.height-mgn[0],
276                        width:evt.data.width-mgn[1],
277                        fullscreen:false
278                };
279                try {
280                        var dps = skin.stage['displayState'];
281                } catch (err:Error) {}
282                if(dps == 'fullScreen') {
283                        dat.fullscreen = true;
284                } else {
285                        if(config['controlbar'] == 'bottom') {
286                                dat.height -= config['controlbarsize'];
287                        }
288                        if(config['playlist'] == 'right') {
289                                dat.width -= config['playlistsize'];
290                        } else if(config['playlist'] == 'bottom') {
291                                dat.height -= config['playlistsize'];
292                        }
293                }
294                config['height'] = dat.height;
295                config['width'] = dat.width;
296                dispatchEvent(new ControllerEvent(ControllerEvent.RESIZE,dat));
297        };
298
299
300        /** Seek to a specific part in a mediafile. **/
301        private function seekHandler(evt:ViewEvent) {
302                if(playlist[config['item']]['author'] != 'commercial' &&
303                        config['state'] != ModelStates.IDLE &&
304                        playlist[config['item']]['duration'] > 0) {
305                        var pos = evt.data.position;
306                        if(pos < 2) {
307                                pos = 0;
308                        } else if (pos > playlist[config['item']]['duration']-2) {
309                                pos = playlist[config['item']]['duration']-2;
310                        }
311                        dispatchEvent(new ControllerEvent(ControllerEvent.SEEK,{position:pos}));
312                }
313        };
314
315
316        /** Stop all playback and buffering. **/
317        private function stopHandler(evt:ViewEvent=undefined) {
318                dispatchEvent(new ControllerEvent(ControllerEvent.STOP));
319        };
320
321
322        /** Manage playback state changes. **/
323        private function stateHandler(evt:ModelEvent) {
324                if(evt.data.newstate == ModelStates.COMPLETED && (config['repeat'] == true ||
325                        (config['shuffle'] == true && randomizer.length > 0) ||
326                        (config['shuffle'] == false && config['item'] < playlist.length-1))) {
327                        if(config['shuffle'] == true) {
328                                playItem(randomizer.pick());
329                        } else if(config['item'] == playlist.length-1) {
330                                playItem(0);
331                        } else {
332                                playItem(config['item']+1);
333                        }
334                }
335        };
336
337
338        /** Save new state of the mute switch and send volume. **/
339        private function volumeHandler(evt:ViewEvent) {
340                var vol = evt.data.percentage;
341                if (vol < 1) {
342                        muteHandler(new ViewEvent(ViewEvent.MUTE,{state:true}));
343                } else if (!isNaN(vol)) {
344                        if(vol > 100) { vol = 100; }
345                        if(config['mute'] == true) {
346                                muteHandler(new ViewEvent(ViewEvent.MUTE,{state:false}));
347                        }
348                        config['volume'] = vol;
349                        Configger.saveCookie('volume',vol);
350                        dispatchEvent(new ControllerEvent(ControllerEvent.VOLUME,{percentage:vol}));
351                }
352        };
353
354
355        /** Getter for the playlist. **/
356        public function get playlist():Array {
357                return playlister.playlist;
358        };
359
360
361}
362
363
364}
Note: See TracBrowser for help on using the browser.