PageRenderTime 51ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/flowplayer/branches/rss/src/actionscript/org/flowplayer/view/Launcher.as

http://flowplayer-core.googlecode.com/
ActionScript | 766 lines | 627 code | 112 blank | 27 comment | 120 complexity | 5a56c9c00d8eba519c5dd8b9f26d5778 MD5 | raw file
Possible License(s): GPL-3.0, AGPL-1.0
  1. /*
  2. * Copyright (c) 2008, 2009 Flowplayer Oy
  3. *
  4. * This file is part of Flowplayer.
  5. *
  6. * Flowplayer is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Flowplayer is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Flowplayer. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package org.flowplayer.view {
  20. import org.flowplayer.config.Config;
  21. import org.flowplayer.config.ConfigLoader;
  22. import org.flowplayer.config.ExternalInterfaceHelper;
  23. import org.flowplayer.config.VersionInfo;
  24. import org.flowplayer.controller.PlayListController;
  25. import org.flowplayer.controller.ResourceLoader;
  26. import org.flowplayer.controller.ResourceLoaderImpl;
  27. import org.flowplayer.flow_internal;
  28. import org.flowplayer.model.Callable;
  29. import org.flowplayer.model.Clip;
  30. import org.flowplayer.model.ClipEvent;
  31. import org.flowplayer.model.ClipEventType;
  32. import org.flowplayer.model.DisplayPluginModel;
  33. import org.flowplayer.model.DisplayProperties;
  34. import org.flowplayer.model.DisplayPropertiesImpl;
  35. import org.flowplayer.model.EventDispatcher;
  36. import org.flowplayer.model.Loadable;
  37. import org.flowplayer.model.Logo;
  38. import org.flowplayer.model.PlayButtonOverlay;
  39. import org.flowplayer.model.PlayerError;
  40. import org.flowplayer.model.PlayerEvent;
  41. import org.flowplayer.model.Playlist;
  42. import org.flowplayer.model.Plugin;
  43. import org.flowplayer.model.PluginError;
  44. import org.flowplayer.model.PluginEvent;
  45. import org.flowplayer.model.PluginModel;
  46. import org.flowplayer.model.ProviderModel;
  47. import org.flowplayer.model.State;
  48. import org.flowplayer.util.Arrange;
  49. import org.flowplayer.util.Log;
  50. import org.flowplayer.util.TextUtil;
  51. import org.flowplayer.util.URLUtil;
  52. import org.flowplayer.view.Panel;
  53. import org.flowplayer.view.PluginLoader;
  54. import org.flowplayer.view.Screen;
  55. import org.osflash.thunderbolt.Logger;
  56. import flash.display.DisplayObject;
  57. import flash.display.DisplayObjectContainer;
  58. import flash.display.Sprite;
  59. import flash.events.Event;
  60. import flash.events.KeyboardEvent;
  61. import flash.events.MouseEvent;
  62. import flash.events.TimerEvent;
  63. import flash.net.URLRequest;
  64. import flash.net.navigateToURL;
  65. import flash.system.Capabilities;
  66. import flash.system.Security;
  67. import flash.text.TextField;
  68. import flash.text.TextFieldAutoSize;
  69. import flash.ui.Keyboard;
  70. import flash.utils.Dictionary;
  71. import flash.utils.Timer;
  72. use namespace flow_internal;
  73. public class Launcher extends StyleableSprite implements ErrorHandler {
  74. private var _panel:Panel;
  75. private var _screen:Screen;
  76. private var _config:Config;
  77. private var _flowplayer:Flowplayer;
  78. private var _pluginRegistry:PluginRegistry;
  79. private var _animationEngine:AnimationEngine;
  80. private var _playButtonOverlay:PlayButtonOverlay;
  81. private var _controlsModel:DisplayPluginModel;
  82. private var _providers:Dictionary = new Dictionary();
  83. private var _fullscreenManager:FullscreenManager;
  84. private var _canvasLogo:Sprite;
  85. private var _pluginLoader:PluginLoader;
  86. private var _error:TextField;
  87. private var _pluginsInitialized:Number = 0;
  88. private var _numLoadablePlugins:int = -1;
  89. private var _enteringFullscreen:Boolean;
  90. private var _copyrightNotice:TextField;
  91. private var _playlistLoader:ResourceLoader;
  92. [Frame(factoryClass="org.flowplayer.view.Preloader")]
  93. public function Launcher() {
  94. super("#canvas", this);
  95. addEventListener(Event.ADDED_TO_STAGE, initPhase1);
  96. }
  97. private function initPhase1(event:Event):void {
  98. createFlashVarsConfig();
  99. Log.configure(_config.getLogConfiguration());
  100. initCustomClipEvents();
  101. if (_config.playerId) {
  102. Security.allowDomain(URLUtil.pageUrl);
  103. }
  104. loader = createNewLoader();
  105. rootStyle = _config.canvas.style;
  106. stage.addEventListener(Event.RESIZE, onStageResize);
  107. setSize(stage.stageWidth, stage.stageHeight);
  108. if (! VersionInfo.commercial) {
  109. log.debug("Adding logo to canvas");
  110. createLogoForCanvas();
  111. }
  112. log = new Log(this);
  113. EventDispatcher.playerId = _config.playerId;
  114. log.debug("security sandbox type: " + Security.sandboxType);
  115. log.info(VersionInfo.versionInfo());
  116. log.debug("creating Panel");
  117. createPanel();
  118. _pluginRegistry = new PluginRegistry(_panel);
  119. log.debug("Creating animation engine");
  120. createAnimationEngine(_pluginRegistry);
  121. log.debug("creating play button overlay");
  122. createPlayButtonOverlay();
  123. log.debug("creating Flowplayer API");
  124. createFlowplayer();
  125. loadPlaylistFeed();
  126. }
  127. private function initPhase2(event:Event = null):void {
  128. log.info("initPhase2");
  129. loadPlugins();
  130. }
  131. private function initPhase3(event:Event = null):void {
  132. log.debug("initPhase3, all plugins loaded");
  133. createScreen();
  134. _pluginLoader.removeEventListener(Event.COMPLETE, this.initPhase3);
  135. _config.getPlaylist().onBeforeBegin(function(event:ClipEvent):void { hideErrorMessage(); });
  136. if (_playButtonOverlay) {
  137. PlayButtonOverlayView(_playButtonOverlay.getDisplayObject()).playlist = _config.getPlaylist();
  138. }
  139. log.debug("creating PlayListController");
  140. _providers = _pluginLoader.providers;
  141. var playListController:PlayListController = createPlayListController();
  142. addPlayListListeners();
  143. createFullscreenManager(playListController.playlist);
  144. addScreenToPanel();
  145. if (!validateLicenseKey()) {
  146. createLogoForCanvas();
  147. resizeCanvasLogo();
  148. }
  149. log.debug("creating logo");
  150. createLogo();
  151. contextMenu = new ContextMenuBuilder(_config.playerId, _config.contextMenu).build();
  152. log.debug("initializing ExternalInterface");
  153. if (useExternalInterfade()) {
  154. _flowplayer.initExternalInterface();
  155. }
  156. log.debug("calling onLoad to plugins");
  157. _pluginRegistry.onLoad(_flowplayer);
  158. }
  159. private function initPhase4(event:Event = null):void {
  160. log.info("initPhase4, all plugins initialized");
  161. log.debug("Adding visible plugins to panel");
  162. addPluginsToPanel(_pluginRegistry);
  163. log.debug("arranging screen");
  164. arrangeScreen();
  165. log.debug("dispatching onLoad");
  166. if (useExternalInterfade()) {
  167. _flowplayer.dispatchEvent(PlayerEvent.load("player"));
  168. }
  169. log.debug("starting configured streams");
  170. startStreams();
  171. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
  172. addListeners();
  173. }
  174. private function resizeCanvasLogo():void {
  175. _canvasLogo.alpha = 1;
  176. _canvasLogo.width = 150;
  177. _canvasLogo.scaleY = _canvasLogo.scaleX;
  178. arrangeCanvasLogo();
  179. }
  180. private function useExternalInterfade():Boolean {
  181. log.debug("useExternalInteface: " + (_config.playerId != null));
  182. return _config.playerId != null;
  183. }
  184. private function onStageResize(event:Event = null):void {
  185. setSize(stage.stageWidth, stage.stageHeight);
  186. arrangeCanvasLogo();
  187. }
  188. private function arrangeCanvasLogo():void {
  189. if (!_canvasLogo) return;
  190. _canvasLogo.x = 15;
  191. _canvasLogo.y = stage.stageHeight - (_controlsModel ? _controlsModel.dimensions.height.toPx(stage.stageHeight) + 10 : 10) - _canvasLogo.height - _copyrightNotice.height;
  192. _copyrightNotice.x = 12;
  193. _copyrightNotice.y = _canvasLogo.y + _canvasLogo.height;
  194. }
  195. private function loadPlugins():void {
  196. var plugins:Array = _config.getLoadables();
  197. log.info("will load following plugins: ");
  198. for (var i:Number = 0; i < plugins.length; i++) {
  199. log.info("" + plugins[i]);
  200. }
  201. _pluginLoader = new PluginLoader(URLUtil.playerBaseUrl(loaderInfo), _pluginRegistry, this, useExternalInterfade(), onPluginLoad, onPluginLoadError);
  202. _pluginLoader.addEventListener(Event.COMPLETE, initPhase3);
  203. _flowplayer.pluginLoader = _pluginLoader;
  204. if (plugins.length == 0) {
  205. log.debug("configuration has no plugins");
  206. initPhase3();
  207. } else {
  208. log.debug("loading plugins and providers");
  209. _pluginLoader.load(plugins);
  210. }
  211. }
  212. private function loadPlaylistFeed():void {
  213. var playlistFeed:String = _config.playlistFeed;
  214. if (! playlistFeed) {
  215. initPhase2();
  216. return;
  217. }
  218. log.info("loading playlist from " + playlistFeed);
  219. _playlistLoader = _flowplayer.createLoader();
  220. _playlistLoader.addTextResourceUrl(playlistFeed);
  221. _playlistLoader.load(null,
  222. function(loader:ResourceLoader):void {
  223. log.info("received playlist feed");
  224. _config.playlistDocument = loader.getContent() as String;
  225. initPhase2();
  226. });
  227. }
  228. private function onPluginLoad(event:PluginEvent):void {
  229. var plugin:PluginModel = event.target as PluginModel;
  230. log.info("plugin " + plugin + " initialized");
  231. checkPluginsInitialized();
  232. }
  233. private function onPluginLoadError(event:PluginEvent):void {
  234. if (! event.hasError(PluginError.INIT_FAILED)) return;
  235. var plugin:PluginModel = event.target as PluginModel;
  236. log.warn("load/init error on " + plugin);
  237. _pluginRegistry.removePlugin(plugin);
  238. checkPluginsInitialized();
  239. }
  240. private function checkPluginsInitialized():void {
  241. var numPlugins:int = countLoadablePlugins();
  242. if (++_pluginsInitialized == numPlugins) {
  243. log.info("all plugins initialized");
  244. initPhase4();
  245. }
  246. log.info(_pluginsInitialized + " out of " + numPlugins + " plugins initialized");
  247. }
  248. private function countLoadablePlugins():int {
  249. var count:Number = 0;
  250. var loadables:Array = _config.getLoadables();
  251. for (var i:Number = 0; i < loadables.length; i++) {
  252. var plugin:PluginModel = Loadable(loadables[i]).plugin;
  253. if (! plugin) {
  254. throw new Error("Plugin " + loadables[i] + " not available");
  255. }
  256. var isNonAdHocPlugin:Boolean = plugin.pluginObject is Plugin;
  257. // var isNonAdHocPlugin:Boolean = (plugin is DisplayPluginModel && DisplayPluginModel(plugin).getDisplayObject() is Plugin) ||
  258. // plugin is ProviderModel && ProviderModel(plugin).pluginObject is Plugin;
  259. if (Loadable(loadables[i]).loadFailed) {
  260. log.debug("load failed for " + loadables[i]);
  261. count++;
  262. } else if (! plugin) {
  263. log.debug("this plugin is not loaded yet");
  264. count++;
  265. } else if (isNonAdHocPlugin) {
  266. log.debug("will wait for onLoad from plugin " + plugin);
  267. count++;
  268. } else {
  269. log.debug("will NOT wait for onLoad from plugin " + Loadable(loadables[i]).plugin);
  270. }
  271. }
  272. // +1 comes from the playbuttonoverlay
  273. return count + (_playButtonOverlay ? 1 : 0);
  274. }
  275. private function playerSwfName():String {
  276. var url:String = loaderInfo.url;
  277. var lastSlash:Number = url.lastIndexOf("/");
  278. return url.substring(lastSlash + 1, url.indexOf(".swf") + 4);
  279. }
  280. private function validateLicenseKey():Boolean {
  281. try {
  282. return LicenseKey.validate(root.loaderInfo.url, _flowplayer.version, _config.licenseKey, useExternalInterfade());
  283. } catch (e:Error) {
  284. log.warn("License key not accepted, will show flowplayer logo");
  285. }
  286. return false;
  287. }
  288. private function createFullscreenManager(playlist:Playlist):void {
  289. _fullscreenManager = new FullscreenManager(stage, playlist, _panel, _pluginRegistry, _animationEngine);
  290. _flowplayer.fullscreenManager = _fullscreenManager;
  291. }
  292. public function showError(message:String):void {
  293. if (! _panel) return;
  294. if (! _config.showErrors) return;
  295. if (_error && _error.parent == this) {
  296. removeChild(_error);
  297. }
  298. _error = TextUtil.createTextField(false);
  299. _error.background = true;
  300. _error.backgroundColor = 0;
  301. _error.textColor = 0xffffff;
  302. _error.autoSize = TextFieldAutoSize.CENTER;
  303. _error.multiline = true;
  304. _error.wordWrap = true;
  305. _error.text = message;
  306. _error.selectable = true;
  307. _error.width = stage.stageWidth - 40;
  308. Arrange.center(_error, stage.stageWidth, stage.stageHeight);
  309. addChild(_error);
  310. createErrorMessageHideTimer();
  311. }
  312. private function createErrorMessageHideTimer():void {
  313. var errorHideTimer:Timer = new Timer(4000, 1);
  314. errorHideTimer.addEventListener(TimerEvent.TIMER_COMPLETE, hideErrorMessage);
  315. errorHideTimer.start();
  316. }
  317. private function hideErrorMessage(event:TimerEvent = null):void {
  318. if (_error && _error.parent == this) {
  319. if (_animationEngine) {
  320. _animationEngine.fadeOut(_error, 1000, function():void { removeChild(_error); });
  321. } else {
  322. removeChild(_error);
  323. }
  324. }
  325. }
  326. public function handleError(error:PlayerError, info:Object = null, throwError:Boolean = true):void {
  327. if (_flowplayer) {
  328. _flowplayer.dispatchError(error, info);
  329. } else {
  330. // initialization is not complete, create a dispatches just to dispatch this error
  331. new PlayerEventDispatcher().dispatchError(error, info);
  332. }
  333. doHandleError(error.code + ": " + error.message + ( info ? ": " + info : ""), throwError);
  334. }
  335. private function doHandleError(message:String, throwError:Boolean = true):void {
  336. if (_config && _config.playerId) {
  337. Logger.error(message);
  338. }
  339. showError(message);
  340. if (throwError && Capabilities.isDebugger) {
  341. throw new Error(message);
  342. }
  343. }
  344. private function createAnimationEngine(pluginRegistry:PluginRegistry):void {
  345. _animationEngine = new AnimationEngine(_panel, pluginRegistry);
  346. }
  347. private function addPluginsToPanel(_pluginRegistry:PluginRegistry):void {
  348. for each (var pluginObj:Object in _pluginRegistry.plugins) {
  349. if (pluginObj is DisplayPluginModel) {
  350. var model:DisplayPluginModel = pluginObj as DisplayPluginModel;
  351. log.debug("adding plugin '"+ model.name +"' to panel: " + model.visible + ", plugin object is " + model.getDisplayObject());
  352. if (model.visible) {
  353. if (model.zIndex == -1) {
  354. model.zIndex = 100;
  355. }
  356. _panel.addView(model.getDisplayObject(), undefined, model);
  357. }
  358. if (model.name == "controls") {
  359. _controlsModel = model;
  360. }
  361. }
  362. }
  363. if (_controlsModel) {
  364. arrangeCanvasLogo();
  365. }
  366. }
  367. private function addScreenToPanel():void {
  368. // if controls visible and screen was not explicitly configured --> place screen on top of controls
  369. var screen:DisplayProperties = _pluginRegistry.getPlugin("screen") as DisplayProperties;
  370. screen.display = "none";
  371. screen.getDisplayObject().visible = false;
  372. _panel.addView(screen.getDisplayObject(), null, screen);
  373. }
  374. private function arrangeScreen():void {
  375. var screen:DisplayProperties = _pluginRegistry.getPlugin("screen") as DisplayProperties;
  376. if (_controlsModel && _controlsModel.visible) {
  377. if (isControlsAlwaysAutoHide() || (_controlsModel.position.bottom.px > 0)) {
  378. log.debug("controls is autoHide or it's in a non-default vertical position, configuring screen to take all available space");
  379. setScreenBottomAndHeight(screen, 100, 0);
  380. } else {
  381. var controlsHeight:Number = _controlsModel.getDisplayObject().height;
  382. var occupiedHeight:Number = screenTopOrBottomConfigured() ? getScreenTopOrBottomPx(screen) : controlsHeight;
  383. log.debug("occupied by controls or screen's configured bottom/top is " + occupiedHeight);
  384. var heightPct:Number = 0;
  385. if (screenTopOrBottomConfigured() && (screen.position.top.pct >= 0 || screen.position.bottom.pct >= 0)) {
  386. heightPct = 100 - Math.abs(50 - (screen.position.top.pct >= 0 ? screen.position.top.pct : screen.position.bottom.pct))*2;
  387. setScreenBottomAndHeight(screen, heightPct, controlsHeight);
  388. } else {
  389. heightPct = ((stage.stageHeight - occupiedHeight) / stage.stageHeight) * 100;
  390. setScreenBottomAndHeight(screen, heightPct, controlsHeight);
  391. }
  392. }
  393. }
  394. log.debug("arranging screen to pos " + screen.position);
  395. screen.display = "block";
  396. screen.getDisplayObject().visible = true;
  397. _pluginRegistry.updateDisplayProperties(screen);
  398. _panel.update(screen.getDisplayObject(), screen);
  399. _panel.draw(screen.getDisplayObject());
  400. }
  401. private function getScreenTopOrBottomPx(screen:DisplayProperties):Number {
  402. var screenConf:Object = _config.getObject("screen");
  403. if (screenConf.hasOwnProperty("top")) return screen.position.top.toPx(stage.stageHeight);
  404. if (screenConf.hasOwnProperty("bottom")) return screen.position.bottom.toPx(stage.stageHeight);
  405. return 0;
  406. }
  407. private function setScreenBottomAndHeight(screen:DisplayProperties, heightPct:Number, bottom:Number = 0):void {
  408. if (! screenTopOrBottomConfigured()) {
  409. log.debug("screen vertical pos not configured, setting bottom to value " + bottom);
  410. screen.bottom = bottom;
  411. } else {
  412. log.debug("using configured top/bottom for screen");
  413. }
  414. var heightConfigured:Boolean = _config.getObject("screen") && _config.getObject("screen").hasOwnProperty("height");
  415. if (! heightConfigured) {
  416. log.debug("screen height not configured, setting it to value " + heightPct + "%");
  417. screen.height = heightPct + "%";
  418. } else {
  419. log.debug("using configured height for screen");
  420. }
  421. }
  422. private function screenTopOrBottomConfigured():Boolean {
  423. var screen:Object = _config.getObject("screen");
  424. if (! screen) return false;
  425. if (screen.hasOwnProperty("top")) return true;
  426. if (screen.hasOwnProperty("bottom")) return true;
  427. return false;
  428. }
  429. private function isControlsAlwaysAutoHide():Boolean {
  430. if (!_controlsModel) return false;
  431. if (!_controlsModel.config) return false;
  432. log.debug("controlsModel.config.auotoHide == always", (_controlsModel.config.autoHide == 'always'));
  433. return _controlsModel.config.autoHide == 'always';
  434. }
  435. private function createFlowplayer():void {
  436. _flowplayer = new Flowplayer(stage, _pluginRegistry, _panel,
  437. _animationEngine, this, this, _config, URLUtil.playerBaseUrl(loaderInfo));
  438. _flowplayer.onBeforeFullscreen(onFullscreen);
  439. // _flowplayer.onFullscreenExit(onFullscreen);
  440. }
  441. private function onFullscreen(event:PlayerEvent):void {
  442. log.debug("entering fullscreen, disabling display clicks");
  443. _enteringFullscreen = true;
  444. var delay:Timer = new Timer(1000, 1);
  445. delay.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
  446. delay.start();
  447. }
  448. private function onTimerComplete(event:TimerEvent):void {
  449. log.debug("fullscreen wait delay complete, display clicks are enabled again");
  450. _enteringFullscreen = false;
  451. }
  452. private function createFlashVarsConfig():void {
  453. for (var prop:String in stage.loaderInfo.parameters) {
  454. log.debug(prop + ": " + (stage.loaderInfo.parameters[prop]));
  455. }
  456. if (! stage.loaderInfo.parameters) {
  457. return;
  458. }
  459. _config = ConfigLoader.flow_internal::parseConfig(stage.loaderInfo.parameters["config"], playerSwfName(), VersionInfo.controlsVersion, VersionInfo.audioVersion);
  460. }
  461. private function createPlayListController():PlayListController {
  462. if (! _providers) {
  463. _providers = new Dictionary();
  464. }
  465. var httpProvider:ProviderModel = _config.getHttpProvider();
  466. _providers["http"] = httpProvider.pluginObject;
  467. _pluginRegistry.registerProvider(httpProvider);
  468. var playListController:PlayListController = new PlayListController(_config.getPlaylist(), _providers, _config, createNewLoader());
  469. playListController.playerEventDispatcher = _flowplayer;
  470. _flowplayer.playlistController = playListController;
  471. return playListController;
  472. }
  473. private function createScreen():void {
  474. _screen = new Screen(_config.getPlaylist(), _animationEngine, _playButtonOverlay, _pluginRegistry);
  475. var screenModel:DisplayProperties = _config.getScreenProperties();
  476. initView(_screen, screenModel, null, false);
  477. if (_playButtonOverlay) {
  478. PlayButtonOverlayView(_playButtonOverlay.getDisplayObject()).setScreen(_screen, hasClip);
  479. }
  480. // addViewLiteners(_screen);
  481. }
  482. private function createPlayButtonOverlay():void {
  483. _playButtonOverlay = _config.getPlayButtonOverlay();
  484. if (! _playButtonOverlay) return;
  485. _playButtonOverlay.onLoad(onPluginLoad);
  486. _playButtonOverlay.onError(onPluginLoadError);
  487. var overlay:PlayButtonOverlayView = new PlayButtonOverlayView(! playButtonOverlayWidthDefined(), _playButtonOverlay, _pluginRegistry);
  488. initView(overlay, _playButtonOverlay, null, false);
  489. }
  490. private function playButtonOverlayWidthDefined():Boolean {
  491. if (! _config.getObject("play")) return false;
  492. return _config.getObject("play").hasOwnProperty("width");
  493. }
  494. private function get hasClip():Boolean {
  495. var firstClip:Clip = _config.getPlaylist().current;
  496. var hasClip:Boolean = ! firstClip.isNullClip && (firstClip.url || firstClip.provider != 'http');
  497. return hasClip;
  498. }
  499. private function createLogo():void {
  500. var logo:Logo = _config.getLogo() || new Logo();
  501. var logoView:LogoView = new LogoView(_panel, logo, _flowplayer);
  502. initView(logoView, logo, logoView.draw, false);
  503. }
  504. private function initView(view:DisplayObject, props:DisplayProperties, resizeListener:Function = null, addToPanel:Boolean = true):void {
  505. if (props.name != "logo" || VersionInfo.commercial) {
  506. _pluginRegistry.registerDisplayPlugin(props, view);
  507. }
  508. if (addToPanel) {
  509. _panel.addView(view, resizeListener, props);
  510. }
  511. if (props is Callable) {
  512. ExternalInterfaceHelper.initializeInterface(props as Callable, view);
  513. }
  514. }
  515. private function addListeners():void {
  516. _screen.addEventListener(MouseEvent.CLICK, onViewClicked);
  517. if (_playButtonOverlay) {
  518. _playButtonOverlay.getDisplayObject().addEventListener(MouseEvent.CLICK, onViewClicked);
  519. }
  520. addEventListener(MouseEvent.ROLL_OVER, onMouseOver);
  521. addEventListener(MouseEvent.ROLL_OUT, onMouseOut);
  522. // add some color so that the ROLL_OVER/ROLL_OUT events are always triggered
  523. graphics.beginFill(0, 0);
  524. graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
  525. graphics.endFill();
  526. }
  527. private function onMouseOut(event:MouseEvent):void {
  528. _flowplayer.dispatchEvent(PlayerEvent.mouseOut());
  529. }
  530. private function onMouseOver(event:MouseEvent):void {
  531. _flowplayer.dispatchEvent(PlayerEvent.mouseOver());
  532. }
  533. private function createPanel():void {
  534. _panel = new Panel();
  535. addChild(_panel);
  536. }
  537. private function startStreams():void {
  538. var canStart:Boolean = true;
  539. if (_flowplayer.state != State.WAITING) {
  540. log.debug("streams have been started in player.onLoad(), will not start streams here.");
  541. canStart = false;
  542. }
  543. if (! hasClip) {
  544. log.info("Configuration has no clips to play.");
  545. canStart = false;
  546. }
  547. var playButton:PlayButtonOverlayView = _playButtonOverlay ? PlayButtonOverlayView(_playButtonOverlay.getDisplayObject()) : null;
  548. if (canStart) {
  549. if (_flowplayer.currentClip.autoPlay) {
  550. log.debug("clip is autoPlay");
  551. _flowplayer.play();
  552. } else if (_flowplayer.currentClip.autoBuffering) {
  553. log.debug("clip is autoBuffering");
  554. _flowplayer.startBuffering();
  555. } else {
  556. if (playButton) {
  557. playButton.stopBuffering();
  558. playButton.showButton();
  559. }
  560. }
  561. } else {
  562. // cannot start playing here, stop buffering indicator, don't show the button
  563. if (playButton) {
  564. playButton.stopBuffering();
  565. }
  566. }
  567. }
  568. private function addPlayListListeners():void {
  569. var playlist:Playlist = _config.getPlaylist();
  570. playlist.onError(onClipError);
  571. }
  572. private function onClipError(event:ClipEvent):void {
  573. if (event.isDefaultPrevented()) return;
  574. doHandleError(event.info + ", " + event.info2 + ", " + event.info3 + ", clip: '" + Clip(event.target) + "'");
  575. }
  576. private function onViewClicked(event:MouseEvent):void {
  577. if (_enteringFullscreen) return;
  578. log.debug("onViewClicked, target " + event.target + ", current target " + event.currentTarget);
  579. if (_playButtonOverlay && isParent(DisplayObject(event.target), _playButtonOverlay.getDisplayObject())) {
  580. _flowplayer.toggle();
  581. } else if (isParent(DisplayObject(event.target), _screen)) {
  582. log.debug("screen clicked");
  583. var clip:Clip = _flowplayer.playlist.current;
  584. if (clip.linkUrl) {
  585. log.debug("opening linked page");
  586. _flowplayer.pause();
  587. navigateToURL(new URLRequest(clip.linkUrl), clip.linkWindow);
  588. return;
  589. }
  590. _flowplayer.toggle();
  591. }
  592. event.stopPropagation();
  593. }
  594. private function isParent(child:DisplayObject, parent:DisplayObject):Boolean {
  595. try {
  596. if (DisplayObject(child).parent == parent) return true;
  597. if (! (parent is DisplayObjectContainer)) return false;
  598. for (var i:Number = 0;i < DisplayObjectContainer(parent).numChildren; i++) {
  599. var curChild:DisplayObject = DisplayObjectContainer(parent).getChildAt(i);
  600. if (isParent(child, curChild)) {
  601. return true;
  602. }
  603. }
  604. } catch (e:SecurityError) {
  605. return true;
  606. }
  607. return false;
  608. }
  609. private function onKeyDown(event:KeyboardEvent):void {
  610. log.debug("keydown");
  611. if (_enteringFullscreen) return;
  612. if (_flowplayer.dispatchBeforeEvent(PlayerEvent.keyPress(event.keyCode))) {
  613. _flowplayer.dispatchEvent(PlayerEvent.keyPress(event.keyCode));
  614. if (event.keyCode == Keyboard.SPACE) {
  615. _flowplayer.toggle();
  616. }
  617. }
  618. }
  619. override protected function onRedraw():void {
  620. if (bgImageHolder && getChildIndex(bgImageHolder) > getChildIndex(_panel)) {
  621. swapChildren(bgImageHolder, _panel);
  622. }
  623. }
  624. private function createLogoForCanvas():void {
  625. if (_canvasLogo) return;
  626. _copyrightNotice = LogoUtil.createCopyrightNotice(8);
  627. addChild(_copyrightNotice);
  628. _canvasLogo = new CanvasLogo();
  629. _canvasLogo.width = 85;
  630. _canvasLogo.scaleY = _canvasLogo.scaleX;
  631. _canvasLogo.alpha = .4;
  632. _canvasLogo.addEventListener(MouseEvent.CLICK,
  633. function(event:MouseEvent):void { navigateToURL(new URLRequest("http://flowplayer.org"), "_self"); });
  634. _canvasLogo.buttonMode = true;
  635. log.debug("adding logo to display list");
  636. addChild(_canvasLogo);
  637. onStageResize();
  638. }
  639. private function createNewLoader():ResourceLoader {
  640. return new ResourceLoaderImpl(_config.playerId ? null : URLUtil.playerBaseUrl(loaderInfo), this);
  641. }
  642. private function initCustomClipEvents():void {
  643. createCustomClipEvents(_config.connectionCallbacks);
  644. createCustomClipEvents(_config.streamCallbacks);
  645. }
  646. private function createCustomClipEvents(callbacks:Array):void {
  647. if (! callbacks) return;
  648. for (var i:int = 0; i < callbacks.length; i++) {
  649. log.debug("creating custom event type " + callbacks[i]);
  650. new ClipEventType(callbacks[i], true);
  651. }
  652. }
  653. }
  654. }