PageRenderTime 56ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/qosmonitor/src/actionscript/org/flowplayer/qosmonitor/QosmonitorProvider.as

https://github.com/longlho/flowplayer
ActionScript | 383 lines | 249 code | 111 blank | 23 comment | 10 complexity | abd689ad1690514005ca30fc6b874e93 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. /*
  2. * This file is part of Flowplayer, http://flowplayer.org
  3. *
  4. * By: Daniel Rossi <electroteque@gmail.com>, Anssi Piirainen <api@iki.fi> Flowplayer Oy
  5. * Copyright (c) 2009, 2010 Electroteque Multimedia, Flowplayer Oy
  6. *
  7. * Released under the MIT License:
  8. * http://www.opensource.org/licenses/mit-license.php
  9. */
  10. package org.flowplayer.qosmonitor {
  11. import org.flowplayer.model.Plugin;
  12. import org.flowplayer.model.PluginModel;
  13. import org.flowplayer.model.ClipEvent;
  14. import org.flowplayer.util.PropertyBinder;
  15. import org.flowplayer.view.Flowplayer;
  16. import org.flowplayer.model.Clip;
  17. import org.flowplayer.model.DisplayProperties;
  18. import org.flowplayer.view.StyleableSprite;
  19. import org.flowplayer.net.BitrateItem;
  20. import flash.events.TimerEvent;
  21. import flash.text.TextField;
  22. import flash.text.TextFieldAutoSize;
  23. import flash.text.AntiAliasType;
  24. import flash.display.Sprite;
  25. import flash.utils.Timer;
  26. import flash.net.NetStream;
  27. import org.flowplayer.qosmonitor.config.Config;
  28. public class QosmonitorProvider extends StyleableSprite implements Plugin {
  29. private var _config:Config;
  30. private var _model:PluginModel;
  31. private var _player:Flowplayer;
  32. private var _statsTimer:Timer;
  33. private var _netStream:NetStream;
  34. private var _clip:Clip;
  35. private var _metrics:Object;
  36. private var _bwcheck:Object;
  37. private var _bandwidthLabel:TextField;
  38. private var _bandwidthStats:TextField;
  39. private var _bufferLengthLabel:TextField;
  40. private var _bufferLengthStats:TextField;
  41. private var _droppedFramesLabel:TextField;
  42. private var _droppedFramesStats:TextField;
  43. private var _bitrateItemLabel:TextField;
  44. private var _bitrateItemStats:TextField;
  45. private var _avgBandwidthLabel:TextField;
  46. private var _avgBandwidthStats:TextField;
  47. private var _avgDroppedFramesLabel:TextField;
  48. private var _avgDroppedFramesStats:TextField;
  49. private var _avgFramesLabel:TextField;
  50. private var _avgFramesStats:TextField;
  51. private var _statsContainer:Sprite;
  52. private var _bandwidthContainer:Sprite;
  53. private var _bufferLengthContainer:Sprite;
  54. private var _droppedFramesContainer:Sprite;
  55. private var _bitrateItemContainer:Sprite;
  56. private var _avgBandwidthContainer:Sprite;
  57. private var _avgDroppedFramesContainer:Sprite;
  58. private var _avgFramesContainer:Sprite;
  59. private const PADDING_X:int = 10;
  60. private const MARGIN_TOP:int = 10;
  61. private const PADDING_Y:int = 3;
  62. public function onConfig(model:PluginModel):void {
  63. _model = model;
  64. _config = new PropertyBinder(new Config(), null).copyProperties(model.config) as Config;
  65. this.rootStyle = _config.canvas;
  66. }
  67. private function applyForClip(clip:Clip):Boolean {
  68. return "rtmp httpstreaming".indexOf(_player.streamProvider.type) >= 0;
  69. }
  70. public function onLoad(player:Flowplayer):void {
  71. _player = player;
  72. log.info("onLoad()");
  73. //#500 get the metrics from the bwcheck plugin.
  74. var plugin:DisplayProperties = _player.pluginRegistry.getPlugin("bwcheck") as DisplayProperties;
  75. _bwcheck = Object(plugin.getDisplayObject());
  76. createStatsView();
  77. _statsTimer = new Timer(_config.interval);
  78. _statsTimer.addEventListener(TimerEvent.TIMER, updateStats);
  79. _player.playlist.onSwitch(function(event:ClipEvent):void {
  80. updateBitrateItemStats();
  81. });
  82. _player.playlist.onSwitchFailed(function(event:ClipEvent):void {
  83. updateBitrateItemStats();
  84. });
  85. _player.playlist.onSwitchComplete(function(event:ClipEvent):void {
  86. updateBitrateItemStats();
  87. });
  88. _player.playlist.onStart(function(event:ClipEvent):void {
  89. _netStream = _player.streamProvider.netStream;
  90. _clip = _player.playlist.current;
  91. _statsTimer.start();
  92. updateBitrateItemStats();
  93. },applyForClip);
  94. _player.playlist.onFinish(function(event:ClipEvent):void {
  95. _statsTimer.stop();
  96. });
  97. _player.playlist.onPause(function(event:ClipEvent):void {
  98. _statsTimer.stop();
  99. });
  100. _player.playlist.onResume(function(event:ClipEvent):void {
  101. _statsTimer.start();
  102. });
  103. _model.dispatchOnLoad();
  104. }
  105. private function updateStatsText(text:TextField, info:String):void {
  106. text.htmlText = "<span class=\"stats\">" + info + "</span>";
  107. }
  108. private function updateBandwidthStats():void {
  109. if (!_config.stats.bandwidth) return;
  110. updateStatsText(_bandwidthStats,
  111. formatBytes(_netStream.info.maxBytesPerSecond) +
  112. " - " + formatBytes(_netStream.info.playbackBytesPerSecond)
  113. );
  114. }
  115. private function updateBufferStats():void {
  116. if (!_config.stats.buffer) return;
  117. updateStatsText(_bufferLengthStats,Math.round(_netStream.bufferLength) + "");
  118. }
  119. private function updateDroppedFramesStats():void {
  120. if (!_config.stats.frames) return;
  121. updateStatsText(_droppedFramesStats,
  122. _netStream.info.droppedFrames + ""
  123. );
  124. }
  125. private function updateBitrateItemStats():void {
  126. if (!_config.stats.bitrate) return;
  127. if (!_clip.getCustomProperty("streamSelectionManager")) return;
  128. var bitrateItem:BitrateItem = BitrateItem(_clip.getCustomProperty("streamSelectionManager").currentBitrateItem);
  129. updateStatsText(_bitrateItemStats,
  130. bitrateItem.bitrate + " kbps (" + bitrateItem.index + "," + bitrateItem.width +"px)"
  131. );
  132. }
  133. private function updateMetrics():void {
  134. if (!_config.stats.metrics) return;
  135. //#500 get the metrics from the bwcheck plugin.
  136. if (!_metrics && !_bwcheck) return;
  137. if (!_metrics) _metrics = _bwcheck.netStreamMetrics;
  138. updateStatsText(_avgBandwidthStats, formatBytes(_metrics.averageMaxBytesPerSecond) + "");
  139. updateStatsText(_avgDroppedFramesStats, Math.round(_metrics.averageDroppedFPS) + "");
  140. updateStatsText(_avgFramesStats, Math.round(_metrics.droppedFPS) + "");
  141. }
  142. private function updateStats(event:TimerEvent):void
  143. {
  144. updateBandwidthStats();
  145. updateBufferStats();
  146. updateDroppedFramesStats();
  147. updateMetrics();
  148. if (_config.info) log.debug("NetStreamInfo - " + _netStream.info);
  149. }
  150. private function formatBytes(value:Number):Number {
  151. return Math.round(value * 8 / 1024);
  152. }
  153. protected function createField():TextField {
  154. var field:TextField = _player.createTextField();
  155. field.selectable = false;
  156. field.focusRect = false;
  157. field.tabEnabled = false;
  158. field.autoSize = TextFieldAutoSize.LEFT;
  159. field.antiAliasType = AntiAliasType.ADVANCED;
  160. field.height = 15;
  161. field.styleSheet = style.styleSheet;
  162. return field;
  163. }
  164. protected function createLabelField(value:String):TextField {
  165. var field:TextField = createField();
  166. field.htmlText = "<span class=\"label\">" + value + ":</span>";
  167. return field;
  168. }
  169. protected function createStatsField():TextField {
  170. var field:TextField = createField();
  171. return field;
  172. }
  173. private function createStatsView():void {
  174. _statsContainer = new Sprite();
  175. addChild(_statsContainer);
  176. //setup netstream stats
  177. //bandidth stats
  178. _bandwidthContainer = new Sprite();
  179. _bandwidthLabel = createLabelField("Bandwidth (kbps)");
  180. _bandwidthContainer.addChild(_bandwidthLabel);
  181. _bandwidthStats = createStatsField();
  182. _bandwidthContainer.addChild(_bandwidthStats);
  183. _bandwidthStats.x = _bandwidthLabel.textWidth + 5;
  184. _statsContainer.addChild(_bandwidthContainer);
  185. //buffer stats
  186. _bufferLengthContainer = new Sprite();
  187. _bufferLengthLabel = createLabelField("Buffer Length (seconds)");
  188. _bufferLengthContainer.addChild(_bufferLengthLabel);
  189. _bufferLengthStats = createStatsField();
  190. _bufferLengthContainer.addChild(_bufferLengthStats);
  191. _bufferLengthStats.x = _bufferLengthLabel.textWidth + 5;
  192. _statsContainer.addChild(_bufferLengthContainer);
  193. //dropped frame stats
  194. _droppedFramesContainer = new Sprite();
  195. _droppedFramesLabel = createLabelField("Dropped Frames");
  196. _droppedFramesContainer.addChild(_droppedFramesLabel);
  197. _droppedFramesStats = createStatsField();
  198. _droppedFramesContainer.addChild(_droppedFramesStats);
  199. _droppedFramesStats.x = _droppedFramesLabel.textWidth + 5;
  200. _statsContainer.addChild(_droppedFramesContainer);
  201. //bitrate item stats
  202. _bitrateItemContainer = new Sprite();
  203. _bitrateItemLabel = createLabelField("Current Bitrate");
  204. _bitrateItemContainer.addChild(_bitrateItemLabel);
  205. _bitrateItemStats = createStatsField();
  206. _bitrateItemContainer.addChild(_bitrateItemStats);
  207. _bitrateItemStats.x = _bitrateItemLabel.textWidth + 5;
  208. _statsContainer.addChild(_bitrateItemContainer);
  209. //setup metrics based stats
  210. //average bandwidth stats
  211. _avgBandwidthContainer = new Sprite();
  212. _avgBandwidthLabel = createLabelField("Avg Bandwidth (kbps)");
  213. _avgBandwidthContainer.addChild(_avgBandwidthLabel);
  214. _avgBandwidthStats = createStatsField();
  215. _avgBandwidthContainer.addChild(_avgBandwidthStats);
  216. _avgBandwidthStats.x = _avgBandwidthLabel.x + _avgBandwidthLabel.textWidth + 5;
  217. _statsContainer.addChild(_avgBandwidthContainer);
  218. //average dropped frames stats
  219. _avgDroppedFramesContainer = new Sprite();
  220. _avgDroppedFramesLabel = createLabelField("Avg Dropped Frames");
  221. _avgDroppedFramesContainer.addChild(_avgDroppedFramesLabel);
  222. _avgDroppedFramesStats = createStatsField();
  223. _avgDroppedFramesContainer.addChild(_avgDroppedFramesStats);
  224. _avgDroppedFramesStats.x = _avgDroppedFramesLabel.x + _avgDroppedFramesLabel.textWidth + 5;
  225. _statsContainer.addChild(_avgDroppedFramesContainer);
  226. //metrics calculated frames stats
  227. _avgFramesContainer = new Sprite();
  228. _avgFramesLabel = createLabelField("Avg Frames");
  229. _avgFramesContainer.addChild(_avgFramesLabel);
  230. _avgFramesStats = createStatsField();
  231. _avgFramesContainer.addChild(_avgFramesStats);
  232. _avgFramesStats.x = _avgFramesLabel.x + _avgFramesLabel.textWidth + 5;
  233. _statsContainer.addChild(_avgFramesContainer);
  234. arrangeStatsView();
  235. }
  236. private function arrangeStatsView():void {
  237. //setup standard netstream stats
  238. _bandwidthContainer.x = PADDING_X;
  239. _bandwidthContainer.y = MARGIN_TOP;
  240. _bufferLengthContainer.x = PADDING_X;
  241. _bufferLengthContainer.y = _bandwidthContainer.y + _bandwidthContainer.height + (PADDING_Y * 2);
  242. _droppedFramesContainer.x = PADDING_X;
  243. _droppedFramesContainer.y = _bufferLengthContainer.y + _bufferLengthContainer.height + (PADDING_Y * 2);
  244. _bitrateItemContainer.x = PADDING_X;
  245. _bitrateItemContainer.y = _droppedFramesContainer.y + _droppedFramesContainer.height + (PADDING_Y * 2);
  246. //setup metrics stats
  247. _avgBandwidthContainer.x = this.width / 2;
  248. _avgBandwidthContainer.y = MARGIN_TOP;
  249. _avgDroppedFramesContainer.x = this.width / 2;
  250. _avgDroppedFramesContainer.y = _avgBandwidthContainer.y + _avgBandwidthContainer.height + (PADDING_Y * 2);
  251. _avgFramesContainer.x = this.width / 2;
  252. _avgFramesContainer.y = _avgDroppedFramesContainer.y + _avgDroppedFramesContainer.height + (PADDING_Y * 2);
  253. }
  254. override protected function onResize():void {
  255. log.debug("onResize " + width + " x " + height);
  256. arrangeStatsView();
  257. }
  258. //implements
  259. public function getDefaultConfig():Object {
  260. return {
  261. top: "0",
  262. left: "2",
  263. background: "#000000",
  264. opacity: 0.8,
  265. borderRadius: 0,
  266. border: 'none',
  267. width: "100%",
  268. height: "50%"
  269. };
  270. }
  271. }
  272. }