winlin

refine srs player, support set the bufferTimeMax.

@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 ////////////////////////////////////////////////////////////////////////////////// 3 //////////////////////////////////////////////////////////////////////////////////
4 4
5 // to query the swf anti cache. 5 // to query the swf anti cache.
6 -function srs_get_version_code() { return "1.25"; } 6 +function srs_get_version_code() { return "1.26"; }
7 7
8 /** 8 /**
9 * player specified size. 9 * player specified size.
@@ -23,6 +23,7 @@ function SrsPlayer(container, width, height, private_object) { @@ -23,6 +23,7 @@ function SrsPlayer(container, width, height, private_object) {
23 this.id = SrsPlayer.__id++; 23 this.id = SrsPlayer.__id++;
24 this.stream_url = null; 24 this.stream_url = null;
25 this.buffer_time = 0.3; // default to 0.3 25 this.buffer_time = 0.3; // default to 0.3
  26 + this.max_buffer_time = this.buffer_time * 3; // default to 3 x bufferTime.
26 this.volume = 1.0; // default to 100% 27 this.volume = 1.0; // default to 100%
27 this.callbackObj = null; 28 this.callbackObj = null;
28 29
@@ -118,8 +119,11 @@ SrsPlayer.prototype.play = function(url, volume) { @@ -118,8 +119,11 @@ SrsPlayer.prototype.play = function(url, volume) {
118 this.volume = volume; 119 this.volume = volume;
119 } 120 }
120 121
121 - this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time, this.volume); 122 + this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time, this.max_buffer_time, this.volume);
122 } 123 }
  124 +/**
  125 + * stop play stream.
  126 + */
