PageRenderTime 65ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/flowplayer/branches/3_1_3_dev/src/actionscript/org/flowplayer/view/Flowplayer.as

http://flowplayer-core.googlecode.com/
ActionScript | 331 lines | 266 code | 33 blank | 32 comment | 44 complexity | 9e4ecc869a242abdf3c6f882fa05e8ee 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.model.ClipEvent;
  21. import org.flowplayer.model.PlayerError;
  22. import org.flowplayer.controller.ResourceLoader;
  23. import org.flowplayer.config.Config;
  24. import org.flowplayer.config.ExternalInterfaceHelper;
  25. import org.flowplayer.controller.PlayListController;
  26. import org.flowplayer.flow_internal;
  27. import org.flowplayer.model.Callable;
  28. import org.flowplayer.model.Clip;
  29. import org.flowplayer.model.ClipEventType;
  30. import org.flowplayer.model.DisplayPluginModel;
  31. import org.flowplayer.model.DisplayProperties;
  32. import org.flowplayer.model.DisplayPropertiesImpl;
  33. import org.flowplayer.model.Loadable;
  34. import org.flowplayer.model.Playlist;
  35. import org.flowplayer.model.Plugin;
  36. import org.flowplayer.model.PluginEvent;
  37. import org.flowplayer.model.PluginEventType;
  38. import org.flowplayer.model.PluginModel;
  39. import org.flowplayer.model.Status;
  40. import org.flowplayer.util.NumberUtil;
  41. import org.flowplayer.util.ObjectConverter;
  42. import org.flowplayer.util.PropertyBinder;
  43. import org.flowplayer.view.FlowplayerBase;
  44. import org.flowplayer.view.Styleable;
  45. import flash.display.Stage;
  46. import flash.external.ExternalInterface;
  47. use namespace flow_internal;
  48. /**
  49. * @author api
  50. */
  51. public class Flowplayer extends FlowplayerBase {
  52. private var _canvas:StyleableSprite;
  53. public function Flowplayer(
  54. stage:Stage,
  55. pluginRegistry:PluginRegistry,
  56. panel:Panel,
  57. animationEngine:AnimationEngine,
  58. canvas:StyleableSprite,
  59. errorHandler:ErrorHandler,
  60. config:Config,
  61. playerSWFBaseURl:String) {
  62. super(stage, pluginRegistry, panel, animationEngine, errorHandler, config, playerSWFBaseURl);
  63. _canvas = canvas;
  64. }
  65. public function initExternalInterface():void {
  66. if (!ExternalInterface.available)
  67. log.info("ExternalInteface is not available in this runtime. JavaScript access will be disabled.");
  68. try {
  69. addCallback("getVersion", function():Array { return version; });
  70. addCallback("getPlaylist", function():Array { return convert(playlist.clips) as Array; });
  71. addCallback("getId", function():String { return id; });
  72. addCallback("play", genericPlay);
  73. addCallback("startBuffering", function():void { startBuffering(); });
  74. addCallback("stopBuffering", function():void { stopBuffering(); } );
  75. addCallback("isFullscreen", isFullscreen);
  76. addCallback("toggleFullscreen", toggleFullscreen);
  77. addCallback("toggle", toggle);
  78. addCallback("getState", function():Number { return state.code; });
  79. addCallback("getStatus", function():Object { return convert(status); });
  80. addCallback("isPlaying", isPlaying);
  81. addCallback("isPaused", isPaused);
  82. var wrapper:WrapperForIE = new WrapperForIE(this);
  83. addCallback("stop", wrapper.fp_stop );
  84. addCallback("pause", wrapper.fp_pause );
  85. addCallback("resume", wrapper.fp_resume );
  86. addCallback("close", wrapper.fp_close );
  87. addCallback("getTime", function():Number { return status.time; });
  88. addCallback("mute", function():void { muted = true; });
  89. addCallback("unmute", function():void { muted = false; });
  90. addCallback("isMuted", function():Boolean { return muted; });
  91. addCallback("setVolume", function(value:Number):void { volume = value; });
  92. addCallback("getVolume", function():Number { return volume; });
  93. addCallback("seek", genericSeek);
  94. addCallback("getCurrentClip", function():Object {
  95. return new ObjectConverter(currentClip).convert(); });
  96. addCallback("getClip", function(index:Number):Object { return convert(playlist.getClip(index)); });
  97. addCallback("setPlaylist", function(clipObjects:Array):void { setPlaylist(_config.createClips(clipObjects)); });
  98. addCallback("addClip", function(clip:Object, index:int = -1):void { addClip(_config.createClip(clip), index); });
  99. addCallback("showError", showError);
  100. addCallback("loadPlugin", pluginLoad);
  101. addCallback("showPlugin", showPlugin);
  102. addCallback("hidePlugin", hidePlugin);
  103. addCallback("togglePlugin", togglePlugin);
  104. addCallback("animate", animate);
  105. addCallback("css", css);
  106. // return;
  107. addCallback("reset", reset);
  108. addCallback("fadeIn", fadeIn);
  109. addCallback("fadeOut", fadeOut);
  110. addCallback("fadeTo", fadeTo);
  111. addCallback("getPlugin", function(pluginName:String):Object {
  112. return new ObjectConverter(_pluginRegistry.getPlugin(pluginName)).convert();
  113. });
  114. addCallback("getRawPlugin", function(pluginName:String):Object {
  115. return _pluginRegistry.getPlugin(pluginName);
  116. });
  117. addCallback("invoke", invoke);
  118. addCallback("addCuepoints", addCuepoints);
  119. addCallback("updateClip", updateClip);
  120. addCallback("logging", logging);
  121. } catch (e:Error) {
  122. handleError(PlayerError.INIT_FAILED, "Unable to add callback to ExternalInterface");
  123. }
  124. }
  125. private function pluginLoad(name:String, url:String, properties:Object = null, callbackId:String = null):void {
  126. var loadable:Loadable = new Loadable(name, _config, url);
  127. if (properties) {
  128. new PropertyBinder(loadable, "config").copyProperties(properties);
  129. }
  130. loadPluginLoadable(loadable, callbackId != null ? createCallback(callbackId) : null);
  131. }
  132. private static function addCallback(methodName:String, func:Function):void {
  133. ExternalInterfaceHelper.addCallback("fp_" + methodName, func);
  134. }
  135. private function genericPlay(param:Object = null, instream:Boolean = false):void {
  136. if (param == null) {
  137. play();
  138. return;
  139. }
  140. if (param is Number) {
  141. _playListController.play(null, param as Number);
  142. return;
  143. }
  144. if (param is Array) {
  145. _playListController.playClips(_config.createClips(param as Array));
  146. return;
  147. }
  148. var clip:Clip = _config.createClip(param);
  149. if (! clip) {
  150. showError("cannot convert " + param + " to a clip");
  151. return;
  152. }
  153. if (instream) {
  154. playInstream(clip);
  155. return;
  156. }
  157. play(clip);
  158. }
  159. private function genericSeek(target:Object):void {
  160. var percentage:Number = target is String ? NumberUtil.decodePercentage(target as String) : NaN;
  161. if (isNaN(percentage)) {
  162. seek(target is String ? parseInt(target as String) : target as Number);
  163. } else {
  164. seekRelative(percentage);
  165. }
  166. }
  167. private function css(pluginName:String, props:Object = null):Object {
  168. log.debug("css, plugin " + pluginName);
  169. if (pluginName == "canvas") {
  170. _canvas.css(props);
  171. return props;
  172. }
  173. return style(pluginName, props, false, 0);
  174. }
  175. private function convert(objToConvert:Object):Object {
  176. return new ObjectConverter(objToConvert).convert();
  177. }
  178. private function collectDisplayProps(props:Object, animatable:Boolean):Object {
  179. var result:Object = new Object();
  180. var coreDisplayProps:Array = [ "width", "height", "left", "top", "bottom", "right", "opacity" ];
  181. if (!animatable) {
  182. coreDisplayProps = coreDisplayProps.concat("display", "zIndex");
  183. }
  184. for (var propName:String in props) {
  185. if (coreDisplayProps.indexOf(propName) >= 0) {
  186. result[propName] = props[propName];
  187. // delete props[propName];
  188. }
  189. }
  190. return result;
  191. }
  192. private function animate(pluginName:String, props:Object, durationMillis:Number = 400, listenerId:String = null):Object {
  193. return style(pluginName, props, true, durationMillis, listenerId);
  194. }
  195. private function style(pluginName:String, props:Object, animate:Boolean, durationMillis:Number = 400, listenerId:String = null):Object {
  196. var plugin:Object = _pluginRegistry.getPlugin(pluginName);
  197. checkPlugin(plugin, pluginName, DisplayPluginModel);
  198. log.debug("going to animate plugin " + pluginName);
  199. var result:Object;
  200. if (props) {
  201. if (pluginName == 'play') {
  202. result = convert(_animationEngine.animateNonPanel(DisplayProperties(_pluginRegistry.getPlugin("screen")).getDisplayObject(), DisplayProperties(plugin).getDisplayObject(), collectDisplayProps(props, animate), durationMillis, createCallback(listenerId, plugin)));
  203. } else {
  204. result = convert(_animationEngine.animate(DisplayProperties(plugin).getDisplayObject(), collectDisplayProps(props, animate), durationMillis, createCallback(listenerId, plugin)));
  205. }
  206. } else {
  207. result = convert(plugin);
  208. }
  209. // check if plugin is Styleable and delegate to it
  210. if (plugin is DisplayProperties && DisplayProperties(plugin).getDisplayObject() is Styleable) {
  211. var newPluginProps:Object = Styleable(DisplayProperties(plugin).getDisplayObject())[animate ? "animate" : "css"](props);
  212. for (var prop:String in newPluginProps) {
  213. result[prop] = newPluginProps[prop];
  214. }
  215. }
  216. return result;
  217. }
  218. private function fadeOut(pluginName:String, durationMillis:Number = 400, listenerId:String = null):void {
  219. var props:DisplayProperties = prepareFade(pluginName, false);
  220. _animationEngine.fadeOut(props.getDisplayObject(), durationMillis, createCallback(listenerId, props));
  221. }
  222. private function fadeIn(pluginName:String, durationMillis:Number = 400, listenerId:String = null):void {
  223. var props:DisplayProperties = prepareFade(pluginName, true);
  224. if (pluginName == "play") {
  225. Screen(screen.getDisplayObject()).showPlay();
  226. }
  227. _animationEngine.fadeIn(props.getDisplayObject(), durationMillis, createCallback(listenerId, props), pluginName != "play");
  228. }
  229. private function fadeTo(pluginName:String, alpha:Number, durationMillis:Number = 400, listenerId:String = null):void {
  230. var props:DisplayProperties = prepareFade(pluginName, true);
  231. if (pluginName == "play") {
  232. Screen(screen.getDisplayObject()).showPlay();
  233. }
  234. _animationEngine.fadeTo(props.getDisplayObject(), alpha, durationMillis, createCallback(listenerId, props), pluginName != "play");
  235. }
  236. private function prepareFade(pluginName:String, show:Boolean):DisplayProperties {
  237. var plugin:Object = _pluginRegistry.getPlugin(pluginName);
  238. checkPlugin(plugin, pluginName, DisplayProperties);
  239. if (show) {
  240. var props:DisplayProperties = plugin as DisplayProperties;
  241. if (! props.getDisplayObject().parent || props.getDisplayObject().parent != _panel) {
  242. props.alpha = 0;
  243. }
  244. doShowPlugin(props.getDisplayObject(), props);
  245. }
  246. return plugin as DisplayProperties;
  247. }
  248. private function invoke(pluginName:String, methodName:String, args:Object = null):Object {
  249. var plugin:Callable = _pluginRegistry.getPlugin(pluginName) as Callable;
  250. checkPlugin(plugin, pluginName, Callable);
  251. try {
  252. log.debug("invoke()");
  253. if (plugin.getMethod(methodName).hasReturnValue) {
  254. log.debug("method has a return value");
  255. return plugin.invokeMethod(methodName, args is Array ? args as Array : [ args ]);
  256. } else {
  257. log.debug("method does not have a return value");
  258. plugin.invokeMethod(methodName, args is Array ? args as Array : [ args ]);
  259. }
  260. } catch (e:Error) {
  261. throw e;
  262. // handleError(PlayerError.PLUGIN_INVOKE_FAILED, "Error when invoking method '" + methodName + "', on plugin '" + pluginName + "'");
  263. }
  264. return "undefined";
  265. }
  266. private function addCuepoints(cuepoints:Array, clipIndex:int, callbackId:String):void {
  267. var clip:Clip = _playListController.playlist.getClip(clipIndex);
  268. var points:Array = _config.createCuepoints(cuepoints, callbackId, 1);
  269. if (! points || points.length == 0) {
  270. showError("unable to create cuepoints from " + cuepoints);
  271. }
  272. clip.addCuepoints(points);
  273. log.debug("clip has now cuepoints " + clip.cuepoints);
  274. }
  275. private function updateClip(clipObj:Object, clipIndex:int):void {
  276. var clip:Clip = _playListController.playlist.getClip(clipIndex);
  277. new PropertyBinder(clip, "customProperties").copyProperties(clipObj);
  278. clip.dispatch(ClipEventType.UPDATE);
  279. }
  280. //
  281. // private function createCallback(listenerId:String):Function {
  282. // if (! listenerId) return null;
  283. // return function():void {
  284. // new PluginEvent(PluginEventType.PLUGIN_EVENT, listenerId).fireExternal(_playerId);
  285. // };
  286. // }
  287. private function createCallback(listenerId:String, pluginArg:Object = null):Function {
  288. if (! listenerId) return null;
  289. return function(plugin:PluginModel = null):void {
  290. if (plugin || pluginArg is PluginModel) {
  291. PluginModel(pluginArg || plugin).dispatch(PluginEventType.PLUGIN_EVENT, listenerId);
  292. } else {
  293. new PluginEvent(PluginEventType.PLUGIN_EVENT, pluginArg is DisplayProperties ? DisplayProperties(pluginArg).name : pluginArg.toString(), listenerId).fireExternal(_playerId);
  294. }
  295. };
  296. }
  297. }
  298. }