1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

refine player to support status change.

This commit is contained in:
winlin 2016-03-22 18:35:44 +08:00
parent 4841435b14
commit 6b5c880ff9
6 changed files with 136 additions and 15 deletions

View file

@ -99,6 +99,7 @@ SrsPlayer.prototype.start = function(url) {
flashvars.on_player_timer = "__srs_on_player_timer"; flashvars.on_player_timer = "__srs_on_player_timer";
flashvars.on_player_empty = "__srs_on_player_empty"; flashvars.on_player_empty = "__srs_on_player_empty";
flashvars.on_player_full = "__srs_on_player_full"; flashvars.on_player_full = "__srs_on_player_full";
flashvars.on_player_status = "__srs_on_player_status";
var params = {}; var params = {};
params.wmode = "opaque"; params.wmode = "opaque";
@ -146,17 +147,6 @@ SrsPlayer.prototype.play = function(url, volume) {
* stop play stream. * stop play stream.
*/ */
SrsPlayer.prototype.stop = function() { SrsPlayer.prototype.stop = function() {
for (var i = 0; i < SrsPlayer.__players.length; i++) {
var player = SrsPlayer.__players[i];
if (player.id != this.id) {
continue;
}
SrsPlayer.__players.splice(i, 1);
break;
}
this.callbackObj.ref.__stop(); this.callbackObj.ref.__stop();
} }
/** /**
@ -301,6 +291,16 @@ SrsPlayer.prototype.on_player_empty = function(time) {
SrsPlayer.prototype.on_player_full = function(time) { SrsPlayer.prototype.on_player_full = function(time) {
// ignore. // ignore.
} }
/**
* the callback when player status change.
* @param code the status code, "init", "connected", "play", "closed", "rejected", "failed".
* init => connected/rejected/failed
* connected => play/rejected => closed
* @param desc the description for the status.
*/
SrsPlayer.prototype.on_player_status = function(code, desc) {
// ignore.
}
/** /**
* helpers. * helpers.
@ -359,3 +359,21 @@ function __srs_on_player_full(id, time) {
player.__fluency.on_stream_full(time); player.__fluency.on_stream_full(time);
player.on_player_full(time); player.on_player_full(time);
} }
function __srs_on_player_status(id, code, desc) {
var player = __srs_find_player(id);
player.on_player_status(code, desc);
if (code != "closed") {
return;
}
for (var i = 0; i < SrsPlayer.__players.length; i++) {
var player = SrsPlayer.__players[i];
if (player.id != this.id) {
continue;
}
SrsPlayer.__players.splice(i, 1);
break;
}
}

View file

@ -514,6 +514,9 @@
select_buffer(0.5); select_buffer(0.5);
this.play(url); this.play(url);
}; };
srs_player.on_player_status = function(code, desc) {
//console.log("[播放器状态] code=" + code + ", desc=" + desc);
};
srs_player.on_player_metadata = function(metadata) { srs_player.on_player_metadata = function(metadata) {
$("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")"); $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");
if (metadata.ip && metadata.pid && metadata.cid) { if (metadata.ip && metadata.pid && metadata.cid) {

View file

@ -1,7 +1,10 @@
package package
{ {
import flash.events.Event; import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.ProgressEvent; import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.external.ExternalInterface; import flash.external.ExternalInterface;
import flash.net.NetConnection; import flash.net.NetConnection;
import flash.net.NetStream; import flash.net.NetStream;
@ -28,6 +31,8 @@ package
// play param url. // play param url.
private var user_url:String = null; private var user_url:String = null;
private var conn:NetConnection = null;
/** /**
* create stream to play hls. * create stream to play hls.
* @param m3u8_refresh_ratio, for example, 0.5, fetch m3u8 every 0.5*ts_duration. * @param m3u8_refresh_ratio, for example, 0.5, fetch m3u8 every 0.5*ts_duration.
@ -40,6 +45,7 @@ package
this.m3u8_refresh_ratio = m3u8_refresh_ratio; this.m3u8_refresh_ratio = m3u8_refresh_ratio;
this.ts_parse_async_interval = ts_parse_async_interval; this.ts_parse_async_interval = ts_parse_async_interval;
hls = new HlsCodec(this); hls = new HlsCodec(this);
this.conn = conn;
} }
/** /**
@ -94,6 +100,8 @@ package
refresh_ts(); refresh_ts();
}) })
} }
private var metadata:Object = null;
private function refresh_ts():void { private function refresh_ts():void {
// all ts parsed. // all ts parsed.
if (parsed_ts_seq_no >= hls.seq_no + hls.tsCount) { if (parsed_ts_seq_no >= hls.seq_no + hls.tsCount) {
@ -125,9 +133,14 @@ package
//log("uv[" + k + "]=" + v); //log("uv[" + k + "]=" + v);
} }
if (client && client.hasOwnProperty("onMetaData")) { // ignore when not changed.
client.onMetaData(obj); if (!metadata || metadata.srs_server_ip != obj.srs_server_ip || metadata.srs_id != obj.srs_id || metadata.srs_pid != obj.srs_pid) {
if (client && client.hasOwnProperty("onMetaData")) {
log("got metadata for url " + uri);
client.onMetaData(obj);
}
} }
metadata = obj;
} }
download(uri, function(stream:ByteArray):void{ download(uri, function(stream:ByteArray):void{
@ -177,6 +190,14 @@ package
completed(stream); completed(stream);
}); });
url.addEventListener(IOErrorEvent.IO_ERROR, function(evt:IOErrorEvent):void{
onPlayFailed(evt);
});
url.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(evt:SecurityErrorEvent):void{
onPlayRejected(evt);
});
// we set to the query. // we set to the query.
uri += ((uri.indexOf("?") == -1)? "?":"&") + "shp_xpsid=" + XPlaybackSessionId; uri += ((uri.indexOf("?") == -1)? "?":"&") + "shp_xpsid=" + XPlaybackSessionId;
var r:URLRequest = new URLRequest(uri); var r:URLRequest = new URLRequest(uri);
@ -219,8 +240,36 @@ package
log("FLV: sps/pps " + flvHeader.length + " bytes"); log("FLV: sps/pps " + flvHeader.length + " bytes");
writeFlv(flvHeader); writeFlv(flvHeader);
onPlayStart();
} }
private function onPlayStart():void {
log("dispatch NetStream.Play.Start.");
dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, {
code: "NetStream.Play.Start",
stream: user_url,
descrption: "play start"
}));
}
private function onPlayFailed(evt:IOErrorEvent):void {
log("dispatch NetConnection.Connect.Failed.");
this.conn.dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, {
code: "NetConnection.Connect.Failed",
stream: user_url,
descrption: evt.text
}));
}
private function onPlayRejected(evt:SecurityErrorEvent):void {
log("dispatch NetConnection.Connect.Rejected.");
this.conn.dispatchEvent(new NetStatusEvent(NetStatusEvent.NET_STATUS, false, false, {
code: "NetConnection.Connect.Rejected",
stream: user_url,
descrption: evt.text
}));
}
private function onFlvBody(uri:String, flv:ByteArray):void { private function onFlvBody(uri:String, flv:ByteArray):void {
if (!flvHeader) { if (!flvHeader) {
return; return;

View file

@ -58,7 +58,18 @@ package
return this.media_stream; return this.media_stream;
} }
private function dumps_object(obj:Object):String {
var smr:String = "";
for (var k:String in obj) {
smr += k + "=" + obj[k] + ", ";
}
return smr;
}
public function play(url:String):void { public function play(url:String):void {
owner.on_player_status("init", "Ready to play");
var streamName:String; var streamName:String;
this.user_url = url; this.user_url = url;
@ -66,7 +77,8 @@ package
this.media_conn.client = {}; this.media_conn.client = {};
this.media_conn.client.onBWDone = function():void {}; this.media_conn.client.onBWDone = function():void {};
this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
log("NetConnection: code=" + evt.info.code); log("NetConnection: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable
+ ", info is " + dumps_object(evt.info));
if (evt.info.hasOwnProperty("data") && evt.info.data) { if (evt.info.hasOwnProperty("data") && evt.info.data) {
owner.on_player_metadata(evt.info.data); owner.on_player_metadata(evt.info.data);
@ -87,8 +99,22 @@ package
owner.on_player_302(url); owner.on_player_302(url);
return; return;
} }
owner.on_player_status("rejected", "Server reject play");
close();
} }
if (evt.info.code == "NetConnection.Connect.Success") {
owner.on_player_status("connected", "Connected at server");
}
if (evt.info.code == "NetConnection.Connect.Closed") {
close();
}
if (evt.info.code == "NetConnection.Connect.Failed") {
owner.on_player_status("failed", "Connect to server failed.");
close();
}
// TODO: FIXME: failed event. // TODO: FIXME: failed event.
if (evt.info.code != "NetConnection.Connect.Success") { if (evt.info.code != "NetConnection.Connect.Success") {
return; return;
@ -100,7 +126,16 @@ package
media_stream = new NetStream(media_conn); media_stream = new NetStream(media_conn);
} }
media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
log("NetStream: code=" + evt.info.code); log("NetStream: type=" + evt.type + ", bub=" + evt.bubbles + ", can=" + evt.cancelable
+ ", info is " + dumps_object(evt.info));
if (evt.info.code == "NetStream.Play.Start") {
owner.on_player_status("play", "Start to play stream");
}
if (evt.info.code == "NetStream.Play.StreamNotFound") {
owner.on_player_status("rejected", "Stream not found");
close();
}
if (evt.info.code == "NetStream.Video.DimensionChange") { if (evt.info.code == "NetStream.Video.DimensionChange") {
owner.on_player_dimension_change(); owner.on_player_dimension_change();
@ -149,14 +184,23 @@ package
} }
public function close():void { public function close():void {
var notify:Boolean = false;
if (this.media_stream) { if (this.media_stream) {
this.media_stream.close(); this.media_stream.close();
this.media_stream = null; this.media_stream = null;
notify = true;
} }
if (this.media_conn) { if (this.media_conn) {
this.media_conn.close(); this.media_conn.close();
this.media_conn = null; this.media_conn = null;
notify = true;
} }
if (notify) {
owner.on_player_status("closed", "Server closed.");
}
} }
private function log(msg:String):void { private function log(msg:String):void {

View file

@ -33,6 +33,7 @@ package
private var js_on_player_timer:String = null; private var js_on_player_timer:String = null;
private var js_on_player_empty:String = null; private var js_on_player_empty:String = null;
private var js_on_player_full:String = null; private var js_on_player_full:String = null;
private var js_on_player_status:String = null;
// play param, user set width and height // play param, user set width and height
private var user_w:int = 0; private var user_w:int = 0;
@ -105,6 +106,7 @@ package
this.js_on_player_timer = flashvars.on_player_timer; this.js_on_player_timer = flashvars.on_player_timer;
this.js_on_player_empty = flashvars.on_player_empty; this.js_on_player_empty = flashvars.on_player_empty;
this.js_on_player_full = flashvars.on_player_full; this.js_on_player_full = flashvars.on_player_full;
this.js_on_player_status = flashvars.on_player_status;
this.media_timer.addEventListener(TimerEvent.TIMER, this.system_on_timer); this.media_timer.addEventListener(TimerEvent.TIMER, this.system_on_timer);
this.media_timer.start(); this.media_timer.start();
@ -498,6 +500,11 @@ package
system_on_buffer_full(); system_on_buffer_full();
} }
public function on_player_status(code:String, desc:String):void {
log("[STATUS] code=" + code + ", desc=" + desc);
flash.external.ExternalInterface.call(this.js_on_player_status, this.js_id, code, desc);
}
/** /**
* get the "right" size of video, * get the "right" size of video,
* 1. initialize with the original video object size. * 1. initialize with the original video object size.