123 SrsPlayer.prototype.stop = function() { 127 SrsPlayer.prototype.stop = function() {
124 for (var i = 0; i < SrsPlayer.__players.length; i++) { 128 for (var i = 0; i < SrsPlayer.__players.length; i++) {
125 var player = SrsPlayer.__players[i]; 129 var player = SrsPlayer.__players[i];
@@ -134,9 +138,15 @@ SrsPlayer.prototype.stop = function() { @@ -134,9 +138,15 @@ SrsPlayer.prototype.stop = function() {
134 138
135 this.callbackObj.ref.__stop(); 139 this.callbackObj.ref.__stop();
136 } 140 }
  141 +/**
  142 + * pause the play.
  143 + */
137 SrsPlayer.prototype.pause = function() { 144 SrsPlayer.prototype.pause = function() {
138 this.callbackObj.ref.__pause(); 145 this.callbackObj.ref.__pause();
139 } 146 }
  147 +/**
  148 + * resume the play.
  149 + */
140 SrsPlayer.prototype.resume = function() { 150 SrsPlayer.prototype.resume = function() {
141 this.callbackObj.ref.__resume(); 151 this.callbackObj.ref.__resume();
142 } 152 }
@@ -180,23 +190,75 @@ SrsPlayer.prototype.set_fs = function(refer, percent) { @@ -180,23 +190,75 @@ SrsPlayer.prototype.set_fs = function(refer, percent) {
180 * @buffer_time the buffer time in seconds. 190 * @buffer_time the buffer time in seconds.
181 */ 191 */
182 SrsPlayer.prototype.set_bt = function(buffer_time) { 192 SrsPlayer.prototype.set_bt = function(buffer_time) {
  193 + if (this.buffer_time == buffer_time) {
  194 + return;
  195 + }
  196 +
183 this.buffer_time = buffer_time; 197 this.buffer_time = buffer_time;
184 this.callbackObj.ref.__set_bt(buffer_time); 198 this.callbackObj.ref.__set_bt(buffer_time);
  199 +
  200 + // reset the max buffer time to 3 x buffer_time.
  201 + this.set_mbt(buffer_time * 3);
  202 +}
  203 +/**
  204 + * set the stream max buffer time in seconds.
  205 + * @param max_buffer_time the max buffer time in seconds.
  206 + * @remark this is the key feature for realtime communication by flash.
  207 + */
  208 +SrsPlayer.prototype.set_mbt = function(max_buffer_time) {
  209 + // we must atleast set the max buffer time to 0.6s.
  210 + max_buffer_time = Math.max(0.6, max_buffer_time);
  211 + // max buffer time always greater than buffer time.
  212 + max_buffer_time = Math.max(this.buffer_time, max_buffer_time);
  213 +
  214 + if (parseInt(this.max_buffer_time * 10) == parseInt(max_buffer_time * 10)) {
  215 + return;
  216 + }
  217 +
  218 + this.max_buffer_time = max_buffer_time;
  219 + this.callbackObj.ref.__set_mbt(max_buffer_time);
185 } 220 }
  221 +/**
  222 + * the callback when player is ready.
  223 + */
186 SrsPlayer.prototype.on_player_ready = function() { 224 SrsPlayer.prototype.on_player_ready = function() {
187 } 225 }
  226 +/**
  227 + * the callback when player got metadata.
  228 + * @param metadata the metadata which player got.
  229 + */
188 SrsPlayer.prototype.on_player_metadata = function(metadata) { 230 SrsPlayer.prototype.on_player_metadata = function(metadata) {
189 // ignore. 231 // ignore.
190 } 232 }
  233 +/**
  234 + * the callback when player timer event.
  235 + * @param time current stream time.
  236 + * @param buffer_length current buffer length.
  237 + * @param kbps current video plus audio bitrate in kbps.
  238 + * @param fps current video fps.
  239 + * @param rtime current relative time by flash.util.getTimer().
  240 + */
191 SrsPlayer.prototype.on_player_timer = function(time, buffer_length, kbps, fps, rtime) { 241 SrsPlayer.prototype.on_player_timer = function(time, buffer_length, kbps, fps, rtime) {
192 // ignore. 242 // ignore.
193 } 243 }
  244 +/**
  245 + * the callback when player got NetStream.Buffer.Empty
  246 + * @param time current relative time by flash.util.getTimer().
  247 + */
194 SrsPlayer.prototype.on_player_empty = function(time) { 248 SrsPlayer.prototype.on_player_empty = function(time) {
195 // ignore. 249 // ignore.
196 } 250 }
  251 +/**
  252 + * the callback when player got NetStream.Buffer.Full
  253 + * @param time current relative time by flash.util.getTimer().
  254 + */
197 SrsPlayer.prototype.on_player_full = function(time) { 255 SrsPlayer.prototype.on_player_full = function(time) {
198 // ignore. 256 // ignore.
199 } 257 }
  258 +
  259 +/**
  260 + * helpers.
  261 + */
200 function __srs_find_player(id) { 262 function __srs_find_player(id) {
201 for (var i = 0; i < SrsPlayer.__players.length; i++) { 263 for (var i = 0; i < SrsPlayer.__players.length; i++) {
202 var player = SrsPlayer.__players[i]; 264 var player = SrsPlayer.__players[i];
@@ -284,7 +284,7 @@ @@ -284,7 +284,7 @@
284 <div> 284 <div>
285 <div class="btn-group dropup"> 285 <div class="btn-group dropup">
286 <button class="btn dropdown-toggle" data-toggle="dropdown"> 286 <button class="btn dropdown-toggle" data-toggle="dropdown">
287 - 设置全屏比例大小<span class="caret"></span> 287 + 全屏比例大小<span class="caret"></span>
288 </button> 288 </button>
289 <ul class="dropdown-menu"> 289 <ul class="dropdown-menu">
290 <li><a id="btn_fs_size_screen_100" href="#">屏幕大小(100%)</a></li> 290 <li><a id="btn_fs_size_screen_100" href="#">屏幕大小(100%)</a></li>
@@ -296,7 +296,7 @@ @@ -296,7 +296,7 @@
296 </ul> 296 </ul>
297 </div> 297 </div>
298 <div class="btn-group dropup"> 298 <div class="btn-group dropup">
299 - <button class="btn dropdown-toggle" data-toggle="dropdown">设置显示比例<span class="caret"></span></button> 299 + <button class="btn dropdown-toggle" data-toggle="dropdown">显示比例<span class="caret"></span></button>
300 <ul class="dropdown-menu"> 300 <ul class="dropdown-menu">
301 <li><a id="btn_dar_original" href="#">视频原始比例</a></li> 301 <li><a id="btn_dar_original" href="#">视频原始比例</a></li>
302 <li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li> 302 <li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li>
@@ -306,23 +306,38 @@ @@ -306,23 +306,38 @@
306 </ul> 306 </ul>
307 </div> 307 </div>
308 <div class="btn-group dropup"> 308 <div class="btn-group dropup">
309 - <button class="btn dropdown-toggle" data-toggle="dropdown">设置缓冲区大小<span class="caret"></span></button> 309 + <button class="btn dropdown-toggle" data-toggle="dropdown">缓冲区大小<span class="caret"></span></button>
310 <ul class="dropdown-menu"> 310 <ul class="dropdown-menu">
311 <li><a id="btn_bt_0_1" href="#">0.1秒(实时)</a></li> 311 <li><a id="btn_bt_0_1" href="#">0.1秒(实时)</a></li>
312 <li><a id="btn_bt_0_2" href="#">0.2秒(实时)</a></li> 312 <li><a id="btn_bt_0_2" href="#">0.2秒(实时)</a></li>
313 <li><a id="btn_bt_0_3" href="#">0.3秒(实时)</a></li> 313 <li><a id="btn_bt_0_3" href="#">0.3秒(实时)</a></li>
314 <li><a id="btn_bt_0_5" href="#">0.5秒(实时)</a></li> 314 <li><a id="btn_bt_0_5" href="#">0.5秒(实时)</a></li>
315 <li><a id="btn_bt_0_8" href="#">0.8秒(会议)</a></li> 315 <li><a id="btn_bt_0_8" href="#">0.8秒(会议)</a></li>
316 - <li><a id="btn_bt_1" href="#">1秒(低延迟)</a></li>  
317 - <li><a id="btn_bt_2" href="#">2秒(较低延时)</a></li>  
318 - <li><a id="btn_bt_3" href="#">3秒(流畅播放)</a></li>  
319 - <li><a id="btn_bt_5" href="#">5秒(网速较低)</a></li>  
320 - <li><a id="btn_bt_10" href="#">10秒(无所谓延迟)</a></li>  
321 - <li><a id="btn_bt_30" href="#">30秒(流畅第一)</a></li> 316 + <li><a id="btn_bt_1_0" href="#">1秒(低延迟)</a></li>
  317 + <li><a id="btn_bt_2_0" href="#">2秒(较低延时)</a></li>
  318 + <li><a id="btn_bt_3_0" href="#">3秒(流畅播放)</a></li>
  319 + <li><a id="btn_bt_5_0" href="#">5秒(网速较低)</a></li>
  320 + <li><a id="btn_bt_10_0" href="#">10秒(无所谓延迟)</a></li>
  321 + <li><a id="btn_bt_30_0" href="#">30秒(流畅第一)</a></li>
322 </ul> 322 </ul>
323 </div> 323 </div>
324 <div class="btn-group dropup"> 324 <div class="btn-group dropup">
325 - <a id="btn_fullscreen" class="btn">进入全屏</a> 325 + <button class="btn dropdown-toggle" data-toggle="dropdown">最大缓冲区<span class="caret"></span></button>
  326 + <ul class="dropdown-menu">
  327 + <li><a id="btn_mbt_0_6" href="#">0.6秒(实时)</a></li>
  328 + <li><a id="btn_mbt_0_9" href="#">0.9秒(实时)</a></li>
  329 + <li><a id="btn_mbt_1_5" href="#">1.5秒(实时)</a></li>
  330 + <li><a id="btn_mbt_2_4" href="#">2.4秒(会议)</a></li>
  331 + <li><a id="btn_mbt_3_0" href="#">3秒(低延迟)</a></li>
  332 + <li><a id="btn_mbt_6_0" href="#">6秒(较低延时)</a></li>
  333 + <li><a id="btn_mbt_9_0" href="#">9秒(流畅播放)</a></li>
  334 + <li><a id="btn_mbt_15_0" href="#">15秒(网速较低)</a></li>
  335 + <li><a id="btn_mbt_30_0" href="#">30秒(无所谓延迟)</a></li>
  336 + <li><a id="btn_mbt_90_0" href="#">90秒(流畅第一)</a></li>
  337 + </ul>
  338 + </div>
  339 + <div class="btn-group dropup">
  340 + <a id="btn_fullscreen" class="btn">全屏</a>
326 </div> 341 </div>
327 <div class="btn-group dropup"> 342 <div class="btn-group dropup">
328 <button id="btn_pause" class="btn">暂停播放</button> 343 <button id="btn_pause" class="btn">暂停播放</button>
@@ -337,21 +352,25 @@ @@ -337,21 +352,25 @@
337 由于安全原因,Flash全屏无法使用JS触发 352 由于安全原因,Flash全屏无法使用JS触发
338 </div> 353 </div>
339 <div> 354 <div>
  355 + <div class="input-prepend div_play_time" title="BufferLength/BufferTime/MaxBufferTime">
  356 + <span class="add-on">@B</span>
  357 + <input class="span2" style="width:80px" id="txt_buffer" type="text" placeholder="0/0/0s">
  358 + </div>
340 <div class="input-prepend div_play_time" title="视频的播放流畅度"> 359 <div class="input-prepend div_play_time" title="视频的播放流畅度">
341 <span class="add-on">@F</span> 360 <span class="add-on">@F</span>
342 <input class="span2" style="width:57px" id="txt_fluency" type="text" placeholder="100%"> 361 <input class="span2" style="width:57px" id="txt_fluency" type="text" placeholder="100%">
343 </div> 362 </div>
344 <div class="input-prepend div_play_time" title="视频总共卡顿次数"> 363 <div class="input-prepend div_play_time" title="视频总共卡顿次数">
345 <span class="add-on">@E</span> 364 <span class="add-on">@E</span>
346 - <input class="span2" style="width:85px" id="txt_empty_count" type="text" placeholder="0"> 365 + <input class="span2" style="width:45px" id="txt_empty_count" type="text" placeholder="0">
347 </div> 366 </div>
348 <div class="input-prepend div_play_time" title="视频当前的帧率FPS"> 367 <div class="input-prepend div_play_time" title="视频当前的帧率FPS">
349 <span class="add-on">@F</span> 368 <span class="add-on">@F</span>
350 - <input class="span2" style="width:85px" id="txt_fps" type="text" placeholder="fps"> 369 + <input class="span2" style="width:55px" id="txt_fps" type="text" placeholder="fps">
351 </div> 370 </div>
352 <div class="input-prepend div_play_time" title="视频当前的码率(视频+音频),单位:Kbps"> 371 <div class="input-prepend div_play_time" title="视频当前的码率(视频+音频),单位:Kbps">
353 <span class="add-on">@B</span> 372 <span class="add-on">@B</span>
354 - <input class="span2" style="width:85px" id="txt_bitrate" type="text" placeholder="kbps"> 373 + <input class="span2" style="width:55px" id="txt_bitrate" type="text" placeholder="kbps">
355 </div> 374 </div>
356 <div class="input-prepend div_play_time" title="播放时长,格式:天 时:分:秒"> 375 <div class="input-prepend div_play_time" title="播放时长,格式:天 时:分:秒">
357 <span class="add-on">@T</span> 376 <span class="add-on">@T</span>
@@ -410,6 +429,17 @@ @@ -410,6 +429,17 @@
410 __active_size.addClass("active"); 429 __active_size.addClass("active");
411 } 430 }
412 431
  432 + function select_buffer(buffer_time) {
  433 + var bt = buffer_time;
  434 + var bt_id = "#btn_bt_" + bt.toFixed(1).replace(".", "_");
  435 + select_buffer_time(bt_id, bt);
  436 + }
  437 + function select_max_buffer(max_buffer_time) {
  438 + var mbt = max_buffer_time;
  439 + var mbt_id = "#btn_mbt_" + mbt.toFixed(1).replace(".", "_");
  440 + select_max_buffer_time(mbt_id, mbt);
  441 + }
  442 +
413 var __active_bt = null; 443 var __active_bt = null;
414 function select_buffer_time(bt_id, buffer_time) { 444 function select_buffer_time(bt_id, buffer_time) {
415 srs_player.set_bt(buffer_time); 445 srs_player.set_bt(buffer_time);
@@ -420,6 +450,20 @@ @@ -420,6 +450,20 @@
420 450
421 __active_bt = $(bt_id).parent(); 451 __active_bt = $(bt_id).parent();
422 __active_bt.addClass("active"); 452 __active_bt.addClass("active");
  453 +
  454 + select_max_buffer(srs_player.max_buffer_time);
  455 + }
  456 +
  457 + var __active_mbt = null;
  458 + function select_max_buffer_time(mbt_id, max_buffer_time) {
  459 + srs_player.set_mbt(max_buffer_time);
  460 +
  461 + if (__active_mbt) {
  462 + __active_mbt.removeClass("active");
  463 + }
  464 +
  465 + __active_mbt = $(mbt_id).parent();
  466 + __active_mbt.addClass("active");
423 } 467 }
424 468
425 $(function(){ 469 $(function(){
@@ -447,7 +491,7 @@ @@ -447,7 +491,7 @@
447 491
448 srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height()); 492 srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height());
449 srs_player.on_player_ready = function() { 493 srs_player.on_player_ready = function() {
450 - select_buffer_time("#btn_bt_0_1", 0.1); 494 + select_buffer(0.2);
451 this.play(url); 495 this.play(url);
452 }; 496 };
453 srs_player.on_player_metadata = function(metadata) { 497 srs_player.on_player_metadata = function(metadata) {
@@ -456,16 +500,21 @@ @@ -456,16 +500,21 @@
456 select_fs_size("#btn_fs_size_screen_100", "screen", 100); 500 select_fs_size("#btn_fs_size_screen_100", "screen", 100);
457 }; 501 };
458 srs_player.on_player_timer = function(time, buffer_length, kbps, fps, rtime) { 502 srs_player.on_player_timer = function(time, buffer_length, kbps, fps, rtime) {
459 - var buffer = buffer_length / this.buffer_time * 100; 503 + var buffer = buffer_length / this.max_buffer_time * 100;
460 $("#pb_buffer").width(Number(buffer).toFixed(1) + "%"); 504 $("#pb_buffer").width(Number(buffer).toFixed(1) + "%");
461 505
462 $("#pb_buffer_bg").attr("title", 506 $("#pb_buffer_bg").attr("title",
463 - "缓冲区长度:" + Number(buffer_length).toFixed(1) + "秒("  
464 - + Number(buffer).toFixed(1) + "%)"); 507 + "缓冲区:" + buffer_length.toFixed(1) + "秒, 最大缓冲区:"
  508 + + this.max_buffer_time.toFixed(1) + "秒, 当前:"
  509 + + buffer.toFixed(1) + "%");
465 510
466 - $("#txt_bitrate").val(kbps.toFixed(1) + "kbps"); 511 + var bts = this.buffer_time >= 1? this.buffer_time.toFixed(0) : this.buffer_time.toFixed(1);
  512 + var mbts = this.buffer_time >= 1? this.max_buffer_time.toFixed(0) : this.max_buffer_time.toFixed(1);
  513 + $("#txt_buffer").val(buffer_length.toFixed(1) + "/" + bts + "/" + mbts + "s");
  514 +
  515 + $("#txt_bitrate").val(kbps.toFixed(0) + "kbps");
467 $("#txt_fps").val(fps.toFixed(1) + "fps"); 516 $("#txt_fps").val(fps.toFixed(1) + "fps");
468 - $("#txt_empty_count").val(srs_player.empty_count() + "次卡顿"); 517 + $("#txt_empty_count").val(srs_player.empty_count() + "次");
469 $("#txt_fluency").val(srs_player.fluency().toFixed(2) + "%"); 518 $("#txt_fluency").val(srs_player.fluency().toFixed(2) + "%");
470 519
471 var time_str = ""; 520 var time_str = "";
@@ -619,39 +668,32 @@ @@ -619,39 +668,32 @@
619 } 668 }
620 669
621 if (true) { 670 if (true) {
622 - $("#btn_bt_0_1").click(function(){  
623 - select_buffer_time("#btn_bt_0_1", 0.1);  
624 - });  
625 - $("#btn_bt_0_2").click(function(){  
626 - select_buffer_time("#btn_bt_0_2", 0.2);  
627 - });  
628 - $("#btn_bt_0_3").click(function(){  
629 - select_buffer_time("#btn_bt_0_3", 0.3);  
630 - });  
631 - $("#btn_bt_0_5").click(function(){  
632 - select_buffer_time("#btn_bt_0_5", 0.5);  
633 - });  
634 - $("#btn_bt_0_8").click(function(){  
635 - select_buffer_time("#btn_bt_0_8", 0.8);  
636 - });  
637 - $("#btn_bt_1").click(function(){  
638 - select_buffer_time("#btn_bt_1", 1);  
639 - });  
640 - $("#btn_bt_2").click(function(){  
641 - select_buffer_time("#btn_bt_2", 2);  
642 - });  
643 - $("#btn_bt_3").click(function(){  
644 - select_buffer_time("#btn_bt_3", 3);  
645 - });  
646 - $("#btn_bt_5").click(function(){  
647 - select_buffer_time("#btn_bt_5", 5);  
648 - });  
649 - $("#btn_bt_10").click(function(){  
650 - select_buffer_time("#btn_bt_10", 10); 671 + var bts = [0.1, 0.2, 0.3, 0.5, 0.8, 1, 2, 3, 5, 10, 30];
  672 + for (var i = 0; i < bts.length; i++) {
  673 + var bt = bts[i];
  674 + var bt_id = "#btn_bt_" + bt.toFixed(1).replace(".", "_");
  675 +
  676 + var bt_fun = function(id, v){
  677 + $(bt_id).click(function(){
  678 + select_buffer_time(id, v);
651 }); 679 });
652 - $("#btn_bt_30").click(function(){  
653 - select_buffer_time("#btn_bt_30", 30); 680 + };
  681 + bt_fun(bt_id, bt);
  682 + }
  683 + }
  684 + if (true) {
  685 + var mbts = [0.6, 0.9, 1.5, 2.4, 3, 6, 9, 15, 30, 90];
  686 + for (var i = 0; i < mbts.length; i++) {
  687 + var mbt = mbts[i];
  688 + var mbt_id = "#btn_mbt_" + mbt.toFixed(1).replace(".", "_");
  689 +
  690 + var mbt_fun = function(id, v){
  691 + $(mbt_id).click(function(){
  692 + select_max_buffer_time(id, v);
654 }); 693 });
  694 + };
  695 + mbt_fun(mbt_id, mbt);
  696 + }
655 } 697 }
656 698
657 var query = parse_query_string(); 699 var query = parse_query_string();
@@ -123,6 +123,7 @@ package @@ -123,6 +123,7 @@ package
123 flash.external.ExternalInterface.addCallback("__set_dar", this.js_call_set_dar); 123 flash.external.ExternalInterface.addCallback("__set_dar", this.js_call_set_dar);
124 flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size); 124 flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size);
125 flash.external.ExternalInterface.addCallback("__set_bt", this.js_call_set_bt); 125 flash.external.ExternalInterface.addCallback("__set_bt", this.js_call_set_bt);
  126 + flash.external.ExternalInterface.addCallback("__set_mbt", this.js_call_set_mbt);
126 127
127 flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id); 128 flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id);
128 } 129 }
@@ -228,6 +229,7 @@ package @@ -228,6 +229,7 @@ package
228 private function js_call_pause():void { 229 private function js_call_pause():void {
229 if (this.media_stream) { 230 if (this.media_stream) {
230 this.media_stream.pause(); 231 this.media_stream.pause();
  232 + log("user pause play");
231 } 233 }
232 } 234 }
233 235
@@ -237,6 +239,7 @@ package @@ -237,6 +239,7 @@ package
237 private function js_call_resume():void { 239 private function js_call_resume():void {
238 if (this.media_stream) { 240 if (this.media_stream) {
239 this.media_stream.resume(); 241 this.media_stream.resume();
  242 + log("user resume play");
240 } 243 }
241 } 244 }
242 245
@@ -254,6 +257,7 @@ package @@ -254,6 +257,7 @@ package
254 user_dar_den = den; 257 user_dar_den = den;
255 258
256 flash.utils.setTimeout(__execute_user_set_dar, 0); 259 flash.utils.setTimeout(__execute_user_set_dar, 0);
  260 + log("user set dar to " + num + "/" + den);
257 } 261 }
258 262
259 /** 263 /**
@@ -267,6 +271,7 @@ package @@ -267,6 +271,7 @@ package
267 private function js_call_set_fs_size(refer:String, percent:int):void { 271 private function js_call_set_fs_size(refer:String, percent:int):void {
268 user_fs_refer = refer; 272 user_fs_refer = refer;
269 user_fs_percent = percent; 273 user_fs_percent = percent;
  274 + log("user set refer to " + refer + ", percent to" + percent);
270 } 275 }
271 276
272 /** 277 /**
@@ -276,6 +281,19 @@ package @@ -276,6 +281,19 @@ package
276 private function js_call_set_bt(buffer_time:Number):void { 281 private function js_call_set_bt(buffer_time:Number):void {
277 if (this.media_stream) { 282 if (this.media_stream) {
278 this.media_stream.bufferTime = buffer_time; 283 this.media_stream.bufferTime = buffer_time;
  284 + log("user set bufferTime to " + buffer_time.toFixed(2) + "s");
  285 + }
  286 + }
  287 +
  288 + /**
  289 + * set the max stream buffer time in seconds.
  290 + * @max_buffer_time the max buffer time in seconds.
  291 + * @remark this is the key feature for realtime communication by flash.
  292 + */
  293 + private function js_call_set_mbt(max_buffer_time:Number):void {
  294 + if (this.media_stream) {
  295 + this.media_stream.bufferTimeMax = max_buffer_time;
  296 + log("user set bufferTimeMax to " + max_buffer_time.toFixed(2) + "s");
279 } 297 }
280 } 298 }
281 299
@@ -335,13 +353,16 @@ package @@ -335,13 +353,16 @@ package
335 * @param _width, the player width. 353 * @param _width, the player width.
336 * @param _height, the player height. 354 * @param _height, the player height.
337 * @param buffer_time, the buffer time in seconds. recommend to >=0.5 355 * @param buffer_time, the buffer time in seconds. recommend to >=0.5
  356 + * @param max_buffer_time, the max buffer time in seconds. recommend to 3 x buffer_time.
