diff --git a/trunk/research/players/js/srs.page.js b/trunk/research/players/js/srs.page.js index 842db7f04..81942ebdd 100755 --- a/trunk/research/players/js/srs.page.js +++ b/trunk/research/players/js/srs.page.js @@ -3,7 +3,7 @@ ////////////////////////////////////////////////////////////////////////////////// // to query the swf anti cache. -function srs_get_version_code() { return "1.25"; } +function srs_get_version_code() { return "1.26"; } /** * player specified size. diff --git a/trunk/research/players/js/srs.player.js b/trunk/research/players/js/srs.player.js index 91dea7f16..c7dd9d972 100755 --- a/trunk/research/players/js/srs.player.js +++ b/trunk/research/players/js/srs.player.js @@ -23,6 +23,7 @@ function SrsPlayer(container, width, height, private_object) { this.id = SrsPlayer.__id++; this.stream_url = null; this.buffer_time = 0.3; // default to 0.3 + this.max_buffer_time = this.buffer_time * 3; // default to 3 x bufferTime. this.volume = 1.0; // default to 100% this.callbackObj = null; @@ -118,8 +119,11 @@ SrsPlayer.prototype.play = function(url, volume) { this.volume = volume; } - this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time, this.volume); + this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time, this.max_buffer_time, this.volume); } +/** + * stop play stream. + */ SrsPlayer.prototype.stop = function() { for (var i = 0; i < SrsPlayer.__players.length; i++) { var player = SrsPlayer.__players[i]; @@ -134,9 +138,15 @@ SrsPlayer.prototype.stop = function() { this.callbackObj.ref.__stop(); } +/** + * pause the play. + */ SrsPlayer.prototype.pause = function() { this.callbackObj.ref.__pause(); } +/** + * resume the play. + */ SrsPlayer.prototype.resume = function() { this.callbackObj.ref.__resume(); } @@ -180,23 +190,75 @@ SrsPlayer.prototype.set_fs = function(refer, percent) { * @buffer_time the buffer time in seconds. */ SrsPlayer.prototype.set_bt = function(buffer_time) { + if (this.buffer_time == buffer_time) { + return; + } + this.buffer_time = buffer_time; this.callbackObj.ref.__set_bt(buffer_time); + + // reset the max buffer time to 3 x buffer_time. + this.set_mbt(buffer_time * 3); +} +/** + * set the stream max buffer time in seconds. + * @param max_buffer_time the max buffer time in seconds. + * @remark this is the key feature for realtime communication by flash. + */ +SrsPlayer.prototype.set_mbt = function(max_buffer_time) { + // we must atleast set the max buffer time to 0.6s. + max_buffer_time = Math.max(0.6, max_buffer_time); + // max buffer time always greater than buffer time. + max_buffer_time = Math.max(this.buffer_time, max_buffer_time); + + if (parseInt(this.max_buffer_time * 10) == parseInt(max_buffer_time * 10)) { + return; + } + + this.max_buffer_time = max_buffer_time; + this.callbackObj.ref.__set_mbt(max_buffer_time); } +/** + * the callback when player is ready. + */ SrsPlayer.prototype.on_player_ready = function() { } +/** + * the callback when player got metadata. + * @param metadata the metadata which player got. + */ SrsPlayer.prototype.on_player_metadata = function(metadata) { // ignore. } +/** + * the callback when player timer event. + * @param time current stream time. + * @param buffer_length current buffer length. + * @param kbps current video plus audio bitrate in kbps. + * @param fps current video fps. + * @param rtime current relative time by flash.util.getTimer(). + */ SrsPlayer.prototype.on_player_timer = function(time, buffer_length, kbps, fps, rtime) { // ignore. } +/** + * the callback when player got NetStream.Buffer.Empty + * @param time current relative time by flash.util.getTimer(). + */ SrsPlayer.prototype.on_player_empty = function(time) { // ignore. } +/** + * the callback when player got NetStream.Buffer.Full + * @param time current relative time by flash.util.getTimer(). + */ SrsPlayer.prototype.on_player_full = function(time) { // ignore. } + +/** + * helpers. + */ function __srs_find_player(id) { for (var i = 0; i < SrsPlayer.__players.length; i++) { var player = SrsPlayer.__players[i]; diff --git a/trunk/research/players/srs_player.html b/trunk/research/players/srs_player.html index 6668e02c8..ca3ee0140 100755 --- a/trunk/research/players/srs_player.html +++ b/trunk/research/players/srs_player.html @@ -284,7 +284,7 @@
- +
- +
- 进入全屏 + + +
+
+ 全屏
@@ -337,21 +352,25 @@ 由于安全原因,Flash全屏无法使用JS触发
+
+ @B + +
@F
@E - +
@F - +
@B - +
@T @@ -410,6 +429,17 @@ __active_size.addClass("active"); } + function select_buffer(buffer_time) { + var bt = buffer_time; + var bt_id = "#btn_bt_" + bt.toFixed(1).replace(".", "_"); + select_buffer_time(bt_id, bt); + } + function select_max_buffer(max_buffer_time) { + var mbt = max_buffer_time; + var mbt_id = "#btn_mbt_" + mbt.toFixed(1).replace(".", "_"); + select_max_buffer_time(mbt_id, mbt); + } + var __active_bt = null; function select_buffer_time(bt_id, buffer_time) { srs_player.set_bt(buffer_time); @@ -420,6 +450,20 @@ __active_bt = $(bt_id).parent(); __active_bt.addClass("active"); + + select_max_buffer(srs_player.max_buffer_time); + } + + var __active_mbt = null; + function select_max_buffer_time(mbt_id, max_buffer_time) { + srs_player.set_mbt(max_buffer_time); + + if (__active_mbt) { + __active_mbt.removeClass("active"); + } + + __active_mbt = $(mbt_id).parent(); + __active_mbt.addClass("active"); } $(function(){ @@ -447,7 +491,7 @@ srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height()); srs_player.on_player_ready = function() { - select_buffer_time("#btn_bt_0_1", 0.1); + select_buffer(0.2); this.play(url); }; srs_player.on_player_metadata = function(metadata) { @@ -456,16 +500,21 @@ select_fs_size("#btn_fs_size_screen_100", "screen", 100); }; srs_player.on_player_timer = function(time, buffer_length, kbps, fps, rtime) { - var buffer = buffer_length / this.buffer_time * 100; + var buffer = buffer_length / this.max_buffer_time * 100; $("#pb_buffer").width(Number(buffer).toFixed(1) + "%"); $("#pb_buffer_bg").attr("title", - "缓冲区长度:" + Number(buffer_length).toFixed(1) + "秒(" - + Number(buffer).toFixed(1) + "%)"); + "缓冲区:" + buffer_length.toFixed(1) + "秒, 最大缓冲区:" + + this.max_buffer_time.toFixed(1) + "秒, 当前:" + + buffer.toFixed(1) + "%"); + + var bts = this.buffer_time >= 1? this.buffer_time.toFixed(0) : this.buffer_time.toFixed(1); + var mbts = this.buffer_time >= 1? this.max_buffer_time.toFixed(0) : this.max_buffer_time.toFixed(1); + $("#txt_buffer").val(buffer_length.toFixed(1) + "/" + bts + "/" + mbts + "s"); - $("#txt_bitrate").val(kbps.toFixed(1) + "kbps"); + $("#txt_bitrate").val(kbps.toFixed(0) + "kbps"); $("#txt_fps").val(fps.toFixed(1) + "fps"); - $("#txt_empty_count").val(srs_player.empty_count() + "次卡顿"); + $("#txt_empty_count").val(srs_player.empty_count() + "次"); $("#txt_fluency").val(srs_player.fluency().toFixed(2) + "%"); var time_str = ""; @@ -619,39 +668,32 @@ } if (true) { - $("#btn_bt_0_1").click(function(){ - select_buffer_time("#btn_bt_0_1", 0.1); - }); - $("#btn_bt_0_2").click(function(){ - select_buffer_time("#btn_bt_0_2", 0.2); - }); - $("#btn_bt_0_3").click(function(){ - select_buffer_time("#btn_bt_0_3", 0.3); - }); - $("#btn_bt_0_5").click(function(){ - select_buffer_time("#btn_bt_0_5", 0.5); - }); - $("#btn_bt_0_8").click(function(){ - select_buffer_time("#btn_bt_0_8", 0.8); - }); - $("#btn_bt_1").click(function(){ - select_buffer_time("#btn_bt_1", 1); - }); - $("#btn_bt_2").click(function(){ - select_buffer_time("#btn_bt_2", 2); - }); - $("#btn_bt_3").click(function(){ - select_buffer_time("#btn_bt_3", 3); - }); - $("#btn_bt_5").click(function(){ - select_buffer_time("#btn_bt_5", 5); - }); - $("#btn_bt_10").click(function(){ - select_buffer_time("#btn_bt_10", 10); - }); - $("#btn_bt_30").click(function(){ - select_buffer_time("#btn_bt_30", 30); - }); + var bts = [0.1, 0.2, 0.3, 0.5, 0.8, 1, 2, 3, 5, 10, 30]; + for (var i = 0; i < bts.length; i++) { + var bt = bts[i]; + var bt_id = "#btn_bt_" + bt.toFixed(1).replace(".", "_"); + + var bt_fun = function(id, v){ + $(bt_id).click(function(){ + select_buffer_time(id, v); + }); + }; + bt_fun(bt_id, bt); + } + } + if (true) { + var mbts = [0.6, 0.9, 1.5, 2.4, 3, 6, 9, 15, 30, 90]; + for (var i = 0; i < mbts.length; i++) { + var mbt = mbts[i]; + var mbt_id = "#btn_mbt_" + mbt.toFixed(1).replace(".", "_"); + + var mbt_fun = function(id, v){ + $(mbt_id).click(function(){ + select_max_buffer_time(id, v); + }); + }; + mbt_fun(mbt_id, mbt); + } } var query = parse_query_string(); diff --git a/trunk/research/players/srs_player/release/srs_player.swf b/trunk/research/players/srs_player/release/srs_player.swf index 20e7302bc..5516be33b 100755 Binary files a/trunk/research/players/srs_player/release/srs_player.swf and b/trunk/research/players/srs_player/release/srs_player.swf differ diff --git a/trunk/research/players/srs_player/src/srs_player.as b/trunk/research/players/srs_player/src/srs_player.as index 27513f0db..bb7db70ff 100755 --- a/trunk/research/players/srs_player/src/srs_player.as +++ b/trunk/research/players/srs_player/src/srs_player.as @@ -123,6 +123,7 @@ package flash.external.ExternalInterface.addCallback("__set_dar", this.js_call_set_dar); flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size); flash.external.ExternalInterface.addCallback("__set_bt", this.js_call_set_bt); + flash.external.ExternalInterface.addCallback("__set_mbt", this.js_call_set_mbt); flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id); } @@ -228,6 +229,7 @@ package private function js_call_pause():void { if (this.media_stream) { this.media_stream.pause(); + log("user pause play"); } } @@ -237,6 +239,7 @@ package private function js_call_resume():void { if (this.media_stream) { this.media_stream.resume(); + log("user resume play"); } } @@ -254,6 +257,7 @@ package user_dar_den = den; flash.utils.setTimeout(__execute_user_set_dar, 0); + log("user set dar to " + num + "/" + den); } /** @@ -267,6 +271,7 @@ package private function js_call_set_fs_size(refer:String, percent:int):void { user_fs_refer = refer; user_fs_percent = percent; + log("user set refer to " + refer + ", percent to" + percent); } /** @@ -276,8 +281,21 @@ package private function js_call_set_bt(buffer_time:Number):void { if (this.media_stream) { this.media_stream.bufferTime = buffer_time; + log("user set bufferTime to " + buffer_time.toFixed(2) + "s"); } } + + /** + * set the max stream buffer time in seconds. + * @max_buffer_time the max buffer time in seconds. + * @remark this is the key feature for realtime communication by flash. + */ + private function js_call_set_mbt(max_buffer_time:Number):void { + if (this.media_stream) { + this.media_stream.bufferTimeMax = max_buffer_time; + log("user set bufferTimeMax to " + max_buffer_time.toFixed(2) + "s"); + } + } /** * function for js to call: to stop the stream. ignore if not play. @@ -335,13 +353,16 @@ package * @param _width, the player width. * @param _height, the player height. * @param buffer_time, the buffer time in seconds. recommend to >=0.5 + * @param max_buffer_time, the max buffer time in seconds. recommend to 3 x buffer_time. * @param volume, the volume, 0 is mute, 1 is 100%, 2 is 200%. */ - private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, volume:Number):void { + private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, max_buffer_time:Number, volume:Number):void { this.user_url = url; this.user_w = _width; this.user_h = _height; - log("start to play url: " + this.user_url + ", w=" + this.user_w + ", h=" + this.user_h); + log("start to play url: " + this.user_url + ", w=" + this.user_w + ", h=" + this.user_h + + ", buffer=" + buffer_time.toFixed(2) + "s, max_buffer=" + max_buffer_time.toFixed(2) + "s, volume=" + volume.toFixed(2) + ); js_call_stop(); @@ -349,7 +370,7 @@ package this.media_conn.client = {}; this.media_conn.client.onBWDone = function():void {}; this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { - trace ("NetConnection: code=" + evt.info.code); + log("NetConnection: code=" + evt.info.code); if (evt.info.hasOwnProperty("data") && evt.info.data) { if (evt.info.data.hasOwnProperty("srs_server")) { @@ -381,10 +402,11 @@ package media_stream = new NetStream(media_conn); media_stream.soundTransform = new SoundTransform(volume); media_stream.bufferTime = buffer_time; + media_stream.bufferTimeMax = max_buffer_time; media_stream.client = {}; media_stream.client.onMetaData = system_on_metadata; media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { - trace ("NetStream: code=" + evt.info.code); + log("NetStream: code=" + evt.info.code); if (evt.info.code == "NetStream.Video.DimensionChange") { system_on_metadata(media_metadata);