source: trunk/fl5/src/com/longtailvideo/jwplayer/player/PlayerV4Emulation.as @ 1246

Revision 1246, 17.5 KB checked in by pablo, 4 years ago (diff)

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 
1package com.longtailvideo.jwplayer.player {
2        import com.jeroenwijering.events.AbstractView;
3        import com.jeroenwijering.events.ControllerEvent;
4        import com.jeroenwijering.events.ModelEvent;
5        import com.jeroenwijering.events.ModelStates;
6        import com.longtailvideo.jwplayer.controller.Controller;
7        import com.longtailvideo.jwplayer.events.MediaEvent;
8        import com.longtailvideo.jwplayer.events.PlayerEvent;
9        import com.longtailvideo.jwplayer.events.PlayerStateEvent;
10        import com.longtailvideo.jwplayer.events.PlaylistEvent;
11        import com.longtailvideo.jwplayer.events.ViewEvent;
12        import com.longtailvideo.jwplayer.model.IPlaylist;
13        import com.longtailvideo.jwplayer.model.Model;
14        import com.longtailvideo.jwplayer.model.PlaylistItem;
15        import com.longtailvideo.jwplayer.model.PlaylistItemLevel;
16        import com.longtailvideo.jwplayer.plugins.IPlugin;
17        import com.longtailvideo.jwplayer.plugins.PluginConfig;
18        import com.longtailvideo.jwplayer.plugins.V4Plugin;
19        import com.longtailvideo.jwplayer.utils.JavascriptSerialization;
20        import com.longtailvideo.jwplayer.utils.Logger;
21        import com.longtailvideo.jwplayer.utils.Strings;
22        import com.longtailvideo.jwplayer.view.interfaces.IControlbarComponent;
23        import com.longtailvideo.jwplayer.view.interfaces.IDisplayComponent;
24        import com.longtailvideo.jwplayer.view.interfaces.IDockComponent;
25        import com.longtailvideo.jwplayer.view.interfaces.IPlaylistComponent;
26       
27        import flash.display.DisplayObject;
28        import flash.events.EventDispatcher;
29        import flash.net.URLRequest;
30        import flash.net.navigateToURL;
31        import flash.utils.describeType;
32
33        /**
34         * This singleton class acts as a wrapper between the Player and plugins or javascripts that were
35         * written for version 4 of the player.  It extends version 4's AbstractView class, and translates
36         * Player 5 event dispatches into their version 4 counterparts.
37         *
38         * @see com.longtailvideo.jwplayer.plugins.V4Plugin 
39         */
40        public class PlayerV4Emulation extends AbstractView {
41                private static var instance:PlayerV4Emulation;
42               
43                private var _player:IPlayer;
44               
45                private var viewEventDispatcher:EventDispatcher;
46                private var modelEventDispatcher:EventDispatcher;
47                private var controllerEventDispatcher:EventDispatcher;
48               
49                private var id:String;
50                private var client:String;
51                private var version:String;
52               
53                public function PlayerV4Emulation(player:IPlayer) {
54                        viewEventDispatcher = new EventDispatcher();
55                        modelEventDispatcher = new EventDispatcher();
56                        controllerEventDispatcher = new EventDispatcher();
57                               
58                        _player = player;
59                        _player.addEventListener(PlayerEvent.JWPLAYER_READY, playerReady);
60                }
61               
62                public static function getInstance(player:IPlayer):PlayerV4Emulation {
63                        if (!instance) {
64                                instance = new PlayerV4Emulation(player);
65                        }
66                        return instance;
67                }
68               
69                private function playerReady(evt:PlayerEvent):void {
70                        id = evt.id;
71                        client = evt.client;
72                        version = evt.version;
73                         
74                        dispatchEvent(new com.jeroenwijering.events.PlayerEvent(com.jeroenwijering.events.PlayerEvent.READY));
75                        setupListeners();
76                }
77               
78                private function setupListeners():void {
79                        _player.addEventListener(PlayerEvent.JWPLAYER_ERROR, errorHandler);
80                       
81                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_BUFFER, mediaBuffer);
82                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_ERROR, mediaError);
83                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_LOADED, mediaLoaded);
84                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_TIME, mediaTime);
85                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_VOLUME, mediaVolume);
86                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_MUTE, mediaMute);
87                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_META, mediaMeta);
88                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_COMPLETE, mediaComplete);
89                        _player.addEventListener(PlayerStateEvent.JWPLAYER_PLAYER_STATE, stateHandler);
90
91                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_FULLSCREEN, viewFullscreen);
92                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_ITEM, viewItem);
93                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_LOAD, viewLoad);
94                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_MUTE, viewMute);
95                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_NEXT, viewNext);
96                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_PAUSE, viewPause);
97                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_PLAY, viewPlay);
98                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_PREV, viewPrev);
99                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_SEEK, viewSeek);
100                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_STOP, viewStop);
101                        _player.addEventListener(ViewEvent.JWPLAYER_VIEW_VOLUME, viewVolume);
102                       
103                        _player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_ITEM, playlistItem);
104                        _player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_LOADED, playlistLoad);
105                }
106               
107                // Player Event Handlers
108               
109                private function errorHandler(evt:PlayerEvent):void {
110                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.ERROR, {message:evt.message, id:id, client:client, version:version}));
111                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.ERROR, {message:evt.message, id:id, client:client, version:version}));
112                }
113               
114                // Media Event Handlers
115               
116                private function mediaBuffer(evt:MediaEvent):void {
117                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.BUFFER, {percentage:evt.bufferPercent, id:id, client:client, version:version}));
118                }
119               
120                private function mediaError(evt:MediaEvent):void {
121                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.ERROR, {message:evt.message, id:id, client:client, version:version}));
122                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.ERROR, {message:evt.message, id:id, client:client, version:version}));
123                }
124               
125                private function mediaLoaded(evt:MediaEvent):void {
126                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.LOADED, {loaded:0, total:0, offset:0, id:id, client:client, version:version}));
127                }
128               
129                private function mediaTime(evt:MediaEvent):void {
130                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.TIME, {duration:evt.duration, position:evt.position, id:id, client:client, version:version}));
131                }
132               
133                private function mediaVolume(evt:MediaEvent):void {
134                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.VOLUME, {percentage:evt.volume, id:id, client:client, version:version}));
135                }
136               
137                private function mediaMute(evt:MediaEvent):void {
138                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.MUTE, {state:evt.mute, id:id, client:client, version:version}));
139                }
140               
141
142                private function mediaMeta(evt:MediaEvent):void {
143                        evt.metadata['id'] = id;
144                        evt.metadata['client'] = client;
145                        evt.metadata['version'] = version;
146                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.META, evt.metadata));
147                }
148               
149                private function mediaComplete(evt:MediaEvent):void {
150                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.STATE, {id:id, oldstate:_player.state, newstate:ModelStates.COMPLETED}));
151                }
152               
153                private function stateHandler(evt:PlayerStateEvent):void {
154                        if (evt.newstate == PlayerState.IDLE && (evt.oldstate == PlayerState.BUFFERING || evt.oldstate == PlayerState.PLAYING)) {
155                                controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.STOP, {id:id, client:client, version:version}));
156                        }
157                       
158                        modelEventDispatcher.dispatchEvent(new ModelEvent(ModelEvent.STATE, {id:id, oldstate:evt.oldstate, newstate:evt.newstate}));
159                }
160               
161                // View Event Handlers
162
163                private function viewFullscreen(evt:ViewEvent):void {
164                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.FULLSCREEN, {state:evt.data, id:id, client:client, version:version}));
165                }
166               
167                private function viewItem(evt:ViewEvent):void {
168                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.ITEM, {index:evt.data, id:id, client:client, version:version}));
169                }
170
171                private function viewLoad(evt:ViewEvent):void {
172                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.LOAD, {object:evt.data, id:id, client:client, version:version}));
173                }
174               
175                private function viewMute(evt:ViewEvent):void {
176                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.MUTE, {state:evt.data, id:id, client:client, version:version}));
177                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.MUTE, {state:evt.data, id:id, client:client, version:version}));
178                }
179               
180                private function viewNext(evt:ViewEvent):void {
181                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.NEXT, {id:id, client:client, version:version}));
182                }
183               
184                private function viewPause(evt:ViewEvent):void {
185                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.PLAY, {state:false, id:id, client:client, version:version}));
186                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.PLAY, {state:false, id:id, client:client, version:version}));
187                }
188
189                private function viewPlay(evt:ViewEvent):void {
190                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.PLAY, {state:true, id:id, client:client, version:version}));
191                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.PLAY, {state:true, id:id, client:client, version:version}));
192                }
193               
194                private function viewPrev(evt:ViewEvent):void {
195                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.PREV, {id:id, client:client, version:version}));
196                }
197               
198                private function viewRedraw(width:Number, height:Number):void {
199                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.REDRAW, {id:id, client:client, version:version}));
200                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.RESIZE, {width:width, height:height, fullscreen:_player.config.fullscreen, client:client, version:version}));
201                }
202
203                private function viewSeek(evt:ViewEvent):void {
204                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.SEEK, {position:evt.data, id:id, client:client, version:version}));
205                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.SEEK, {position:evt.data, id:id, client:client, version:version}));
206                }
207               
208                private function viewStop(evt:ViewEvent):void {
209                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.STOP, {id:id, client:client, version:version}));
210                }
211               
212                private function viewVolume(evt:ViewEvent):void {
213                        viewEventDispatcher.dispatchEvent(new com.jeroenwijering.events.ViewEvent(com.jeroenwijering.events.ViewEvent.VOLUME, {state:evt.data, id:id, client:client, version:version}));
214                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.VOLUME, {percentage:evt.data, id:id, client:client, version:version}));
215                }
216               
217                // Playlist Event Handlers
218               
219                private function playlistItem(evt:PlaylistEvent):void {
220                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.ITEM, {index:_player.playlist.currentIndex, id:id, client:client, version:version}));
221                }
222
223                private function playlistLoad(evt:PlaylistEvent):void {
224                        controllerEventDispatcher.dispatchEvent(new ControllerEvent(ControllerEvent.PLAYLIST, {playlist:JavascriptSerialization.playlistToArray(_player.playlist), id:id, client:client, version:version}));
225                }
226               
227               
228                // Listeners
229
230                public override function addModelListener(type:String, listener:Function):void {
231                        modelEventDispatcher.addEventListener(type.toUpperCase(), listener);
232                }
233                public override function removeModelListener(type:String, listener:Function):void {
234                        modelEventDispatcher.removeEventListener(type.toUpperCase(), listener);
235                }
236
237                public override function addViewListener(type:String, listener:Function):void {
238                        viewEventDispatcher.addEventListener(type.toUpperCase(), listener);
239                }
240                public override function removeViewListener(type:String, listener:Function):void {
241                        viewEventDispatcher.removeEventListener(type.toUpperCase(), listener);
242                }
243
244                public override function addControllerListener(type:String, listener:Function):void {
245                        controllerEventDispatcher.addEventListener(type.toUpperCase(), listener);
246                }
247                public override function removeControllerListener(type:String, listener:Function):void {
248                        controllerEventDispatcher.removeEventListener(type.toUpperCase(), listener);
249                }
250               
251                // Event "dispatcher"
252               
253                public override function sendEvent(typ:String, prm:Object=undefined) : void {
254                        Logger.log("V4 emulator sending event: " + typ + " " + Strings.print_r(prm));
255                        switch (typ) {
256                                case com.jeroenwijering.events.ViewEvent.FULLSCREEN:
257                                        _player.fullscreen(prm);
258                                        break;
259                                case com.jeroenwijering.events.ViewEvent.ITEM:
260                                        _player.playlistItem(Number(prm));
261                                        break;
262                                case com.jeroenwijering.events.ViewEvent.LINK:
263                                        link(Number(prm));
264                                        break;
265                                case com.jeroenwijering.events.ViewEvent.LOAD:
266                                        _player.load(prm);
267                                        break;
268                                case com.jeroenwijering.events.ViewEvent.MUTE:
269                                        if (prm != null && prm != "") {
270                                                _player.mute(prm != "false" && prm != 0);
271                                        } else {
272                                                _player.mute(!_player.config.mute);
273                                        }
274                                        break;
275                                case com.jeroenwijering.events.ViewEvent.NEXT:
276                                        _player.playlistNext();
277                                        break;
278                                case com.jeroenwijering.events.ViewEvent.PLAY:
279                                        if (prm == null || prm == "") {
280                                                if (_player.state == PlayerState.PAUSED || _player.state == PlayerState.IDLE) {
281                                                        prm = "true";
282                                                } else {
283                                                        prm = "false";
284                                                }
285                                        }
286                                        if (prm != null && Strings.serialize(prm.toString()) == false) {
287                                                _player.pause();
288                                        } else {
289                                                _player.play();
290                                        }
291                                        break;
292                                case com.jeroenwijering.events.ViewEvent.PREV:
293                                        _player.playlistPrev();
294                                        break;
295                                case com.jeroenwijering.events.ViewEvent.REDRAW:
296                                        _player.redraw();
297                                        break;
298                                case com.jeroenwijering.events.ViewEvent.SEEK:
299                                        _player.seek(Number(prm));
300                                        break;
301                                case com.jeroenwijering.events.ViewEvent.STOP:
302                                        _player.stop();
303                                        break;
304                                case com.jeroenwijering.events.ViewEvent.TRACE:
305                                        Logger.log(prm);
306                                        break;
307                                case com.jeroenwijering.events.ViewEvent.VOLUME:
308                                        _player.volume(Number(prm));
309                                        break;
310                        }
311                }
312
313                public override function get config():Object {
314                        var cfg:Object = {};
315                        var descType:XML = describeType(_player.config)
316                        for each (var i:String in descType.accessor.@name) {
317                                if (_player.config[i] != null) {
318                                        cfg[i] = Strings.serialize(_player.config[i].toString());
319                                }
320                        }
321                       
322                        for each (var j:String in _player.config.pluginIds) {
323                                var pluginConfig:PluginConfig = _player.config.pluginConfig(j);
324                                for (var k:String in pluginConfig){
325                                        cfg[j+"."+k] = pluginConfig[k];
326                                }
327                        }
328
329                        switch(_player.state) {
330                                case PlayerState.BUFFERING:
331                                        cfg['state'] = ModelStates.BUFFERING;
332                                        break;
333                                case PlayerState.PLAYING:
334                                        cfg['state'] = ModelStates.PLAYING;
335                                        break;
336                                case PlayerState.PAUSED:
337                                        cfg['state'] = ModelStates.PAUSED;
338                                        break;
339                                case PlayerState.IDLE:
340                                        if (_player.playlist.currentIndex > 0 && _player.playlist.currentIndex == (_player.playlist.length-1)) {
341                                                cfg['state'] = ModelStates.COMPLETED;
342                                        } else {
343                                                cfg['state'] = ModelStates.IDLE;
344                                        }
345                                        break;
346                        }
347
348                        cfg['fullscreen'] = _player.config.fullscreen;
349                        cfg['version'] = _player.version;
350                        cfg['item'] = _player.playlist.currentIndex;
351                        cfg['level'] = _player.playlist.currentItem ? _player.playlist.currentItem.currentLevel : 0;
352                       
353                        return cfg;
354                }
355
356                public override function get playlist():Array {
357                        return JavascriptSerialization.playlistToArray(_player.playlist);
358                }
359               
360                public override function getPluginConfig(plugin:Object):Object {
361                        if (plugin is IPlugin) {
362                                return _player.config.pluginConfig((plugin as IPlugin).id)
363                        } else if (plugin is V4Plugin) {
364                                return _player.config.pluginConfig((plugin as V4Plugin).pluginId);
365                        } else if ((plugin as DisplayObject).parent is V4Plugin) {
366                                return _player.config.pluginConfig((plugin.parent as V4Plugin).pluginId);
367                        } else if (plugin is IDockComponent) {
368                                return _player.config.pluginConfig('dock');
369                        } else if (plugin is IDisplayComponent) {
370                                return _player.config.pluginConfig('display');
371                        } else if (plugin is IControlbarComponent) {
372                                return _player.config.pluginConfig('controlbar');
373                        } else if (plugin is IPlaylistComponent) {
374                                return _player.config.pluginConfig('playlist');
375                        } else {
376                                return new PluginConfig('');
377                        }
378                }
379               
380                public function resize(width:Number, height:Number):void {
381                        viewRedraw(width, height);
382                }
383               
384                public override function getPlugin(plugin:String):Object {
385                        var result:Object;
386                        switch (plugin){
387                                case 'dock':
388                                        result = _player.controls.dock as Object;
389                                        break;
390                                case 'controlbar':
391                                        result = _player.controls.controlbar as Object;
392                                        break;
393                                case 'display':
394                                        result = _player.controls.display as Object;
395                                        break;
396                                case 'playlist':
397                                        result = _player.controls.playlist as Object;
398                                        break;
399                                default:
400                                        // Backwards compatibility for 4.x plugins
401                                        try {
402                                                result = (_player as Object).getPlugin(plugin);
403                                        } catch (e:Error) {}
404                        }
405                        return result;
406                }
407               
408                private function link(playlistIndex:Number):void {
409                        if (isNaN(playlistIndex))
410                                playlistIndex = _player.playlist.currentIndex;
411                       
412                        if (playlistIndex >= 0 && playlistIndex < _player.playlist.length) {
413                                navigateToURL(new URLRequest(_player.playlist.getItemAt(playlistIndex).link), _player.config.linktarget);
414                        }
415                }
416        }
417}
Note: See TracBrowser for help on using the repository browser.