338 * @param volume, the volume, 0 is mute, 1 is 100%, 2 is 200%. 357 * @param volume, the volume, 0 is mute, 1 is 100%, 2 is 200%.
339 */ 358 */
340 - private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, volume:Number):void { 359 + private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, max_buffer_time:Number, volume:Number):void {
341 this.user_url = url; 360 this.user_url = url;
342 this.user_w = _width; 361 this.user_w = _width;
343 this.user_h = _height; 362 this.user_h = _height;
344 - log("start to play url: " + this.user_url + ", w=" + this.user_w + ", h=" + this.user_h); 363 + log("start to play url: " + this.user_url + ", w=" + this.user_w + ", h=" + this.user_h
  364 + + ", buffer=" + buffer_time.toFixed(2) + "s, max_buffer=" + max_buffer_time.toFixed(2) + "s, volume=" + volume.toFixed(2)
  365 + );
345 366
346 js_call_stop(); 367 js_call_stop();
347 368
@@ -349,7 +370,7 @@ package @@ -349,7 +370,7 @@ package
349 this.media_conn.client = {}; 370 this.media_conn.client = {};
350 this.media_conn.client.onBWDone = function():void {}; 371 this.media_conn.client.onBWDone = function():void {};
351 this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { 372 this.media_conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
352 - trace ("NetConnection: code=" + evt.info.code); 373 + log("NetConnection: code=" + evt.info.code);
353 374
354 if (evt.info.hasOwnProperty("data") && evt.info.data) { 375 if (evt.info.hasOwnProperty("data") && evt.info.data) {
355 if (evt.info.data.hasOwnProperty("srs_server")) { 376 if (evt.info.data.hasOwnProperty("srs_server")) {
@@ -381,10 +402,11 @@ package @@ -381,10 +402,11 @@ package
381 media_stream = new NetStream(media_conn); 402 media_stream = new NetStream(media_conn);
382 media_stream.soundTransform = new SoundTransform(volume); 403 media_stream.soundTransform = new SoundTransform(volume);
383 media_stream.bufferTime = buffer_time; 404 media_stream.bufferTime = buffer_time;
  405 + media_stream.bufferTimeMax = max_buffer_time;
384 media_stream.client = {}; 406 media_stream.client = {};
385 media_stream.client.onMetaData = system_on_metadata; 407 media_stream.client.onMetaData = system_on_metadata;
386 media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { 408 media_stream.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
387 - trace ("NetStream: code=" + evt.info.code); 409 + log("NetStream: code=" + evt.info.code);
388 410
389 if (evt.info.code == "NetStream.Video.DimensionChange") { 411 if (evt.info.code == "NetStream.Video.DimensionChange") {
390 system_on_metadata(media_metadata); 412 system_on_metadata(media_metadata);