diff --git a/trunk/research/players/js/srs.player.js b/trunk/research/players/js/srs.player.js index ac45896b6..0c82d4457 100755 --- a/trunk/research/players/js/srs.player.js +++ b/trunk/research/players/js/srs.player.js @@ -5,6 +5,22 @@ * @param height a float value specifies the height of player. * @param private_object [optional] an object that used as private object, * for example, the logic chat object which owner this player. +* Usage: + + +
+ var p = new SrsPlayer("player", 640, 480); + p.set_srs_player_url("srs_player.swf?v=1.0.0"); + p.on_player_ready = function() { + p.set_bt(0.8); + p.set_mbt(1.2); + p.play("rtmp://ossrs.net/live/livestream"); + }; + p.on_player_metadata = function(metadata) { + console.log(metadata); + console.log(p.dump_log()); + }; + p.start(); */ function SrsPlayer(container, width, height, private_object) { if (!SrsPlayer.__id) { @@ -63,8 +79,12 @@ function SrsPlayer(container, width, height, private_object) { * user can set some callback, then start the player. * @param url the default url. * callbacks: -* on_player_ready():int, when srs player ready, user can play. +* on_player_ready():int, when srs player ready, user can play(). * on_player_metadata(metadata:Object):int, when srs player get metadata. +* methods: +* set_bt(t:Number):void, set the buffer time in seconds. +* set_mbt(t:Number):void, set the max buffer time in seconds. +* dump_log():String, get all logs of player. */ SrsPlayer.prototype.start = function(url) { if (url) { diff --git a/trunk/research/players/srs_player/src/M3u8Player.as b/trunk/research/players/srs_player/src/M3u8Player.as index 6aa928dd4..173473477 100644 --- a/trunk/research/players/srs_player/src/M3u8Player.as +++ b/trunk/research/players/srs_player/src/M3u8Player.as @@ -52,6 +52,68 @@ package public function play(url:String):void { this.user_url = url; + + this.media_conn = new NetConnection(); + this.media_conn.client = {}; + this.media_conn.client.onBWDone = function():void {}; + this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { + log("NetConnection: code=" + evt.info.code); + + if (evt.info.hasOwnProperty("data") && evt.info.data) { + owner.on_player_metadata(evt.info.data); + } + + // reject by server, maybe redirect. + if (evt.info.code == "NetConnection.Connect.Rejected") { + // RTMP 302 redirect. + if (evt.info.hasOwnProperty("ex") && evt.info.ex.code == 302) { + streamName = url.substr(url.lastIndexOf("/") + 1); + url = evt.info.ex.redirect + "/" + streamName; + log("Async RTMP 302 Redirect to: " + url); + + // notify server. + media_conn.call("Redirected", null, evt.info.ex.redirect); + + // do 302. + owner.on_player_302(url); + return; + } + } + + // TODO: FIXME: failed event. + if (evt.info.code != "NetConnection.Connect.Success") { + return; + } + + media_stream = new NetStream(media_conn); + media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { + log("NetStream: code=" + evt.info.code); + + if (evt.info.code == "NetStream.Video.DimensionChange") { + owner.on_player_dimension_change(); + } else if (evt.info.code == "NetStream.Buffer.Empty") { + owner.on_player_buffer_empty(); + } else if (evt.info.code == "NetStream.Buffer.Full") { + owner.on_player_buffer_full(); + } + + // TODO: FIXME: failed event. + }); + + // setup stream before play. + owner.on_player_before_play(); + + if (url.indexOf("http") == 0) { + media_stream.play(url); + } else { + streamName = url.substr(url.lastIndexOf("/") + 1); + media_stream.play(streamName); + } + + owner.on_player_play(); + }); + + this.media_conn.connect(null); } public function close():void { diff --git a/trunk/research/players/srs_player/src/Utility.as b/trunk/research/players/srs_player/src/Utility.as index f462fded3..8204ee443 100644 --- a/trunk/research/players/srs_player/src/Utility.as +++ b/trunk/research/players/srs_player/src/Utility.as @@ -14,13 +14,19 @@ package public static var logData:String = ""; /** - * initialize the player by flashvars for config. - * @param flashvars the config. + * whether string s endswith f. */ public static function stringEndswith(s:String, f:String):Boolean { return s && f && s.indexOf(f) == s.length - f.length; } + /** + * whether string s startswith f. + */ + public static function stringStartswith(s:String, f:String):Boolean { + return s && f && s.indexOf(f) == 0; + } + /** * write log to trace and console.log. * @param msg the log message. diff --git a/trunk/research/players/srs_player/src/srs_player.as b/trunk/research/players/srs_player/src/srs_player.as index a0168e65d..62d0ba407 100755 --- a/trunk/research/players/srs_player/src/srs_player.as +++ b/trunk/research/players/srs_player/src/srs_player.as @@ -429,7 +429,7 @@ package js_call_stop(); // create player. - if (Utility.stringEndswith(url, ".m3u8")) { + if (Utility.stringEndswith(url, ".m3u8") && Utility.stringStartswith(url, "http://")) { player = new M3u8Player(this); log("create M3U8 player."); } else {