正在显示
6 个修改的文件
包含
136 行增加
和
15 行删除
| @@ -99,6 +99,7 @@ SrsPlayer.prototype.start = function(url) { | @@ -99,6 +99,7 @@ SrsPlayer.prototype.start = function(url) { | ||
| 99 | flashvars.on_player_timer = "__srs_on_player_timer"; | 99 | flashvars.on_player_timer = "__srs_on_player_timer"; |
| 100 | flashvars.on_player_empty = "__srs_on_player_empty"; | 100 | flashvars.on_player_empty = "__srs_on_player_empty"; |
| 101 | flashvars.on_player_full = "__srs_on_player_full"; | 101 | flashvars.on_player_full = "__srs_on_player_full"; |
| 102 | + flashvars.on_player_status = "__srs_on_player_status"; | ||
| 102 | 103 | ||
| 103 | var params = {}; | 104 | var params = {}; |
| 104 | params.wmode = "opaque"; | 105 | params.wmode = "opaque"; |
| @@ -146,17 +147,6 @@ SrsPlayer.prototype.play = function(url, volume) { | @@ -146,17 +147,6 @@ SrsPlayer.prototype.play = function(url, volume) { | ||
| 146 | * stop play stream. | 147 | * stop play stream. |
| 147 | */ | 148 | */ |
| 148 | SrsPlayer.prototype.stop = function() { | 149 | SrsPlayer.prototype.stop = function() { |
| 149 | - for (var i = 0; i < SrsPlayer.__players.length; i++) { | ||
| 150 | - var player = SrsPlayer.__players[i]; | ||
| 151 | - | ||
| 152 | - if (player.id != this.id) { | ||
| 153 | - continue; | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | - SrsPlayer.__players.splice(i, 1); | ||
| 157 | - break; | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | this.callbackObj.ref.__stop(); | 150 | this.callbackObj.ref.__stop(); |
| 161 | } | 151 | } |
| 162 | /** | 152 | /** |
| @@ -301,6 +291,16 @@ SrsPlayer.prototype.on_player_empty = function(time) { | @@ -301,6 +291,16 @@ SrsPlayer.prototype.on_player_empty = function(time) { | ||
| 301 | SrsPlayer.prototype.on_player_full = function(time) { | 291 | SrsPlayer.prototype.on_player_full = function(time) { |
| 302 | // ignore. | 292 | // ignore. |
| 303 | } | 293 | } |
| 294 | +/** | ||
| 295 | + * the callback when player status change. | ||
| 296 | + * @param code the status code, "init", "connected", "play", "closed", "rejected", "failed". | ||
| 297 | + * init => connected/rejected/failed | ||
| 298 | + * connected => play/rejected => closed | ||
| 299 | + * @param desc the description for the status. | ||
| 300 | + */ | ||
| 301 | +SrsPlayer.prototype.on_player_status = function(code, desc) { | ||
| 302 | + // ignore. | ||
| 303 | +} | ||
| 304 | 304 | ||
| 305 | /** | 305 | /** |
| 306 | * helpers. | 306 | * helpers. |
| @@ -359,3 +359,21 @@ function __srs_on_player_full(id, time) { | @@ -359,3 +359,21 @@ function __srs_on_player_full(id, time) { | ||
| 359 | player.__fluency.on_stream_full(time); | 359 | player.__fluency.on_stream_full(time); |
| 360 | player.on_player_full(time); | 360 | player.on_player_full(time); |
| 361 | } | 361 | } |
| 362 | +function __srs_on_player_status(id, code, desc) { | ||
| 363 | + var player = __srs_find_player(id); | ||
| 364 | + player.on_player_status(code, desc); | ||
| 365 | + | ||
| 366 | + if (code != "closed") { | ||
| 367 | + return; | ||
| 368 | + } | ||
| 369 | + for (var i = 0; i < SrsPlayer.__players.length; i++) { | ||
| 370 | + var player = SrsPlayer.__players[i]; | ||
| 371 | + | ||
| 372 | + if (player.id != this.id) { | ||
| 373 | + continue; | ||
| 374 | + } | ||
| 375 | + | ||
| 376 | + SrsPlayer.__players.splice(i, 1); | ||
| 377 | + break; | ||
| 378 | + } | ||
| 379 | +} |
| @@ -514,6 +514,9 @@ | @@ -514,6 +514,9 @@ | ||
| 514 | select_buffer(0.5); | 514 | select_buffer(0.5); |
| 515 | this.play(url); | 515 | this.play(url); |
| 516 | }; | 516 | }; |
| 517 | + srs_player.on_player_status = function(code, desc) { | ||
| 518 | + //console.log("[播放器状态] code=" + code + ", desc=" + desc); | ||
| 519 | + }; | ||
| 517 | srs_player.on_player_metadata = function(metadata) { | 520 | srs_player.on_player_metadata = function(metadata) { |
| 518 | $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")"); | 521 | $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")"); |
| 519 | if (metadata.ip && metadata.pid && metadata.cid) { | 522 | if (metadata.ip && metadata.pid && metadata.cid) { |
| 1 | package | 1 | package |
| 2 | { | 2 | { |
| 3 | import flash.events.Event; | 3 | import flash.events.Event; |
| 4 | + import flash.events.IOErrorEvent; | ||
| 5 | + import flash.events.NetStatusEvent; | ||
| 4 | import flash.events.ProgressEvent; | 6 | import flash.events.ProgressEvent; |
| 7 | + import flash.events.SecurityErrorEvent; | ||
| 5 | import flash.external.ExternalInterface; | 8 | import flash.external.ExternalInterface; |
| 6 | import flash.net.NetConnection; | 9 | import flash.net.NetConnection; |
| 7 | import flash.net.NetStream; | 10 | import flash.net.NetStream; |
| @@ -27,6 +30,8 @@ package | @@ -27,6 +30,8 @@ package | ||
| 27 | 30 | ||
| 28 | // play param url. | 31 | // play param url. |
| 29 | private var user_url:String = null; | 32 | private var user_url:String = null; |
| 33 | + | ||
| 34 | + private var conn:NetConnection = null; | ||
| 30 | 35 | ||
| 31 | /** | 36 | /** |
| 32 | * create stream to play hls. | 37 | * create stream to play hls. |
| @@ -40,6 +45,7 @@ package | @@ -40,6 +45,7 @@ package | ||
| 40 | this.m3u8_refresh_ratio = m3u8_refresh_ratio; | 45 | this.m3u8_refresh_ratio = m3u8_refresh_ratio; |
| 41 | this.ts_parse_async_interval = ts_parse_async_interval; | 46 | this.ts_parse_async_interval = ts_parse_async_interval; |
| 42 | hls = new HlsCodec(this); | 47 | hls = new HlsCodec(this); |
| 48 | + this.conn = conn; | ||
| 43 | } | 49 | } |
| 44 | 50 | ||
| 45 | /** | 51 | /** |
| @@ -94,6 +100,8 @@ package | @@ -94,6 +100,8 @@ package | ||
| 94 | refresh_ts(); | 100 | refresh_ts(); |
| 95 | }) | 101 | }) |
| 96 | } | 102 | } |
| 103 | + | ||
| 104 | + private var metadata:Object = null; | ||
| 97 | private function refresh_ts():void { | 105 | private function refresh_ts():void { |
| 98 | // all ts parsed. | 106 | // all ts parsed. |
| 99 | if (parsed_ts_seq_no >= hls.seq_no + hls.tsCount) { | 107 | if (parsed_ts_seq_no >= hls.seq_no + hls.tsCount) { |
| @@ -125,9 +133,14 @@ package | @@ -125,9 +133,14 @@ package | ||
| 125 | //log("uv[" + k + "]=" + v); | 133 | //log("uv[" + k + "]=" + v); |
| 126 | } | 134 | } |
| 127 | 135 | ||
| 128 | - if (client && client.hasOwnProperty("onMetaData")) { | ||
| 129 | - client.onMetaData(obj); | 136 | + // ignore when not changed. |
| 137 | + if (!metadata || metadata.srs_server_ip != obj.srs_server_ip || metadata.srs_id != obj.srs_id || metadata.srs_pid != obj.srs_pid) { | ||
| 138 | + if (client && client.hasOwnProperty("onMetaData")) { | ||
| 139 | + log("got metadata for url " + uri); | ||
| 140 | + client.onMetaData(obj); | ||
| 141 | + } | ||
| 130 | } | 142 | } |
| 143 | + metadata = obj; | ||
| 131 | } | 144 | } |
| 132 | 145 | ||
| 133 | download(uri, function(stream:ByteArray):void{ | 146 | download(uri, function(stream:ByteArray):void{ |
| @@ -177,6 +190,14 @@ package | @@ -177,6 +190,14 @@ package | ||
| 177 | completed(stream); | 190 | completed(stream); |
| 178 | }); | 191 | }); |
| 179 | 192 | ||
| 193 | + url.addEventListener(IOErrorEvent.IO_ERROR, function(evt:IOErrorEvent):void{ | ||
| 194 | + onPlayFailed(evt); | ||
| 195 | + }); | ||
| 196 | + | ||
| 197 | + url.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(evt:SecurityErrorEvent):void{ | ||
| 198 | + onPlayRejected(evt); | ||
| 199 | + }); | ||
| 200 | + | ||
| 180 | // we set to the query. | 201 | // we set to the query. |
| 181 | uri += ((uri.indexOf("?") == -1)? "?":"&") + "shp_xpsid=" + XPlaybackSessionId; | 202 | uri += ((uri.indexOf("?") == -1)? "?":"&") + "shp_xpsid=" + XPlaybackSessionId; |
| 182 | var r:URLRequest = new URLRequest(uri); | 203 | var r:URLRequest = new URLRequest(uri); |
| @@ -219,7 +240,35 @@ package | @@ -219,7 +240,35 @@ package | ||
| 219 | log("FLV: sps/pps " + flvHeader.length + " bytes"); | 240 | log("FLV: sps/pps " + flvHeader.length + " bytes"); |
| 220 | 241 | ||
| 221 | writeFlv(flvHeader); | 242 | writeFlv(flvHeader); |
| 243 | + onPlayStart(); | ||
| 222 | } | 244 | } |
| 245 | + | ||
| 246 | + private function onPlayStart():void { | ||
| 247 | + log("dispatch NetStream.Play.Start."); | ||
| 248 | + dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, { | ||
| 249 | + code: "NetStream.Play.Start", | ||
| 250 | + stream: user_url, | ||
| 251 | + descrption: "play start" | ||
| 252 | + })); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + private function onPlayFailed(evt:IOErrorEvent):void { | ||
| 256 | + log("dispatch NetConnection.Connect.Failed."); | ||
| 257 | + this.conn.dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, { | ||
| 258 | + code: "NetConnection.Connect.Failed", | ||
| 259 | + stream: user_url, | ||
| 260 | + descrption: evt.text | ||
| 261 | + })); | ||
| 262 | + } | ||
| 263 | + | ||
| 264 | + private function onPlayRejected(evt:SecurityErrorEvent):void { | ||
| 265 | + log("dispatch NetConnection.Connect.Rejected."); | ||
| 266 | + this.conn.dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, { | ||
| 267 | + code: "NetConnection.Connect.Rejected", | ||
| 268 | + stream: user_url, | ||
| 269 | + descrption: evt.text | ||
| 270 | + })); | ||
| 271 | + } | ||
| 223 | 272 | ||
| 224 | private function onFlvBody(uri:String, flv:ByteArray):void { | 273 | private function onFlvBody(uri:String, flv:ByteArray):void { |
| 225 | if (!flvHeader) { | 274 | if (!flvHeader) { |
| @@ -57,8 +57,19 @@ package | @@ -57,8 +57,19 @@ package | ||
| 57 | public function stream():NetStream { | 57 | public function stream():NetStream { |
| 58 | return this.media_stream; | 58 | return this.media_stream; |
| 59 | } | 59 | } |
| 60 | + | ||
| 61 | + private function dumps_object(obj:Object):String { | ||
| 62 | + var smr:String = ""; | ||
| 63 | + for (var k:String in obj) { | ||
| 64 | + smr += k + "=" + obj[k] + ", "; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + return smr; | ||
| 68 | + } | ||
| 60 | 69 | ||
| 61 | public function play(url:String):void { | 70 | public function play(url:String):void { |
| 71 | + owner.on_player_status("init", "Ready to play"); | ||
| 72 | + | ||
| 62 | var streamName:String; | 73 | var streamName:String; |
| 63 | this.user_url = url; | 74 | this.user_url = url; |
| 64 | 75 | ||
| @@ -66,7 +77,8 @@ package | @@ -66,7 +77,8 @@ package | ||
| 66 | this.media_conn.client = {}; | 77 | this.media_conn.client = {}; |
| 67 | this.media_conn.client.onBWDone = function():void {}; | 78 | this.media_conn.client.onBWDone = function():void {}; |
| 68 | this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | 79 | this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { |
| 69 | - log("NetConnection: code=" + evt.info.code); | 80 | + log("NetConnection: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable |
| 81 | + + ", info is " + dumps_object(evt.info)); | ||
| 70 | 82 | ||
| 71 | if (evt.info.hasOwnProperty("data") && evt.info.data) { | 83 | if (evt.info.hasOwnProperty("data") && evt.info.data) { |
| 72 | owner.on_player_metadata(evt.info.data); | 84 | owner.on_player_metadata(evt.info.data); |
| @@ -87,7 +99,21 @@ package | @@ -87,7 +99,21 @@ package | ||
| 87 | owner.on_player_302(url); | 99 | owner.on_player_302(url); |
| 88 | return; | 100 | return; |
| 89 | } | 101 | } |
| 102 | + | ||
| 103 | + owner.on_player_status("rejected", "Server reject play"); | ||
| 104 | + close(); | ||
| 90 | } | 105 | } |
| 106 | + | ||
| 107 | + if (evt.info.code == "NetConnection.Connect.Success") { | ||
| 108 | + owner.on_player_status("connected", "Connected at server"); | ||
| 109 | + } | ||
| 110 | + if (evt.info.code == "NetConnection.Connect.Closed") { | ||
| 111 | + close(); | ||
| 112 | + } | ||
| 113 | + if (evt.info.code == "NetConnection.Connect.Failed") { | ||
| 114 | + owner.on_player_status("failed", "Connect to server failed."); | ||
| 115 | + close(); | ||
| 116 | + } | ||
| 91 | 117 | ||
| 92 | // TODO: FIXME: failed event. | 118 | // TODO: FIXME: failed event. |
| 93 | if (evt.info.code != "NetConnection.Connect.Success") { | 119 | if (evt.info.code != "NetConnection.Connect.Success") { |
| @@ -100,7 +126,16 @@ package | @@ -100,7 +126,16 @@ package | ||
| 100 | media_stream = new NetStream(media_conn); | 126 | media_stream = new NetStream(media_conn); |
| 101 | } | 127 | } |
| 102 | media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { | 128 | media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { |
| 103 | - log("NetStream: code=" + evt.info.code); | 129 | + log("NetStream: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable |
| 130 | + + ", info is " + dumps_object(evt.info)); | ||
| 131 | + | ||
| 132 | + if (evt.info.code == "NetStream.Play.Start") { | ||
| 133 | + owner.on_player_status("play", "Start to play stream"); | ||
| 134 | + } | ||
| 135 | + if (evt.info.code == "NetStream.Play.StreamNotFound") { | ||
| 136 | + owner.on_player_status("rejected", "Stream not found"); | ||
| 137 | + close(); | ||
| 138 | + } | ||
| 104 | 139 | ||
| 105 | if (evt.info.code == "NetStream.Video.DimensionChange") { | 140 | if (evt.info.code == "NetStream.Video.DimensionChange") { |
| 106 | owner.on_player_dimension_change(); | 141 | owner.on_player_dimension_change(); |
| @@ -149,14 +184,23 @@ package | @@ -149,14 +184,23 @@ package | ||
| 149 | } | 184 | } |
| 150 | 185 | ||
| 151 | public function close():void { | 186 | public function close():void { |
| 187 | + var notify:Boolean = false; | ||
| 188 | + | ||
| 152 | if (this.media_stream) { | 189 | if (this.media_stream) { |
| 153 | this.media_stream.close(); | 190 | this.media_stream.close(); |
| 154 | this.media_stream = null; | 191 | this.media_stream = null; |
| 192 | + notify = true; | ||
| 155 | } | 193 | } |
| 194 | + | ||
| 156 | if (this.media_conn) { | 195 | if (this.media_conn) { |
| 157 | this.media_conn.close(); | 196 | this.media_conn.close(); |
| 158 | this.media_conn = null; | 197 | this.media_conn = null; |
| 198 | + notify = true; | ||
| 159 | } | 199 | } |
| 200 | + | ||
| 201 | + if (notify) { | ||
| 202 | + owner.on_player_status("closed", "Server closed."); | ||
| 203 | + } | ||
| 160 | } | 204 | } |
| 161 | 205 | ||
| 162 | private function log(msg:String):void { | 206 | private function log(msg:String):void { |
| @@ -33,6 +33,7 @@ package | @@ -33,6 +33,7 @@ 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 | + private var js_on_player_status:String = null; | ||
| 36 | 37 | ||
| 37 | // play param, user set width and height | 38 | // play param, user set width and height |
| 38 | private var user_w:int = 0; | 39 | private var user_w:int = 0; |
| @@ -105,6 +106,7 @@ package | @@ -105,6 +106,7 @@ package | ||
| 105 | this.js_on_player_timer = flashvars.on_player_timer; | 106 | this.js_on_player_timer = flashvars.on_player_timer; |
| 106 | this.js_on_player_empty = flashvars.on_player_empty; | 107 | this.js_on_player_empty = flashvars.on_player_empty; |
| 107 | this.js_on_player_full = flashvars.on_player_full; | 108 | this.js_on_player_full = flashvars.on_player_full; |
| 109 | + this.js_on_player_status = flashvars.on_player_status; | ||
| 108 | 110 | ||
| 109 | this.media_timer.addEventListener(TimerEvent.TIMER, this.system_on_timer); | 111 | this.media_timer.addEventListener(TimerEvent.TIMER, this.system_on_timer); |
| 110 | this.media_timer.start(); | 112 | this.media_timer.start(); |
| @@ -497,6 +499,11 @@ package | @@ -497,6 +499,11 @@ package | ||
| 497 | public function on_player_buffer_full():void { | 499 | public function on_player_buffer_full():void { |
| 498 | system_on_buffer_full(); | 500 | system_on_buffer_full(); |
| 499 | } | 501 | } |
| 502 | + | ||
| 503 | + public function on_player_status(code:String, desc:String):void { | ||
| 504 | + log("[STATUS] code=" + code + ", desc=" + desc); | ||
| 505 | + flash.external.ExternalInterface.call(this.js_on_player_status, this.js_id, code, desc); | ||
| 506 | + } | ||
| 500 | 507 | ||
| 501 | /** | 508 | /** |
| 502 | * get the "right" size of video, | 509 | * get the "right" size of video, |
-
请 注册 或 登录 后发表评论