| 1 | /** |
|---|
| 2 | * Loads external SWF skins and plugins. |
|---|
| 3 | **/ |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | package com.jeroenwijering.player { |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | import com.jeroenwijering.events.SPLoaderEvent; |
|---|
| 10 | import com.jeroenwijering.player.Player; |
|---|
| 11 | import com.jeroenwijering.utils.Strings; |
|---|
| 12 | |
|---|
| 13 | import flash.display.*; |
|---|
| 14 | import flash.events.*; |
|---|
| 15 | import flash.net.URLRequest; |
|---|
| 16 | import flash.system.*; |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | public class SPLoader extends EventDispatcher { |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | /** Reference to the player config. **/ |
|---|
| 23 | private var config:Object; |
|---|
| 24 | /** Reference to the skin. **/ |
|---|
| 25 | private var skin:MovieClip; |
|---|
| 26 | /** Reference to the view. **/ |
|---|
| 27 | private var player:Player; |
|---|
| 28 | /** SWF loader reference **/ |
|---|
| 29 | private var loader:Loader; |
|---|
| 30 | /** Number of plugns that are done loading. **/ |
|---|
| 31 | private var done:Number = 0; |
|---|
| 32 | /** List with all the plugins. **/ |
|---|
| 33 | private var plugins:Array; |
|---|
| 34 | /** Base directory from which plugins are loaded. **/ |
|---|
| 35 | private var basedir:String = 'http://plugins.longtailvideo.com/'; |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | /** Constructor, references **/ |
|---|
| 39 | public function SPLoader(ply:Player):void { |
|---|
| 40 | config = ply.config; |
|---|
| 41 | skin = ply.skin; |
|---|
| 42 | player = ply; |
|---|
| 43 | plugins = new Array(); |
|---|
| 44 | }; |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | /** Add a plugin to the list. **/ |
|---|
| 48 | public function addPlugin(pgi:Object,nam:String,ext:Boolean=false):void { |
|---|
| 49 | var obj:Object = { reference:pgi,name:nam,x:0,y:0,width:400,height:300}; |
|---|
| 50 | // hack for the playlist/controlbar flashvars |
|---|
| 51 | var cbr:DisplayObject = skin.getChildByName('controlbar'); |
|---|
| 52 | var dck:DisplayObject = skin.getChildByName('dock'); |
|---|
| 53 | if(nam == 'controlbar') { |
|---|
| 54 | config['controlbar.position'] = config['controlbar']; |
|---|
| 55 | config['controlbar.size'] = cbr.height; |
|---|
| 56 | config['controlbar.margin'] = cbr.x; |
|---|
| 57 | } else if (nam == 'playlist') { |
|---|
| 58 | config['playlist.position'] = config['playlist']; |
|---|
| 59 | config['playlist.size'] = config['playlistsize']; |
|---|
| 60 | } |
|---|
| 61 | // load config for plugin |
|---|
| 62 | try { |
|---|
| 63 | for(var org:String in pgi.config) { |
|---|
| 64 | obj[org] = pgi.config[org]; |
|---|
| 65 | } |
|---|
| 66 | } catch (err:Error) {} |
|---|
| 67 | for(var str:String in config) { |
|---|
| 68 | if (str.indexOf(nam + ".") == 0) { |
|---|
| 69 | obj[str.substring(nam.length + 1)] = config[str]; |
|---|
| 70 | } |
|---|
| 71 | } |
|---|
| 72 | //load skin for plugin |
|---|
| 73 | var clp:DisplayObject; |
|---|
| 74 | if(ext == true) { |
|---|
| 75 | clp = DisplayObject(pgi); |
|---|
| 76 | skin.addChild(clp); |
|---|
| 77 | } else if(skin.getChildByName(nam)) { |
|---|
| 78 | clp = skin.getChildByName(nam); |
|---|
| 79 | } else { |
|---|
| 80 | clp = new MovieClip(); |
|---|
| 81 | clp.name = nam; |
|---|
| 82 | skin.addChildAt(clp,1); |
|---|
| 83 | } |
|---|
| 84 | // add plugin and initialize |
|---|
| 85 | plugins.push(obj); |
|---|
| 86 | try { |
|---|
| 87 | pgi.config = obj; |
|---|
| 88 | pgi.clip = clp; |
|---|
| 89 | } catch (err:Error) {} |
|---|
| 90 | if(cbr) { skin.setChildIndex(cbr,skin.numChildren-1); } |
|---|
| 91 | if(dck) { skin.setChildIndex(dck,skin.numChildren-1); } |
|---|
| 92 | pgi.initializePlugin(player.view); |
|---|
| 93 | }; |
|---|
| 94 | |
|---|
| 95 | |
|---|
| 96 | /** Get a reference to a specific plugin. **/ |
|---|
| 97 | public function getPlugin(nam:String):Object { |
|---|
| 98 | for(var i:Number=0; i<plugins.length; i++) { |
|---|
| 99 | if(plugins[i]['name'] == nam) { |
|---|
| 100 | return plugins[i]['reference']; |
|---|
| 101 | } |
|---|
| 102 | } |
|---|
| 103 | return null; |
|---|
| 104 | }; |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | /** Return the configuration data of a specific plugin. **/ |
|---|
| 108 | public function getPluginConfig(plg:Object):Object { |
|---|
| 109 | for(var i:Number=0; i<plugins.length; i++) { |
|---|
| 110 | if(plugins[i]['reference'] == plg) { |
|---|
| 111 | return plugins[i]; |
|---|
| 112 | } |
|---|
| 113 | } |
|---|
| 114 | return null; |
|---|
| 115 | }; |
|---|
| 116 | |
|---|
| 117 | |
|---|
| 118 | /** Load a single plugin into the stack (after initialization). **/ |
|---|
| 119 | public function loadPlugin(url:String,str:String=null) { |
|---|
| 120 | if(str != null && str != '') { |
|---|
| 121 | var ar1:Array = str.split('&'); |
|---|
| 122 | for(var i:String in ar1) { |
|---|
| 123 | var ar2:Array = ar1[i].split('='); |
|---|
| 124 | config[ar2[0]] = Strings.serialize(ar2[1]); |
|---|
| 125 | } |
|---|
| 126 | } |
|---|
| 127 | loadSWF(url,false); |
|---|
| 128 | }; |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | /** Start loading the SWF plugins, or broadcast if there's none. **/ |
|---|
| 132 | public function loadPlugins():void { |
|---|
| 133 | if(config['plugins']) { |
|---|
| 134 | var arr:Array = config['plugins'].split(','); |
|---|
| 135 | done = arr.length; |
|---|
| 136 | for(var i:Number=0; i<arr.length; i++) { |
|---|
| 137 | loadSWF(arr[i],false); |
|---|
| 138 | } |
|---|
| 139 | } else { |
|---|
| 140 | dispatchEvent(new SPLoaderEvent(SPLoaderEvent.PLUGINS)); |
|---|
| 141 | } |
|---|
| 142 | }; |
|---|
| 143 | |
|---|
| 144 | |
|---|
| 145 | /** Start loading the skin, or broadcast if there's none. **/ |
|---|
| 146 | public function loadSkin():void { |
|---|
| 147 | if(config['skin']) { |
|---|
| 148 | loadSWF(config['skin'],true); |
|---|
| 149 | } else { |
|---|
| 150 | dispatchEvent(new SPLoaderEvent(SPLoaderEvent.SKIN)); |
|---|
| 151 | } |
|---|
| 152 | }; |
|---|
| 153 | |
|---|
| 154 | |
|---|
| 155 | /** Load a particular SWF file. **/ |
|---|
| 156 | private function loadSWF(str:String,skn:Boolean):void { |
|---|
| 157 | if(str.substr(-4) == '.swf') { str = str.substr(0, str.length-4); } |
|---|
| 158 | var ldr:Loader = new Loader(); |
|---|
| 159 | if(skn || str.indexOf('/') > -1) { |
|---|
| 160 | ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,skinError); |
|---|
| 161 | ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,skinHandler); |
|---|
| 162 | } else { |
|---|
| 163 | ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,pluginError); |
|---|
| 164 | ldr.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR,pluginError); |
|---|
| 165 | ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,pluginHandler); |
|---|
| 166 | } |
|---|
| 167 | str += '.swf'; |
|---|
| 168 | if(skin.loaderInfo.url.indexOf('http') == 0) { |
|---|
| 169 | var ctx:LoaderContext = new LoaderContext(true,ApplicationDomain.currentDomain,SecurityDomain.currentDomain); |
|---|
| 170 | if(skn) { |
|---|
| 171 | ldr.load(new URLRequest(str),ctx); |
|---|
| 172 | } else { |
|---|
| 173 | ldr.load(new URLRequest(basedir+str),ctx); |
|---|
| 174 | } |
|---|
| 175 | } else { |
|---|
| 176 | ldr.load(new URLRequest(str)); |
|---|
| 177 | } |
|---|
| 178 | }; |
|---|
| 179 | |
|---|
| 180 | |
|---|
| 181 | /** Plugin loading failed. **/ |
|---|
| 182 | private function pluginError(evt:ErrorEvent):void { |
|---|
| 183 | done--; |
|---|
| 184 | if(done == 0) { |
|---|
| 185 | dispatchEvent(new SPLoaderEvent(SPLoaderEvent.PLUGINS)); |
|---|
| 186 | } |
|---|
| 187 | }; |
|---|
| 188 | |
|---|
| 189 | |
|---|
| 190 | /** Plugin loading completed; add to stage and populate. **/ |
|---|
| 191 | private function pluginHandler(evt:Event):void { |
|---|
| 192 | try { |
|---|
| 193 | var idx:Number = evt.target.url.lastIndexOf('/'); |
|---|
| 194 | var end:Number = evt.target.url.length-4; |
|---|
| 195 | if(evt.target.url.indexOf('-',end-5) > -1) { |
|---|
| 196 | end = evt.target.url.indexOf('-',end-5); |
|---|
| 197 | } |
|---|
| 198 | var nam:String = evt.target.url.substring(idx+1,end).toLowerCase(); |
|---|
| 199 | addPlugin(evt.target.content,nam,true); |
|---|
| 200 | evt.target.loader.visible = true; |
|---|
| 201 | } catch(err:Error) {} |
|---|
| 202 | done--; |
|---|
| 203 | if(done == 0) { |
|---|
| 204 | dispatchEvent(new SPLoaderEvent(SPLoaderEvent.PLUGINS)); |
|---|
| 205 | } else if (done <0) { |
|---|
| 206 | player.view.sendEvent('REDRAW'); |
|---|
| 207 | } |
|---|
| 208 | }; |
|---|
| 209 | |
|---|
| 210 | |
|---|
| 211 | /** Layout all plugins for a normal resize. **/ |
|---|
| 212 | public function layoutNormal():void { |
|---|
| 213 | var bounds:Object = {x:0,y:0,width:config['width'],height:config['height']}; |
|---|
| 214 | var overs:Array = new Array(); |
|---|
| 215 | for(var i:Number = plugins.length-1; i>=0; i--) { |
|---|
| 216 | switch(plugins[i]['position']) { |
|---|
| 217 | case "left": |
|---|
| 218 | plugins[i]['x'] = bounds.x; |
|---|
| 219 | plugins[i]['y'] = bounds.y; |
|---|
| 220 | plugins[i]['width'] = plugins[i]['size']; |
|---|
| 221 | plugins[i]['height'] = bounds.height; |
|---|
| 222 | plugins[i]['visible'] = true; |
|---|
| 223 | bounds.x += plugins[i]['size']; |
|---|
| 224 | bounds.width -= plugins[i]['size']; |
|---|
| 225 | break; |
|---|
| 226 | case "top": |
|---|
| 227 | plugins[i]['x'] = bounds.x; |
|---|
| 228 | plugins[i]['y'] = bounds.y; |
|---|
| 229 | plugins[i]['width'] = bounds.width; |
|---|
| 230 | plugins[i]['height'] = plugins[i]['size']; |
|---|
| 231 | plugins[i]['visible'] = true; |
|---|
| 232 | bounds.y += plugins[i]['size']; |
|---|
| 233 | bounds.height -= plugins[i]['size']; |
|---|
| 234 | break; |
|---|
| 235 | case "right": |
|---|
| 236 | plugins[i]['x'] = bounds.x + bounds.width - plugins[i]['size']; |
|---|
| 237 | plugins[i]['y'] = bounds.y; |
|---|
| 238 | plugins[i]['width'] = plugins[i]['size']; |
|---|
| 239 | plugins[i]['height'] = bounds.height; |
|---|
| 240 | plugins[i]['visible'] = true; |
|---|
| 241 | bounds.width -= plugins[i]['size']; |
|---|
| 242 | break; |
|---|
| 243 | case "bottom": |
|---|
| 244 | plugins[i]['x'] = bounds.x; |
|---|
| 245 | plugins[i]['y'] = bounds.y+bounds.height-plugins[i]['size']; |
|---|
| 246 | plugins[i]['width'] = bounds.width; |
|---|
| 247 | plugins[i]['height'] = plugins[i]['size']; |
|---|
| 248 | plugins[i]['visible'] = true; |
|---|
| 249 | bounds.height -= plugins[i]['size']; |
|---|
| 250 | break; |
|---|
| 251 | case "none": |
|---|
| 252 | plugins[i]['visible'] = false; |
|---|
| 253 | break; |
|---|
| 254 | default: |
|---|
| 255 | overs.push(i); |
|---|
| 256 | break; |
|---|
| 257 | } |
|---|
| 258 | } |
|---|
| 259 | for(var j:Number=0; j<overs.length; j++) { |
|---|
| 260 | plugins[overs[j]]['x'] = bounds.x; |
|---|
| 261 | plugins[overs[j]]['y'] = bounds.y; |
|---|
| 262 | plugins[overs[j]]['width'] = bounds.width; |
|---|
| 263 | plugins[overs[j]]['height'] = bounds.height; |
|---|
| 264 | plugins[overs[j]]['visible'] = true; |
|---|
| 265 | } |
|---|
| 266 | if(config['resizing']) { |
|---|
| 267 | config['width'] = bounds.width; |
|---|
| 268 | config['height'] = bounds.height; |
|---|
| 269 | } |
|---|
| 270 | }; |
|---|
| 271 | |
|---|
| 272 | |
|---|
| 273 | /** Layout all plugins in case of a fullscreen resize. **/ |
|---|
| 274 | public function layoutFullscreen() { |
|---|
| 275 | for(var i:Number=0; i<plugins.length; i++) { |
|---|
| 276 | if (plugins[i]['position'] == 'over' || plugins[i]['position'] == undefined || |
|---|
| 277 | plugins[i]['name'] == 'controlbar' && plugins[i]['position'] != 'none') { |
|---|
| 278 | plugins[i]['x'] = 0; |
|---|
| 279 | plugins[i]['y'] = 0; |
|---|
| 280 | plugins[i]['width'] = skin.stage.stageWidth; |
|---|
| 281 | plugins[i]['height'] = skin.stage.stageHeight; |
|---|
| 282 | plugins[i]['visible'] = true; |
|---|
| 283 | } else { |
|---|
| 284 | plugins[i]['visible'] = false; |
|---|
| 285 | } |
|---|
| 286 | } |
|---|
| 287 | if(config['resizing']) { |
|---|
| 288 | config['width'] = skin.stage.stageWidth; |
|---|
| 289 | config['height'] = skin.stage.stageHeight; |
|---|
| 290 | } |
|---|
| 291 | }; |
|---|
| 292 | |
|---|
| 293 | |
|---|
| 294 | /** Skin loading failed; use default skin. **/ |
|---|
| 295 | private function skinError(evt:IOErrorEvent=null):void { |
|---|
| 296 | dispatchEvent(new SPLoaderEvent(SPLoaderEvent.SKIN)); |
|---|
| 297 | }; |
|---|
| 298 | |
|---|
| 299 | |
|---|
| 300 | /** Skin loading completed; add to stage and populate. **/ |
|---|
| 301 | private function skinHandler(evt:Event):void { |
|---|
| 302 | try { |
|---|
| 303 | var skn:MovieClip = evt.target.content['player']; |
|---|
| 304 | while(skn.numChildren > 0) { |
|---|
| 305 | var chd:DisplayObject = skin.getChildByName(skn.getChildAt(0).name); |
|---|
| 306 | |
|---|
| 307 | if(chd) { |
|---|
| 308 | var idx:Number = skin.getChildIndex(chd); |
|---|
| 309 | skin.removeChild(chd); |
|---|
| 310 | skin.addChildAt(skn.getChildAt(0),idx); |
|---|
| 311 | skin.getChildByName(chd.name).visible = false; |
|---|
| 312 | } else { |
|---|
| 313 | skin.addChild(skn.getChildAt(0)); |
|---|
| 314 | } |
|---|
| 315 | } |
|---|
| 316 | dispatchEvent(new SPLoaderEvent(SPLoaderEvent.SKIN)); |
|---|
| 317 | } catch (err:Error) {} |
|---|
| 318 | }; |
|---|
| 319 | |
|---|
| 320 | |
|---|
| 321 | } |
|---|
| 322 | |
|---|
| 323 | |
|---|
| 324 | } |
|---|