正在显示
7 个修改的文件
包含
387 行增加
和
119 行删除
| @@ -12,6 +12,9 @@ | @@ -12,6 +12,9 @@ | ||
| 12 | margin-top: -20px; | 12 | margin-top: -20px; |
| 13 | padding-top: 3px; | 13 | padding-top: 3px; |
| 14 | } | 14 | } |
| 15 | + #main_modal { | ||
| 16 | + margin-top: -60px; | ||
| 17 | + } | ||
| 15 | .div_play_time { | 18 | .div_play_time { |
| 16 | margin-top: 10px; | 19 | margin-top: 10px; |
| 17 | } | 20 | } |
| @@ -378,15 +381,13 @@ | @@ -378,15 +381,13 @@ | ||
| 378 | </div> | 381 | </div> |
| 379 | </div> | 382 | </div> |
| 380 | <div style="margin-top:-12px;"> | 383 | <div style="margin-top:-12px;"> |
| 384 | + <span id="debug_info"></span> | ||
| 381 | URL: <a href="#" id="player_url"></a> | 385 | URL: <a href="#" id="player_url"></a> |
| 382 | <div class="input-prepend div_play_time" title="当前时间:年-月-日 时:分:秒"> | 386 | <div class="input-prepend div_play_time" title="当前时间:年-月-日 时:分:秒"> |
| 383 | <span class="add-on">@N</span> | 387 | <span class="add-on">@N</span> |
| 384 | <input class="span2" style="width:135px" id="player_clock" type="text" placeholder="年-月-日 时:分:秒"> | 388 | <input class="span2" style="width:135px" id="player_clock" type="text" placeholder="年-月-日 时:分:秒"> |
| 385 | </div> | 389 | </div> |
| 386 | </div> | 390 | </div> |
| 387 | - <div> | ||
| 388 | - <span id="debug_info"></span> | ||
| 389 | - </div> | ||
| 390 | </div> | 391 | </div> |
| 391 | </div> | 392 | </div> |
| 392 | <footer> | 393 | <footer> |
| @@ -496,6 +497,7 @@ | @@ -496,6 +497,7 @@ | ||
| 496 | } | 497 | } |
| 497 | 498 | ||
| 498 | $("#div_container").remove(); | 499 | $("#div_container").remove(); |
| 500 | + $("#debug_info").text(""); | ||
| 499 | 501 | ||
| 500 | var div_container = $("<div/>"); | 502 | var div_container = $("<div/>"); |
| 501 | $(div_container).attr("id", "div_container"); | 503 | $(div_container).attr("id", "div_container"); |
| @@ -513,7 +515,7 @@ | @@ -513,7 +515,7 @@ | ||
| 513 | srs_player.on_player_metadata = function(metadata) { | 515 | srs_player.on_player_metadata = function(metadata) { |
| 514 | $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")"); | 516 | $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")"); |
| 515 | if (metadata.ip && metadata.pid && metadata.cid) { | 517 | if (metadata.ip && metadata.pid && metadata.cid) { |
| 516 | - $("#debug_info").text("DEBUG: " + metadata.ip + ' grep -in "\\[' + metadata.pid + '\\]\\[' + metadata.cid + '\\]"'); | 518 | + $("#debug_info").text("ID:" + metadata.ip + '/' + metadata.pid + '/' + metadata.cid + ''); |
| 517 | } | 519 | } |
| 518 | select_dar("#btn_dar_original", 0, 0); | 520 | select_dar("#btn_dar_original", 0, 0); |
| 519 | select_fs_size("#btn_fs_size_screen_100", "screen", 100); | 521 | select_fs_size("#btn_fs_size_screen_100", "screen", 100); |
| 1 | +package | ||
| 2 | +{ | ||
| 3 | + import flash.display.Sprite; | ||
| 4 | + import flash.display.StageAlign; | ||
| 5 | + import flash.display.StageDisplayState; | ||
| 6 | + import flash.display.StageScaleMode; | ||
| 7 | + import flash.events.Event; | ||
| 8 | + import flash.events.FullScreenEvent; | ||
| 9 | + import flash.events.MouseEvent; | ||
| 10 | + import flash.events.NetStatusEvent; | ||
| 11 | + import flash.events.TimerEvent; | ||
| 12 | + import flash.external.ExternalInterface; | ||
| 13 | + import flash.media.SoundTransform; | ||
| 14 | + import flash.media.Video; | ||
| 15 | + import flash.net.NetConnection; | ||
| 16 | + import flash.net.NetStream; | ||
| 17 | + import flash.system.Security; | ||
| 18 | + import flash.ui.ContextMenu; | ||
| 19 | + import flash.ui.ContextMenuItem; | ||
| 20 | + import flash.utils.Timer; | ||
| 21 | + import flash.utils.getTimer; | ||
| 22 | + import flash.utils.setTimeout; | ||
| 23 | + | ||
| 24 | + import flashx.textLayout.formats.Float; | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * common player to play rtmp/flv stream, | ||
| 28 | + * use system NetStream. | ||
| 29 | + */ | ||
| 30 | + public class CommonPlayer implements IPlayer | ||
| 31 | + { | ||
| 32 | + private var js_id:String = null; | ||
| 33 | + | ||
| 34 | + // play param url. | ||
| 35 | + private var user_url:String = null; | ||
| 36 | + | ||
| 37 | + private var media_stream:NetStream = null; | ||
| 38 | + private var media_conn:NetConnection = null; | ||
| 39 | + | ||
| 40 | + private var owner:srs_player = null; | ||
| 41 | + | ||
| 42 | + public function CommonPlayer(o:srs_player) { | ||
| 43 | + owner = o; | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + public function init(flashvars:Object):void { | ||
| 47 | + this.js_id = flashvars.id; | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + public function stream():NetStream { | ||
| 51 | + return this.media_stream; | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + public function play(url:String):void { | ||
| 55 | + var streamName:String; | ||
| 56 | + this.user_url = url; | ||
| 57 | + | ||
| 58 | + this.media_conn = new NetConnection(); | ||
| 59 | + this.media_conn.client = {}; | ||
| 60 | + this.media_conn.client.onBWDone = function():void {}; | ||
| 61 | + this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | ||
| 62 | + log("NetConnection: code=" + evt.info.code); | ||
| 63 | + | ||
| 64 | + if (evt.info.hasOwnProperty("data") && evt.info.data) { | ||
| 65 | + owner.on_player_metadata(evt.info.data); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + // reject by server, maybe redirect. | ||
| 69 | + if (evt.info.code == "NetConnection.Connect.Rejected") { | ||
| 70 | + // RTMP 302 redirect. | ||
| 71 | + if (evt.info.hasOwnProperty("ex") && evt.info.ex.code == 302) { | ||
| 72 | + streamName = url.substr(url.lastIndexOf("/") + 1); | ||
| 73 | + url = evt.info.ex.redirect + "/" + streamName; | ||
| 74 | + log("Async RTMP 302 Redirect to: " + url); | ||
| 75 | + | ||
| 76 | + // notify server. | ||
| 77 | + media_conn.call("Redirected", null, evt.info.ex.redirect); | ||
| 78 | + | ||
| 79 | + // do 302. | ||
| 80 | + owner.on_player_302(url); | ||
| 81 | + return; | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + // TODO: FIXME: failed event. | ||
| 86 | + if (evt.info.code != "NetConnection.Connect.Success") { | ||
| 87 | + return; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + media_stream = new NetStream(media_conn); | ||
| 91 | + media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | ||
| 92 | + log("NetStream: code=" + evt.info.code); | ||
| 93 | + | ||
| 94 | + if (evt.info.code == "NetStream.Video.DimensionChange") { | ||
| 95 | + owner.on_player_dimension_change(); | ||
| 96 | + } else if (evt.info.code == "NetStream.Buffer.Empty") { | ||
| 97 | + owner.on_player_buffer_empty(); | ||
| 98 | + } else if (evt.info.code == "NetStream.Buffer.Full") { | ||
| 99 | + owner.on_player_buffer_full(); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + // TODO: FIXME: failed event. | ||
| 103 | + }); | ||
| 104 | + | ||
| 105 | + // setup stream before play. | ||
| 106 | + owner.on_player_before_play(); | ||
| 107 | + | ||
| 108 | + if (url.indexOf("http") == 0) { | ||
| 109 | + media_stream.play(url); | ||
| 110 | + } else { | ||
| 111 | + streamName = url.substr(url.lastIndexOf("/") + 1); | ||
| 112 | + media_stream.play(streamName); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + owner.on_player_play(); | ||
| 116 | + }); | ||
| 117 | + | ||
| 118 | + if (url.indexOf("http") == 0) { | ||
| 119 | + this.media_conn.connect(null); | ||
| 120 | + } else { | ||
| 121 | + var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/")); | ||
| 122 | + this.media_conn.connect(tcUrl); | ||
| 123 | + } | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + public function close():void { | ||
| 127 | + if (this.media_stream) { | ||
| 128 | + this.media_stream.close(); | ||
| 129 | + this.media_stream = null; | ||
| 130 | + } | ||
| 131 | + if (this.media_conn) { | ||
| 132 | + this.media_conn.close(); | ||
| 133 | + this.media_conn = null; | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + private function log(msg:String):void { | ||
| 138 | + Utility.log(js_id, msg); | ||
| 139 | + } | ||
| 140 | + } | ||
| 141 | +} |
| 1 | +package | ||
| 2 | +{ | ||
| 3 | + import flash.net.NetStream; | ||
| 4 | + | ||
| 5 | + /** | ||
| 6 | + * the player interface. | ||
| 7 | + */ | ||
| 8 | + public interface IPlayer | ||
| 9 | + { | ||
| 10 | + /** | ||
| 11 | + * initialize the player by flashvars for config. | ||
| 12 | + * @param flashvars the config. | ||
| 13 | + */ | ||
| 14 | + function init(flashvars:Object):void; | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * get the NetStream to play the stream. | ||
| 18 | + * @return the underlayer stream object. | ||
| 19 | + */ | ||
| 20 | + function stream():NetStream; | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * connect and play url. | ||
| 24 | + * @param url the stream url to play. | ||
| 25 | + */ | ||
| 26 | + function play(url:String):void; | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * close the player. | ||
| 30 | + */ | ||
| 31 | + function close():void; | ||
| 32 | + } | ||
| 33 | +} |
| 1 | +package | ||
| 2 | +{ | ||
| 3 | + import flash.display.Sprite; | ||
| 4 | + import flash.display.StageAlign; | ||
| 5 | + import flash.display.StageDisplayState; | ||
| 6 | + import flash.display.StageScaleMode; | ||
| 7 | + import flash.events.Event; | ||
| 8 | + import flash.events.FullScreenEvent; | ||
| 9 | + import flash.events.MouseEvent; | ||
| 10 | + import flash.events.NetStatusEvent; | ||
| 11 | + import flash.events.TimerEvent; | ||
| 12 | + import flash.external.ExternalInterface; | ||
| 13 | + import flash.media.SoundTransform; | ||
| 14 | + import flash.media.Video; | ||
| 15 | + import flash.net.NetConnection; | ||
| 16 | + import flash.net.NetStream; | ||
| 17 | + import flash.system.Security; | ||
| 18 | + import flash.ui.ContextMenu; | ||
| 19 | + import flash.ui.ContextMenuItem; | ||
| 20 | + import flash.utils.Timer; | ||
| 21 | + import flash.utils.getTimer; | ||
| 22 | + import flash.utils.setTimeout; | ||
| 23 | + | ||
| 24 | + import flashx.textLayout.formats.Float; | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * the m3u8 player. | ||
| 28 | + */ | ||
| 29 | + public class M3u8Player implements IPlayer | ||
| 30 | + { | ||
| 31 | + private var js_id:String = null; | ||
| 32 | + | ||
| 33 | + // play param url. | ||
| 34 | + private var user_url:String = null; | ||
| 35 | + | ||
| 36 | + private var media_stream:NetStream = null; | ||
| 37 | + private var media_conn:NetConnection = null; | ||
| 38 | + | ||
| 39 | + private var owner:srs_player = null; | ||
| 40 | + | ||
| 41 | + public function M3u8Player(o:srs_player) { | ||
| 42 | + owner = o; | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + public function init(flashvars:Object):void { | ||
| 46 | + this.js_id = flashvars.id; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + public function stream():NetStream { | ||
| 50 | + return this.media_stream; | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + public function play(url:String):void { | ||
| 54 | + this.user_url = url; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + public function close():void { | ||
| 58 | + if (this.media_stream) { | ||
| 59 | + this.media_stream.close(); | ||
| 60 | + this.media_stream = null; | ||
| 61 | + } | ||
| 62 | + if (this.media_conn) { | ||
| 63 | + this.media_conn.close(); | ||
| 64 | + this.media_conn = null; | ||
| 65 | + } | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + private function log(msg:String):void { | ||
| 69 | + Utility.log(js_id, msg); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | +} |
| 1 | +package | ||
| 2 | +{ | ||
| 3 | + import flash.external.ExternalInterface; | ||
| 4 | + import flash.utils.setTimeout; | ||
| 5 | + | ||
| 6 | + /** | ||
| 7 | + * the utility functions. | ||
| 8 | + */ | ||
| 9 | + public class Utility | ||
| 10 | + { | ||
| 11 | + /** | ||
| 12 | + * initialize the player by flashvars for config. | ||
| 13 | + * @param flashvars the config. | ||
| 14 | + */ | ||
| 15 | + public static function stringEndswith(s:String, f:String):Boolean { | ||
| 16 | + return s && f && s.indexOf(f) == s.length - f.length; | ||
| 17 | + } | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * write log to trace and console.log. | ||
| 21 | + * @param msg the log message. | ||
| 22 | + */ | ||
| 23 | + public static function log(js_id:String, msg:String):void { | ||
| 24 | + msg = "[" + new Date() +"][srs-player][" + js_id + "] " + msg; | ||
| 25 | + | ||
| 26 | + trace(msg); | ||
| 27 | + | ||
| 28 | + if (!flash.external.ExternalInterface.available) { | ||
| 29 | + flash.utils.setTimeout(log, 300, msg); | ||
| 30 | + return; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + ExternalInterface.call("console.log", msg); | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | +} |
| @@ -33,12 +33,13 @@ package | @@ -33,12 +33,13 @@ package | ||
| 33 | private var js_on_player_timer:String = null; | 33 | private var js_on_player_timer:String = null; |
| 34 | private var js_on_player_empty:String = null; | 34 | private var js_on_player_empty:String = null; |
| 35 | private var js_on_player_full:String = null; | 35 | private var js_on_player_full:String = null; |
| 36 | - | ||
| 37 | - // play param url. | ||
| 38 | - private var user_url:String = null; | 36 | + |
| 39 | // play param, user set width and height | 37 | // play param, user set width and height |
| 40 | private var user_w:int = 0; | 38 | private var user_w:int = 0; |
| 41 | private var user_h:int = 0; | 39 | private var user_h:int = 0; |
| 40 | + private var user_buffer_time:Number = 0; | ||
| 41 | + private var user_max_buffer_time:Number = 0; | ||
| 42 | + private var user_volume:Number = 0; | ||
| 42 | // user set dar den:num | 43 | // user set dar den:num |
| 43 | private var user_dar_den:int = 0; | 44 | private var user_dar_den:int = 0; |
| 44 | private var user_dar_num:int = 0; | 45 | private var user_dar_num:int = 0; |
| @@ -47,8 +48,6 @@ package | @@ -47,8 +48,6 @@ package | ||
| 47 | private var user_fs_percent:int = 0; | 48 | private var user_fs_percent:int = 0; |
| 48 | 49 | ||
| 49 | // media specified. | 50 | // media specified. |
| 50 | - private var media_conn:NetConnection = null; | ||
| 51 | - private var media_stream:NetStream = null; | ||
| 52 | private var media_video:Video = null; | 51 | private var media_video:Video = null; |
| 53 | private var media_metadata:Object = {}; | 52 | private var media_metadata:Object = {}; |
| 54 | private var media_timer:Timer = new Timer(300); | 53 | private var media_timer:Timer = new Timer(300); |
| @@ -57,6 +56,11 @@ package | @@ -57,6 +56,11 @@ package | ||
| 57 | // flash donot allow js to set to fullscreen, | 56 | // flash donot allow js to set to fullscreen, |
| 58 | // only allow user click to enter fullscreen. | 57 | // only allow user click to enter fullscreen. |
| 59 | private var control_fs_mask:Sprite = new Sprite(); | 58 | private var control_fs_mask:Sprite = new Sprite(); |
| 59 | + | ||
| 60 | + // the common player to play stream. | ||
| 61 | + private var player:IPlayer = null; | ||
| 62 | + // the flashvars config. | ||
| 63 | + private var config:Object = null; | ||
| 60 | 64 | ||
| 61 | public function srs_player() | 65 | public function srs_player() |
| 62 | { | 66 | { |
| @@ -93,7 +97,8 @@ package | @@ -93,7 +97,8 @@ package | ||
| 93 | if (!flashvars.hasOwnProperty("id")) { | 97 | if (!flashvars.hasOwnProperty("id")) { |
| 94 | throw new Error("must specifies the id"); | 98 | throw new Error("must specifies the id"); |
| 95 | } | 99 | } |
| 96 | - | 100 | + |
| 101 | + this.config = flashvars; | ||
| 97 | this.js_id = flashvars.id; | 102 | this.js_id = flashvars.id; |
| 98 | this.js_on_player_ready = flashvars.on_player_ready; | 103 | this.js_on_player_ready = flashvars.on_player_ready; |
| 99 | this.js_on_player_metadata = flashvars.on_player_metadata; | 104 | this.js_on_player_metadata = flashvars.on_player_metadata; |
| @@ -134,7 +139,11 @@ package | @@ -134,7 +139,11 @@ package | ||
| 134 | * system callack event, timer to do some regular tasks. | 139 | * system callack event, timer to do some regular tasks. |
| 135 | */ | 140 | */ |
| 136 | private function system_on_timer(evt:TimerEvent):void { | 141 | private function system_on_timer(evt:TimerEvent):void { |
| 137 | - var ms:NetStream = this.media_stream; | 142 | + if (!player) { |
| 143 | + return; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + var ms:NetStream = player.stream(); | ||
| 138 | 147 | ||
| 139 | if (!ms) { | 148 | if (!ms) { |
| 140 | //log("stream is null, ignore timer event."); | 149 | //log("stream is null, ignore timer event."); |
| @@ -249,8 +258,8 @@ package | @@ -249,8 +258,8 @@ package | ||
| 249 | * function for js to call: to pause the stream. ignore if not play. | 258 | * function for js to call: to pause the stream. ignore if not play. |
| 250 | */ | 259 | */ |
| 251 | private function js_call_pause():void { | 260 | private function js_call_pause():void { |
| 252 | - if (this.media_stream) { | ||
| 253 | - this.media_stream.pause(); | 261 | + if (player && player.stream()) { |
| 262 | + player.stream().pause(); | ||
| 254 | log("user pause play"); | 263 | log("user pause play"); |
| 255 | } | 264 | } |
| 256 | } | 265 | } |
| @@ -259,8 +268,8 @@ package | @@ -259,8 +268,8 @@ package | ||
| 259 | * function for js to call: to resume the stream. ignore if not play. | 268 | * function for js to call: to resume the stream. ignore if not play. |
| 260 | */ | 269 | */ |
| 261 | private function js_call_resume():void { | 270 | private function js_call_resume():void { |
| 262 | - if (this.media_stream) { | ||
| 263 | - this.media_stream.resume(); | 271 | + if (player && player.stream()) { |
| 272 | + player.stream().resume(); | ||
| 264 | log("user resume play"); | 273 | log("user resume play"); |
| 265 | } | 274 | } |
| 266 | } | 275 | } |
| @@ -301,8 +310,8 @@ package | @@ -301,8 +310,8 @@ package | ||
| 301 | * @buffer_time the buffer time in seconds. | 310 | * @buffer_time the buffer time in seconds. |
| 302 | */ | 311 | */ |
| 303 | private function js_call_set_bt(buffer_time:Number):void { | 312 | private function js_call_set_bt(buffer_time:Number):void { |
| 304 | - if (this.media_stream) { | ||
| 305 | - this.media_stream.bufferTime = buffer_time; | 313 | + if (player && player.stream()) { |
| 314 | + player.stream().bufferTime = buffer_time; | ||
| 306 | log("user set bufferTime to " + buffer_time.toFixed(2) + "s"); | 315 | log("user set bufferTime to " + buffer_time.toFixed(2) + "s"); |
| 307 | } | 316 | } |
| 308 | } | 317 | } |
| @@ -313,8 +322,8 @@ package | @@ -313,8 +322,8 @@ package | ||
| 313 | * @remark this is the key feature for realtime communication by flash. | 322 | * @remark this is the key feature for realtime communication by flash. |
| 314 | */ | 323 | */ |
| 315 | private function js_call_set_mbt(max_buffer_time:Number):void { | 324 | private function js_call_set_mbt(max_buffer_time:Number):void { |
| 316 | - if (this.media_stream) { | ||
| 317 | - this.media_stream.bufferTimeMax = max_buffer_time; | 325 | + if (player && player.stream()) { |
| 326 | + player.stream().bufferTimeMax = max_buffer_time; | ||
| 318 | log("user set bufferTimeMax to " + max_buffer_time.toFixed(2) + "s"); | 327 | log("user set bufferTimeMax to " + max_buffer_time.toFixed(2) + "s"); |
| 319 | } | 328 | } |
| 320 | } | 329 | } |
| @@ -327,13 +336,10 @@ package | @@ -327,13 +336,10 @@ package | ||
| 327 | this.removeChild(this.media_video); | 336 | this.removeChild(this.media_video); |
| 328 | this.media_video = null; | 337 | this.media_video = null; |
| 329 | } | 338 | } |
| 330 | - if (this.media_stream) { | ||
| 331 | - this.media_stream.close(); | ||
| 332 | - this.media_stream = null; | ||
| 333 | - } | ||
| 334 | - if (this.media_conn) { | ||
| 335 | - this.media_conn.close(); | ||
| 336 | - this.media_conn = null; | 339 | + |
| 340 | + if (player) { | ||
| 341 | + player.close(); | ||
| 342 | + player = null; | ||
| 337 | } | 343 | } |
| 338 | log("player stopped"); | 344 | log("player stopped"); |
| 339 | } | 345 | } |
| @@ -403,97 +409,83 @@ package | @@ -403,97 +409,83 @@ package | ||
| 403 | * @param volume, the volume, 0 is mute, 1 is 100%, 2 is 200%. | 409 | * @param volume, the volume, 0 is mute, 1 is 100%, 2 is 200%. |
| 404 | */ | 410 | */ |
| 405 | private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, max_buffer_time:Number, volume:Number):void { | 411 | private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, max_buffer_time:Number, volume:Number):void { |
| 406 | - this.user_url = url; | ||
| 407 | this.user_w = _width; | 412 | this.user_w = _width; |
| 408 | this.user_h = _height; | 413 | this.user_h = _height; |
| 409 | - log("start to play url: " + this.user_url + ", w=" + this.user_w + ", h=" + this.user_h | 414 | + this.user_buffer_time = buffer_time; |
| 415 | + this.user_max_buffer_time = max_buffer_time; | ||
| 416 | + this.user_volume = volume; | ||
| 417 | + log("start to play url: " + url + ", w=" + this.user_w + ", h=" + this.user_h | ||
| 410 | + ", buffer=" + buffer_time.toFixed(2) + "s, max_buffer=" + max_buffer_time.toFixed(2) + "s, volume=" + volume.toFixed(2) | 418 | + ", buffer=" + buffer_time.toFixed(2) + "s, max_buffer=" + max_buffer_time.toFixed(2) + "s, volume=" + volume.toFixed(2) |
| 411 | ); | 419 | ); |
| 412 | 420 | ||
| 413 | js_call_stop(); | 421 | js_call_stop(); |
| 414 | - | ||
| 415 | - this.media_conn = new NetConnection(); | ||
| 416 | - this.media_conn.client = {}; | ||
| 417 | - this.media_conn.client.onBWDone = function():void {}; | ||
| 418 | - this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | ||
| 419 | - log("NetConnection: code=" + evt.info.code); | ||
| 420 | - | ||
| 421 | - if (evt.info.hasOwnProperty("data") && evt.info.data) { | ||
| 422 | - on_debug_info(evt.info.data); | ||
| 423 | - update_context_items(); | ||
| 424 | - } | ||
| 425 | - | ||
| 426 | - // reject by server, maybe redirect. | ||
| 427 | - if (evt.info.code == "NetConnection.Connect.Rejected") { | ||
| 428 | - // RTMP 302 redirect. | ||
| 429 | - if (evt.info.hasOwnProperty("ex") && evt.info.ex.code == 302) { | ||
| 430 | - var streamName:String = url.substr(url.lastIndexOf("/") + 1); | ||
| 431 | - url = evt.info.ex.redirect + "/" + streamName; | ||
| 432 | - log("Async RTMP 302 Redirect to: " + url); | ||
| 433 | - | ||
| 434 | - // notify server. | ||
| 435 | - media_conn.call("Redirected", null, evt.info.ex.redirect); | ||
| 436 | - | ||
| 437 | - // do 302. | ||
| 438 | - setTimeout(function(){ | ||
| 439 | - log("Async RTMP 302 Redirected."); | ||
| 440 | - js_call_play(url, _width, _height, buffer_time, max_buffer_time, volume); | ||
| 441 | - }, 1000); | ||
| 442 | - return; | ||
| 443 | - } | ||
| 444 | - } | ||
| 445 | - | ||
| 446 | - // TODO: FIXME: failed event. | ||
| 447 | - if (evt.info.code != "NetConnection.Connect.Success") { | ||
| 448 | - return; | ||
| 449 | - } | ||
| 450 | - | ||
| 451 | - media_stream = new NetStream(media_conn); | ||
| 452 | - media_stream.soundTransform = new SoundTransform(volume); | ||
| 453 | - media_stream.bufferTime = buffer_time; | ||
| 454 | - media_stream.bufferTimeMax = max_buffer_time; | ||
| 455 | - media_stream.client = {}; | ||
| 456 | - media_stream.client.onMetaData = system_on_metadata; | ||
| 457 | - media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | ||
| 458 | - log("NetStream: code=" + evt.info.code); | ||
| 459 | - | ||
| 460 | - if (evt.info.code == "NetStream.Video.DimensionChange") { | ||
| 461 | - system_on_metadata(media_metadata); | ||
| 462 | - } else if (evt.info.code == "NetStream.Buffer.Empty") { | ||
| 463 | - system_on_buffer_empty(); | ||
| 464 | - } else if (evt.info.code == "NetStream.Buffer.Full") { | ||
| 465 | - system_on_buffer_full(); | ||
| 466 | - } | ||
| 467 | - | ||
| 468 | - // TODO: FIXME: failed event. | ||
| 469 | - }); | ||
| 470 | - | ||
| 471 | - if (url.indexOf("http") == 0) { | ||
| 472 | - media_stream.play(url); | ||
| 473 | - } else { | ||
| 474 | - var streamName:String = url.substr(url.lastIndexOf("/") + 1); | ||
| 475 | - media_stream.play(streamName); | ||
| 476 | - } | ||
| 477 | - | ||
| 478 | - media_video = new Video(); | ||
| 479 | - media_video.width = _width; | ||
| 480 | - media_video.height = _height; | ||
| 481 | - media_video.attachNetStream(media_stream); | ||
| 482 | - media_video.smoothing = true; | ||
| 483 | - addChild(media_video); | ||
| 484 | - | ||
| 485 | - __draw_black_background(_width, _height); | ||
| 486 | - | ||
| 487 | - // lowest layer, for mask to cover it. | ||
| 488 | - setChildIndex(media_video, 0); | ||
| 489 | - }); | ||
| 490 | - | ||
| 491 | - if (url.indexOf("http") == 0) { | ||
| 492 | - this.media_conn.connect(null); | 422 | + |
| 423 | + // create player. | ||
| 424 | + if (Utility.stringEndswith(url, ".m3u8")) { | ||
| 425 | + player = new M3u8Player(this); | ||
| 426 | + log("create M3U8 player."); | ||
| 493 | } else { | 427 | } else { |
| 494 | - var tcUrl:String = this.user_url.substr(0, this.user_url.lastIndexOf("/")); | ||
| 495 | - this.media_conn.connect(tcUrl); | 428 | + player = new CommonPlayer(this); |
| 429 | + log("create Common player."); | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + // init player by config. | ||
| 433 | + player.init(config); | ||
| 434 | + | ||
| 435 | + // play the url. | ||
| 436 | + player.play(url); | ||
| 437 | + } | ||
| 438 | + public function on_player_before_play():void { | ||
| 439 | + if (!player) { | ||
| 440 | + return; | ||
| 496 | } | 441 | } |
| 442 | + | ||
| 443 | + var ms:NetStream = player.stream(); | ||
| 444 | + if (!ms) { | ||
| 445 | + return; | ||
| 446 | + } | ||
| 447 | + | ||
| 448 | + ms.soundTransform = new SoundTransform(user_volume); | ||
| 449 | + ms.bufferTime = user_buffer_time; | ||
| 450 | + ms.bufferTimeMax = user_max_buffer_time; | ||
| 451 | + ms.client = {}; | ||
| 452 | + ms.client.onMetaData = system_on_metadata; | ||
| 453 | + } | ||
| 454 | + public function on_player_play():void { | ||
| 455 | + if (!player) { | ||
| 456 | + return; | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + media_video = new Video(); | ||
| 460 | + media_video.width = user_w; | ||
| 461 | + media_video.height = user_h; | ||
| 462 | + media_video.attachNetStream(player.stream()); | ||
| 463 | + media_video.smoothing = true; | ||
| 464 | + addChild(media_video); | ||
| 465 | + | ||
| 466 | + __draw_black_background(user_w, user_h); | ||
| 467 | + | ||
| 468 | + // lowest layer, for mask to cover it. | ||
| 469 | + setChildIndex(media_video, 0); | ||
| 470 | + } | ||
| 471 | + public function on_player_metadata(data:Object):void { | ||
| 472 | + on_debug_info(data); | ||
| 473 | + update_context_items(); | ||
| 474 | + } | ||
| 475 | + public function on_player_302(url:String):void { | ||
| 476 | + setTimeout(function():void{ | ||
| 477 | + log("Async RTMP 302 Redirected."); | ||
| 478 | + js_call_play(url, user_w, user_h, user_buffer_time, user_max_buffer_time, user_volume); | ||
| 479 | + }, 1000); | ||
| 480 | + } | ||
| 481 | + public function on_player_dimension_change():void { | ||
| 482 | + system_on_metadata(media_metadata); | ||
| 483 | + } | ||
| 484 | + public function on_player_buffer_empty():void { | ||
| 485 | + system_on_buffer_empty(); | ||
| 486 | + } | ||
| 487 | + public function on_player_buffer_full():void { | ||
| 488 | + system_on_buffer_full(); | ||
| 497 | } | 489 | } |
| 498 | 490 | ||
| 499 | /** | 491 | /** |
| @@ -650,16 +642,7 @@ package | @@ -650,16 +642,7 @@ package | ||
| 650 | } | 642 | } |
| 651 | 643 | ||
| 652 | private function log(msg:String):void { | 644 | private function log(msg:String):void { |
| 653 | - msg = "[" + new Date() +"][srs-player][" + js_id + "] " + msg; | ||
| 654 | - | ||
| 655 | - trace(msg); | ||
| 656 | - | ||
| 657 | - if (!flash.external.ExternalInterface.available) { | ||
| 658 | - flash.utils.setTimeout(log, 300, msg); | ||
| 659 | - return; | ||
| 660 | - } | ||
| 661 | - | ||
| 662 | - ExternalInterface.call("console.log", msg); | 645 | + Utility.log(js_id, msg); |
| 663 | } | 646 | } |
| 664 | } | 647 | } |
| 665 | } | 648 | } |
-
请 注册 或 登录 后发表评论