PageRenderTime 46ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/com/becarella/ustream/UStreamPlane.as

https://github.com/becarella/ustream_cube
ActionScript | 247 lines | 134 code | 42 blank | 71 comment | 18 complexity | 707713eecb776effb0142fad6c2d53c6 MD5 | raw file
  1. /**
  2. * Copyright 2009 Becky Carella
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.becarella.ustream {
  17. import flash.display.DisplayObject;
  18. import flash.display.Loader;
  19. import flash.display.Sprite;
  20. import flash.events.*;
  21. import flash.net.URLRequest;
  22. import flash.utils.getTimer;
  23. import flash.system.Security;
  24. import flash.text.TextField;
  25. import flash.text.TextFormat;
  26. /**
  27. * A plane for the UStreamCube that shows a UStream channel
  28. * and the video's title.
  29. *
  30. * UStream viewer built on the UStream Flash API
  31. * See: http://developer.ustream.tv/external/flash/index.html
  32. */
  33. public class UStreamPlane extends Sprite {
  34. private var loader:Loader
  35. private var viewer:*; // tv.ustream.viewer.logic.Logic
  36. private var _channel:String; // channel to play
  37. private var _playing:Boolean = false;
  38. private var online:Boolean = false;
  39. private var label:TextField = new TextField();
  40. private var size:int;
  41. private var lastClickTime:int = 0;
  42. /**
  43. * Create a new plane with the given size and play the given channel
  44. *
  45. * @param width and height of the plane
  46. * @param channel id (optional)
  47. * @param loader with ustream rsl preloaded (optional)
  48. */
  49. public function UStreamPlane(size:int, channel:String = null, loader:Loader = null) {
  50. // we have to allow the logic loaded from ustream.tv
  51. // to access the stage and loaderInfo
  52. Security.allowDomain('*');
  53. this.size = size;
  54. this.channel = channel;
  55. this.loader = loader;
  56. _playing = false;
  57. fillBackground();
  58. initLabel();
  59. // Next, create a Loader object, and set up a listener
  60. // to watch the loader progress
  61. if (!loader) {
  62. loader = new Loader();
  63. loader.contentLoaderInfo.addEventListener("complete", onComplete);
  64. loader.load(new URLRequest('http://www.ustream.tv/flash/viewer.rsl.swf'));
  65. } else {
  66. onComplete();
  67. }
  68. }
  69. /**
  70. * Set the channel and start playback if possible.
  71. * The channel consists of a brand id and channel code
  72. * The brand id (integer) and the channel code (string) is concatenated
  73. * with a slash character, like: 49/test
  74. *
  75. * If using a UStream channel, you can skip the brand id and slash.
  76. */
  77. public function set channel(value:String) : void {
  78. _channel = value;
  79. if (viewer) {
  80. try {
  81. viewer.createChannel(_channel, false);
  82. } catch (e:Error) {
  83. trace("[UStreamPlane] error: " + e);
  84. }
  85. }
  86. }
  87. /**
  88. * Play or pause the stream
  89. */
  90. public function set playing(value:Boolean) : void {
  91. _playing = value;
  92. if (viewer && viewer.playing == _playing) { return; }
  93. if (viewer) {
  94. viewer.playing = _playing;
  95. }
  96. updateLabel();
  97. }
  98. /**
  99. * RSL loaded. Setup the viewer.
  100. */
  101. private function onComplete(event:Event = null) : void {
  102. loader.contentLoaderInfo.removeEventListener("complete", onComplete);
  103. // After we made sure that all the required classes are loaded
  104. // from the logic SWF we can initiate the Logic class.
  105. var Viewer:Class = loader.contentLoaderInfo.applicationDomain.getDefinition('tv.ustream.viewer.logic.Logic') as Class;
  106. viewer = new Viewer();
  107. playing = _playing;
  108. Viewer.debug = false;
  109. viewer.display.width = size;
  110. viewer.display.height = size;
  111. viewer.display.x = -size/2;
  112. viewer.display.y = -size/2;
  113. viewer.addEventListener("createChannel", onCreateChannel);
  114. //viewer.display.doubleClickEnabled = true;
  115. viewer.display.addEventListener(MouseEvent.DOUBLE_CLICK, onDoubleClick); // not working, why??
  116. viewer.display.addEventListener(MouseEvent.CLICK, onClick); // use a click event to fake doubleClick for now
  117. addChild(viewer.display);
  118. if (_channel) {
  119. channel = _channel;
  120. }
  121. }
  122. private function onCreateChannel(event:Event) : void {
  123. viewer.removeEventListener("createChannel", onCreateChannel);
  124. viewer.channel.addEventListener("offline", onOffline);
  125. viewer.channel.addEventListener("online", onOnline);
  126. viewer.channel.addEventListener("data", onData);
  127. updateLabel();
  128. }
  129. private function onData(event:Event) : void {
  130. viewer.channel.removeEventListener("data", onData);
  131. updateLabel();
  132. }
  133. private function onOffline(event:Event) : void {
  134. online = false;
  135. updateLabel();
  136. }
  137. private function onOnline(event:Event) : void {
  138. online = true;
  139. updateLabel();
  140. }
  141. /**
  142. * User double clicked on the UStream video, relay the event
  143. *
  144. * NOTE: this is never called, but I'm not sure why. I've
  145. * implemented a fake doubleClick event in the onClick handler
  146. * until I get a proper doubleClick working
  147. */
  148. private function onDoubleClick(event:MouseEvent) : void {
  149. dispatchEvent(event);
  150. }
  151. /**
  152. * Fake a MouseEvent.DOUBLE_CLICK by looking for two
  153. * click events that are less than a second apart.
  154. */
  155. private function onClick(event:MouseEvent) : void {
  156. var clickTime:int = getTimer();
  157. if (clickTime - lastClickTime < 300) {
  158. dispatchEvent(new Event(MouseEvent.DOUBLE_CLICK));
  159. }
  160. lastClickTime = clickTime;
  161. }
  162. /**
  163. * Fill the square plane with a background color
  164. */
  165. private function fillBackground() : void {
  166. graphics.lineStyle(2.0, 0xCCCCCC);
  167. graphics.beginFill(0x000000, 1);
  168. graphics.drawRect(-size/2,-size/2,size,size);
  169. graphics.endFill();
  170. }
  171. /**
  172. * Initialize the label show in the upper right corner
  173. */
  174. private function initLabel() : void {
  175. label.x = -size/2 + 5;
  176. label.y = -size/2 + 5;
  177. label.width = size - 10;
  178. label.selectable = false;
  179. label.mouseEnabled = false;
  180. var format:TextFormat = new TextFormat();
  181. format.font = "Verdana";
  182. format.color = 0xFFFFFF;
  183. format.size = 16;
  184. label.defaultTextFormat = format;
  185. updateLabel();
  186. addChild(label);
  187. }
  188. /**
  189. * Update the label to show the current playback
  190. * state: playing, paused, or offline
  191. */
  192. private function updateLabel() : void {
  193. if (!online && (viewer && viewer.recorded && !viewer.recorded.playing)) {
  194. label.text = "Offline";
  195. } else if (_playing) {
  196. label.text = "Playing";
  197. } else {
  198. label.text = "Paused";
  199. }
  200. if (viewer && viewer.channel) {
  201. label.appendText(" - " + viewer.channel.title);
  202. }
  203. }
  204. }
  205. }