winlin

add buffer time and play time display

1 /** 1 /**
  2 +* padding the output.
  3 +* padding(3, 5, '0') is 00003
  4 +* padding(3, 5, 'x') is xxxx3
  5 +* @see http://blog.csdn.net/win_lin/article/details/12065413
  6 +*/
  7 +function padding(number, length, prefix) {
  8 + if(String(number).length >= length){
  9 + return String(number);
  10 + }
  11 + return padding(prefix+number, length, prefix);
  12 +}
  13 +
  14 +/**
2 * update the navigator, add same query string. 15 * update the navigator, add same query string.
3 */ 16 */
4 function update_nav() { 17 function update_nav() {
@@ -88,7 +101,7 @@ function srs_init(rtmp_url, hls_url) { @@ -88,7 +101,7 @@ function srs_init(rtmp_url, hls_url) {
88 /** 101 /**
89 * the SrsPlayer object. 102 * the SrsPlayer object.
90 */ 103 */
91 -function SrsPlayer(container, stream_url, width, height, buffer_time) { 104 +function SrsPlayer(container, stream_url, width, height) {
92 if (!SrsPlayer.__id) { 105 if (!SrsPlayer.__id) {
93 SrsPlayer.__id = 100; 106 SrsPlayer.__id = 100;
94 } 107 }
@@ -102,12 +115,14 @@ function SrsPlayer(container, stream_url, width, height, buffer_time) { @@ -102,12 +115,14 @@ function SrsPlayer(container, stream_url, width, height, buffer_time) {
102 this.stream_url = stream_url; 115 this.stream_url = stream_url;
103 this.width = width; 116 this.width = width;
104 this.height = height; 117 this.height = height;
105 - this.buffer_time = buffer_time;  
106 this.id = SrsPlayer.__id++; 118 this.id = SrsPlayer.__id++;
107 this.callbackObj = null; 119 this.callbackObj = null;
  120 + this.buffer_time = 0.8; // default to 0.8
108 121
109 // callback set the following values. 122 // callback set the following values.
110 this.meatadata = {}; // for on_player_metadata 123 this.meatadata = {}; // for on_player_metadata
  124 + this.time = 0; // current stream time.
  125 + this.buffer_length = 0; // current stream buffer length.
111 } 126 }
112 /** 127 /**
113 * user can set some callback, then start the player. 128 * user can set some callback, then start the player.
@@ -121,6 +136,7 @@ SrsPlayer.prototype.start = function() { @@ -121,6 +136,7 @@ SrsPlayer.prototype.start = function() {
121 flashvars.id = this.id; 136 flashvars.id = this.id;
122 flashvars.on_player_ready = "__srs_on_player_ready"; 137 flashvars.on_player_ready = "__srs_on_player_ready";
123 flashvars.on_player_metadata = "__srs_on_player_metadata"; 138 flashvars.on_player_metadata = "__srs_on_player_metadata";
  139 + flashvars.on_player_timer = "__srs_on_player_timer";
124 140
125 var params = {}; 141 var params = {};
126 params.wmode = "opaque"; 142 params.wmode = "opaque";
@@ -144,7 +160,7 @@ SrsPlayer.prototype.start = function() { @@ -144,7 +160,7 @@ SrsPlayer.prototype.start = function() {
144 return this; 160 return this;
145 } 161 }
146 SrsPlayer.prototype.play = function() { 162 SrsPlayer.prototype.play = function() {
147 - return this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time); 163 + this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time);
148 } 164 }
149 SrsPlayer.prototype.stop = function() { 165 SrsPlayer.prototype.stop = function() {
150 for (var i = 0; i < SrsPlayer.__players.length; i++) { 166 for (var i = 0; i < SrsPlayer.__players.length; i++) {
@@ -157,13 +173,14 @@ SrsPlayer.prototype.stop = function() { @@ -157,13 +173,14 @@ SrsPlayer.prototype.stop = function() {
157 SrsPlayer.__players.splice(i, 1); 173 SrsPlayer.__players.splice(i, 1);
158 break; 174 break;
159 } 175 }
160 - return this.callbackObj.ref.__stop(); 176 +
  177 + this.callbackObj.ref.__stop();
161 } 178 }
162 SrsPlayer.prototype.pause = function() { 179 SrsPlayer.prototype.pause = function() {
163 - return this.callbackObj.ref.__pause(); 180 + this.callbackObj.ref.__pause();
164 } 181 }
165 SrsPlayer.prototype.resume = function() { 182 SrsPlayer.prototype.resume = function() {
166 - return this.callbackObj.ref.__resume(); 183 + this.callbackObj.ref.__resume();
167 } 184 }
168 /** 185 /**
169 * to set the DAR, for example, DAR=16:9 186 * to set the DAR, for example, DAR=16:9
@@ -175,7 +192,7 @@ SrsPlayer.prototype.resume = function() { @@ -175,7 +192,7 @@ SrsPlayer.prototype.resume = function() {
175 * use user specified width if -1. 192 * use user specified width if -1.
176 */ 193 */
177 SrsPlayer.prototype.dar = function(num, den) { 194 SrsPlayer.prototype.dar = function(num, den) {
178 - return this.callbackObj.ref.__dar(num, den); 195 + this.callbackObj.ref.__dar(num, den);
179 } 196 }
180 /** 197 /**
181 * set the fullscreen size data. 198 * set the fullscreen size data.
@@ -186,13 +203,24 @@ SrsPlayer.prototype.dar = function(num, den) { @@ -186,13 +203,24 @@ SrsPlayer.prototype.dar = function(num, den) {
186 * 100 means 100%. 203 * 100 means 100%.
187 */ 204 */
188 SrsPlayer.prototype.set_fs = function(refer, percent) { 205 SrsPlayer.prototype.set_fs = function(refer, percent) {
189 - return this.callbackObj.ref.__set_fs(refer, percent); 206 + this.callbackObj.ref.__set_fs(refer, percent);
  207 +}
  208 +/**
  209 +* set the stream buffer time in seconds.
  210 +* @buffer_time the buffer time in seconds.
  211 +*/
  212 +SrsPlayer.prototype.set_bt = function(buffer_time) {
  213 + this.buffer_time = buffer_time;
  214 + this.callbackObj.ref.__set_bt(buffer_time);
190 } 215 }
191 SrsPlayer.prototype.on_player_ready = function() { 216 SrsPlayer.prototype.on_player_ready = function() {
192 - return this.play(); 217 + this.play();
193 } 218 }
194 SrsPlayer.prototype.on_player_metadata = function(metadata) { 219 SrsPlayer.prototype.on_player_metadata = function(metadata) {
195 - return 0; 220 + // ignore.
  221 +}
  222 +SrsPlayer.prototype.on_player_timer = function(time, buffer_length) {
  223 + // ignore.
196 } 224 }
197 function __srs_on_player_ready(id) { 225 function __srs_on_player_ready(id) {
198 for (var i = 0; i < SrsPlayer.__players.length; i++) { 226 for (var i = 0; i < SrsPlayer.__players.length; i++) {
@@ -202,7 +230,8 @@ function __srs_on_player_ready(id) { @@ -202,7 +230,8 @@ function __srs_on_player_ready(id) {
202 continue; 230 continue;
203 } 231 }
204 232
205 - return player.on_player_ready(); 233 + player.on_player_ready();
  234 + return;
206 } 235 }
207 236
208 throw new Error("player not found. id=" + id); 237 throw new Error("player not found. id=" + id);
@@ -219,7 +248,30 @@ function __srs_on_player_metadata(id, metadata) { @@ -219,7 +248,30 @@ function __srs_on_player_metadata(id, metadata) {
219 // so set the data before invoke it. 248 // so set the data before invoke it.
220 player.metadata = metadata; 249 player.metadata = metadata;
221 250
222 - return player.on_player_metadata(metadata); 251 + player.on_player_metadata(metadata);
  252 + return;
  253 + }
  254 +
  255 + throw new Error("player not found. id=" + id);
  256 +}
  257 +function __srs_on_player_timer(id, time, buffer_length) {
  258 + for (var i = 0; i < SrsPlayer.__players.length; i++) {
  259 + var player = SrsPlayer.__players[i];
  260 +
  261 + if (player.id != id) {
  262 + continue;
  263 + }
  264 +
  265 + buffer_length = Math.max(0, buffer_length);
  266 + buffer_length = Math.min(player.buffer_time, buffer_length);
  267 +
  268 + // user may override the on_player_timer,
  269 + // so set the data before invoke it.
  270 + player.time = time;
  271 + player.buffer_length = buffer_length;
  272 +
  273 + player.on_player_timer(time, buffer_length);
  274 + return;
223 } 275 }
224 276
225 throw new Error("player not found. id=" + id); 277 throw new Error("player not found. id=" + id);
@@ -40,6 +40,18 @@ @@ -40,6 +40,18 @@
40 __active_size.addClass("active"); 40 __active_size.addClass("active");
41 } 41 }
42 42
  43 + var __active_bt = null;
  44 + function select_buffer_time(bt_id, buffer_time) {
  45 + srs_player.set_bt(buffer_time);
  46 +
  47 + if (__active_bt) {
  48 + __active_bt.removeClass("active");
  49 + }
  50 +
  51 + __active_bt = $(bt_id).parent();
  52 + __active_bt.addClass("active");
  53 + }
  54 +
43 $(function(){ 55 $(function(){
44 // get the vhost and port to set the default url. 56 // get the vhost and port to set the default url.
45 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo 57 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
@@ -68,15 +80,38 @@ @@ -68,15 +80,38 @@
68 80
69 var url = $("#txt_url").val(); 81 var url = $("#txt_url").val();
70 82
71 - srs_player = new SrsPlayer("player_id", url, 530, 300, 0.8); 83 + srs_player = new SrsPlayer("player_id", url, 530, 300);
72 srs_player.on_player_ready = function() { 84 srs_player.on_player_ready = function() {
73 - return srs_player.play(); 85 + srs_player.play();
74 } 86 }
75 srs_player.on_player_metadata = function(metadata) { 87 srs_player.on_player_metadata = function(metadata) {
76 $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")"); 88 $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");
77 select_dar("#btn_dar_original", 0, 0); 89 select_dar("#btn_dar_original", 0, 0);
78 select_fs_size("#btn_fs_size_screen_100", "screen", 100); 90 select_fs_size("#btn_fs_size_screen_100", "screen", 100);
79 - return 0; 91 + select_buffer_time("#btn_bt_0_8", 0.8);
  92 + }
  93 + srs_player.on_player_timer = function(time, buffer_length) {
  94 + var buffer = buffer_length / srs_player.buffer_time * 100;
  95 + $("#pb_buffer").width(Number(buffer).toFixed(1) + "%");
  96 +
  97 + $("#pb_buffer_bg").attr("title",
  98 + "缓冲区长度:" + Number(buffer_length).toFixed(1) + "秒("
  99 + + Number(buffer).toFixed(1) + "%)");
  100 +
  101 + var time_str = "";
  102 + // day
  103 + time_str = padding(parseInt(time / 24 / 3600), 2, '0') + " ";
  104 + // hour
  105 + time = time % (24 * 3600);
  106 + time_str += padding(parseInt(time / 3600), 2, '0') + ":";
  107 + // minute
  108 + time = time % (3600);
  109 + time_str += padding(parseInt(time / 60), 2, '0') + ":";
  110 + // seconds
  111 + time = time % (60);
  112 + time_str += padding(parseInt(time), 2, '0');
  113 + // show
  114 + $("#txt_time").val(time_str);
80 } 115 }
81 srs_player.start(); 116 srs_player.start();
82 }); 117 });
@@ -97,11 +132,11 @@ @@ -97,11 +132,11 @@
97 }); 132 });
98 133
99 $("#btn_pause").click(function(){ 134 $("#btn_pause").click(function(){
100 - if ($("#btn_pause").text() == "暂停播放") {  
101 - $("#btn_pause").text("继续播放"); 135 + if ($("#btn_pause").text() == "暂停") {
  136 + $("#btn_pause").text("继续");
102 srs_player.pause(); 137 srs_player.pause();
103 } else { 138 } else {
104 - $("#btn_pause").text("暂停播放"); 139 + $("#btn_pause").text("暂停");
105 srs_player.resume(); 140 srs_player.resume();
106 } 141 }
107 }); 142 });
@@ -144,6 +179,33 @@ @@ -144,6 +179,33 @@
144 select_fs_size("#btn_fs_size_screen_50", "screen", 50); 179 select_fs_size("#btn_fs_size_screen_50", "screen", 50);
145 }); 180 });
146 } 181 }
  182 +
  183 + if (true) {
  184 + $("#btn_bt_0_5").click(function(){
  185 + select_buffer_time("#btn_bt_0_5", 0.5);
  186 + });
  187 + $("#btn_bt_0_8").click(function(){
  188 + select_buffer_time("#btn_bt_0_8", 0.8);
  189 + });
  190 + $("#btn_bt_1").click(function(){
  191 + select_buffer_time("#btn_bt_1", 1);
  192 + });
  193 + $("#btn_bt_2").click(function(){
  194 + select_buffer_time("#btn_bt_2", 2);
  195 + });
  196 + $("#btn_bt_3").click(function(){
  197 + select_buffer_time("#btn_bt_3", 3);
  198 + });
  199 + $("#btn_bt_5").click(function(){
  200 + select_buffer_time("#btn_bt_5", 5);
  201 + });
  202 + $("#btn_bt_10").click(function(){
  203 + select_buffer_time("#btn_bt_10", 10);
  204 + });
  205 + $("#btn_bt_30").click(function(){
  206 + select_buffer_time("#btn_bt_30", 30);
  207 + });
  208 + }
147 }); 209 });
148 </script> 210 </script>
149 </head> 211 </head>
@@ -180,15 +242,23 @@ @@ -180,15 +242,23 @@
180 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 242 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
181 <h3>SrsPlayer</h3> 243 <h3>SrsPlayer</h3>
182 </div> 244 </div>
183 - <div class="modal-body" id="player"> 245 + <div class="modal-body">
  246 + <div id="player"></div>
  247 + <div class="progress progress-striped active" id="pb_buffer_bg">
  248 + <div class="bar" style="width: 0%;" id="pb_buffer"></div>
  249 + </div>
184 </div> 250 </div>
185 - <div class="modal-footer"> 251 + <div class="modal-footer" style="margin-top:-20px;">
  252 + <div class="input-prepend" style="margin-top: 10px;">
  253 + <span class="add-on" title="播放时长">@T</span>
  254 + <input class="span2" style="width:85px" id="txt_time" type="text" placeholder="天 时:分:秒">
  255 + </div>
186 <div class="btn-group dropup"> 256 <div class="btn-group dropup">
187 <button class="btn dropdown-toggle" data-toggle="dropdown"> 257 <button class="btn dropdown-toggle" data-toggle="dropdown">
188 <a id="fs_tips" href="#" data-toggle="tooltip" data-placement="top" title=""> 258 <a id="fs_tips" href="#" data-toggle="tooltip" data-placement="top" title="">
189 <img src="img/tooltip.png"/> 259 <img src="img/tooltip.png"/>
190 </a> 260 </a>
191 - 全屏大小<span class="caret"></span> 261 + 大小<span class="caret"></span>
192 </button> 262 </button>
193 <ul class="dropdown-menu"> 263 <ul class="dropdown-menu">
194 <li><a id="btn_fs_size_screen_100" href="#">屏幕大小(100%)</a></li> 264 <li><a id="btn_fs_size_screen_100" href="#">屏幕大小(100%)</a></li>
@@ -200,7 +270,7 @@ @@ -200,7 +270,7 @@
200 </ul> 270 </ul>
201 </div> 271 </div>
202 <div class="btn-group dropup"> 272 <div class="btn-group dropup">
203 - <button class="btn dropdown-toggle" data-toggle="dropdown">显示比例<span class="caret"></span></button> 273 + <button class="btn dropdown-toggle" data-toggle="dropdown">比例<span class="caret"></span></button>
204 <ul class="dropdown-menu"> 274 <ul class="dropdown-menu">
205 <li><a id="btn_dar_original" href="#">视频原始比例</a></li> 275 <li><a id="btn_dar_original" href="#">视频原始比例</a></li>
206 <li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li> 276 <li><a id="btn_dar_21_9" href="#">宽屏影院(21:9)</a></li>
@@ -210,7 +280,20 @@ @@ -210,7 +280,20 @@
210 </ul> 280 </ul>
211 </div> 281 </div>
212 <div class="btn-group dropup"> 282 <div class="btn-group dropup">
213 - <button id="btn_pause" class="btn">暂停播放</button> 283 + <button class="btn dropdown-toggle" data-toggle="dropdown">缓冲区<span class="caret"></span></button>
  284 + <ul class="dropdown-menu">
  285 + <li><a id="btn_bt_0_5" href="#">0.5秒(实时)</a></li>
  286 + <li><a id="btn_bt_0_8" href="#">0.8秒(会议)</a></li>
  287 + <li><a id="btn_bt_1" href="#">1秒(低延迟)</a></li>
  288 + <li><a id="btn_bt_2" href="#">2秒(较低延时)</a></li>
  289 + <li><a id="btn_bt_3" href="#">3秒(流畅播放)</a></li>
  290 + <li><a id="btn_bt_5" href="#">5秒(网速较低)</a></li>
  291 + <li><a id="btn_bt_10" href="#">10秒(无所谓延迟)</a></li>
  292 + <li><a id="btn_bt_30" href="#">30秒(流畅第一)</a></li>
  293 + </ul>
  294 + </div>
  295 + <div class="btn-group dropup">
  296 + <button id="btn_pause" class="btn">暂停</button>
214 </div> 297 </div>
215 <div class="btn-group dropup"> 298 <div class="btn-group dropup">
216 <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭</button> 299 <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">关闭</button>
@@ -8,6 +8,7 @@ package @@ -8,6 +8,7 @@ package
8 import flash.events.FullScreenEvent; 8 import flash.events.FullScreenEvent;
9 import flash.events.MouseEvent; 9 import flash.events.MouseEvent;
10 import flash.events.NetStatusEvent; 10 import flash.events.NetStatusEvent;
  11 + import flash.events.TimerEvent;
11 import flash.external.ExternalInterface; 12 import flash.external.ExternalInterface;
12 import flash.media.Video; 13 import flash.media.Video;
13 import flash.net.NetConnection; 14 import flash.net.NetConnection;
@@ -15,6 +16,7 @@ package @@ -15,6 +16,7 @@ package
15 import flash.system.Security; 16 import flash.system.Security;
16 import flash.ui.ContextMenu; 17 import flash.ui.ContextMenu;
17 import flash.ui.ContextMenuItem; 18 import flash.ui.ContextMenuItem;
  19 + import flash.utils.Timer;
18 import flash.utils.setTimeout; 20 import flash.utils.setTimeout;
19 21
20 public class srs_player extends Sprite 22 public class srs_player extends Sprite
@@ -24,6 +26,7 @@ package @@ -24,6 +26,7 @@ package
24 // user set callback 26 // user set callback
25 private var on_player_ready:String = null; 27 private var on_player_ready:String = null;
26 private var on_player_metadata:String = null; 28 private var on_player_metadata:String = null;
  29 + private var on_player_timer:String = null;
27 30
28 // play param url. 31 // play param url.
29 private var url:String = null; 32 private var url:String = null;
@@ -41,6 +44,7 @@ package @@ -41,6 +44,7 @@ package
41 private var stream:NetStream = null; 44 private var stream:NetStream = null;
42 private var video:Video = null; 45 private var video:Video = null;
43 private var metadata:Object = {}; 46 private var metadata:Object = {};
  47 + private var timer:Timer = new Timer(300);
44 48
45 // flash donot allow js to set to fullscreen, 49 // flash donot allow js to set to fullscreen,
46 // only allow user click to enter fullscreen. 50 // only allow user click to enter fullscreen.
@@ -82,10 +86,25 @@ package @@ -82,10 +86,25 @@ package
82 this.id = flashvars.id; 86 this.id = flashvars.id;
83 this.on_player_ready = flashvars.on_player_ready; 87 this.on_player_ready = flashvars.on_player_ready;
84 this.on_player_metadata = flashvars.on_player_metadata; 88 this.on_player_metadata = flashvars.on_player_metadata;
  89 + this.on_player_timer = flashvars.on_player_timer;
  90 +
  91 + this.timer.addEventListener(TimerEvent.TIMER, this.on_timer);
  92 + this.timer.start();
85 93
86 flash.utils.setTimeout(this.on_js_ready, 0); 94 flash.utils.setTimeout(this.on_js_ready, 0);
87 } 95 }
88 96
  97 + private function on_timer(evt:TimerEvent):void {
  98 + if (!this.stream) {
  99 + trace("stream is null, ignore timer event.");
  100 + return;
  101 + }
  102 +
  103 + trace("notify js the timer event.");
  104 + flash.external.ExternalInterface.call(
  105 + this.on_player_timer, this.id, this.stream.time, this.stream.bufferLength);
  106 + }
  107 +
89 private function on_stage_fullscreen(evt:FullScreenEvent):void { 108 private function on_stage_fullscreen(evt:FullScreenEvent):void {
90 if (!evt.fullScreen) { 109 if (!evt.fullScreen) {
91 execute_user_set_dar(); 110 execute_user_set_dar();
@@ -107,25 +126,21 @@ package @@ -107,25 +126,21 @@ package
107 flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume); 126 flash.external.ExternalInterface.addCallback("__resume", this.js_call_resume);
108 flash.external.ExternalInterface.addCallback("__dar", this.js_call_dar); 127 flash.external.ExternalInterface.addCallback("__dar", this.js_call_dar);
109 flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size); 128 flash.external.ExternalInterface.addCallback("__set_fs", this.js_call_set_fs_size);
  129 + flash.external.ExternalInterface.addCallback("__set_bt", this.js_call_set_bt);
110 130
111 - var code:int = flash.external.ExternalInterface.call(this.on_player_ready, this.id);  
112 - if (code != 0) {  
113 - throw new Error("callback on_player_ready failed. code=" + code);  
114 - } 131 + flash.external.ExternalInterface.call(this.on_player_ready, this.id);
115 } 132 }
116 133
117 - private function js_call_pause():int { 134 + private function js_call_pause():void {
118 if (this.stream) { 135 if (this.stream) {
119 this.stream.pause(); 136 this.stream.pause();
120 } 137 }
121 - return 0;  
122 } 138 }
123 139
124 - private function js_call_resume():int { 140 + private function js_call_resume():void {
125 if (this.stream) { 141 if (this.stream) {
126 this.stream.resume(); 142 this.stream.resume();
127 } 143 }
128 - return 0;  
129 } 144 }
130 145
131 /** 146 /**
@@ -137,12 +152,11 @@ package @@ -137,12 +152,11 @@ package
137 * use metadata width if 0. 152 * use metadata width if 0.
138 * use user specified width if -1. 153 * use user specified width if -1.
139 */ 154 */
140 - private function js_call_dar(num:int, den:int):int { 155 + private function js_call_dar(num:int, den:int):void {
141 dar_num = num; 156 dar_num = num;
142 dar_den = den; 157 dar_den = den;
143 158
144 flash.utils.setTimeout(execute_user_set_dar, 0); 159 flash.utils.setTimeout(execute_user_set_dar, 0);
145 - return 0;  
146 } 160 }
147 161
148 /** 162 /**
@@ -153,11 +167,9 @@ package @@ -153,11 +167,9 @@ package
153 * @param percent, the rescale percent, where 167 * @param percent, the rescale percent, where
154 * 100 means 100%. 168 * 100 means 100%.
155 */ 169 */
156 - private function js_call_set_fs_size(refer:String, percent:int):int { 170 + private function js_call_set_fs_size(refer:String, percent:int):void {
157 fs_refer = refer; 171 fs_refer = refer;
158 fs_percent = percent; 172 fs_percent = percent;
159 -  
160 - return 0;  
161 } 173 }
162 /** 174 /**
163 * js cannot enter the fullscreen mode, user must click to. 175 * js cannot enter the fullscreen mode, user must click to.
@@ -176,7 +188,17 @@ package @@ -176,7 +188,17 @@ package
176 } 188 }
177 } 189 }
178 190
179 - private function js_call_stop():int { 191 + /**
  192 + * set the stream buffer time in seconds.
  193 + * @buffer_time the buffer time in seconds.
  194 + */
  195 + private function js_call_set_bt(buffer_time:Number):void {
  196 + if (this.stream) {
  197 + this.stream.bufferTime = buffer_time;
  198 + }
  199 + }
  200 +
  201 + private function js_call_stop():void {
180 if (this.stream) { 202 if (this.stream) {
181 this.stream.close(); 203 this.stream.close();
182 this.stream = null; 204 this.stream = null;
@@ -189,8 +211,6 @@ package @@ -189,8 +211,6 @@ package
189 this.removeChild(this.video); 211 this.removeChild(this.video);
190 this.video = null; 212 this.video = null;
191 } 213 }
192 -  
193 - return 0;  
194 } 214 }
195 215
196 private function draw_black_background(_width:int, _height:int):void { 216 private function draw_black_background(_width:int, _height:int):void {
@@ -205,7 +225,7 @@ package @@ -205,7 +225,7 @@ package
205 this.fs_mask.graphics.endFill(); 225 this.fs_mask.graphics.endFill();
206 } 226 }
207 227
208 - private function js_call_play(url:String, _width:int, _height:int, _buffer_time:Number):int { 228 + private function js_call_play(url:String, _width:int, _height:int, _buffer_time:Number):void {
209 this.url = url; 229 this.url = url;
210 this.w = _width; 230 this.w = _width;
211 this.h = _height; 231 this.h = _height;
@@ -218,6 +238,8 @@ package @@ -218,6 +238,8 @@ package
218 this.conn.client.onBWDone = function():void {}; 238 this.conn.client.onBWDone = function():void {};
219 this.conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void { 239 this.conn.addEventListener(NetStatusEvent.NET_STATUS, function(evt:NetStatusEvent):void {
220 trace ("NetConnection: code=" + evt.info.code); 240 trace ("NetConnection: code=" + evt.info.code);
  241 +
  242 + // TODO: FIXME: failed event.
221 if (evt.info.code != "NetConnection.Connect.Success") { 243 if (evt.info.code != "NetConnection.Connect.Success") {
222 return; 244 return;
223 } 245 }
@@ -232,8 +254,12 @@ package @@ -232,8 +254,12 @@ package
232 if (evt.info.code == "NetStream.Video.DimensionChange") { 254 if (evt.info.code == "NetStream.Video.DimensionChange") {
233 on_metadata(metadata); 255 on_metadata(metadata);
234 } 256 }
  257 +
  258 + // TODO: FIXME: failed event.
235 }); 259 });
236 - stream.play(url.substr(url.lastIndexOf("/"))); 260 +
  261 + var streamName:String = url.substr(url.lastIndexOf("/"));
  262 + stream.play(streamName);
237 263
238 video = new Video(); 264 video = new Video();
239 video.width = _width; 265 video.width = _width;
@@ -247,9 +273,9 @@ package @@ -247,9 +273,9 @@ package
247 // lowest layer, for mask to cover it. 273 // lowest layer, for mask to cover it.
248 setChildIndex(video, 0); 274 setChildIndex(video, 0);
249 }); 275 });
250 - this.conn.connect(this.url.substr(0, this.url.lastIndexOf("/")));  
251 276
252 - return 0; 277 + var tcUrl:String = this.url.substr(0, this.url.lastIndexOf("/"));
  278 + this.conn.connect(tcUrl);
253 } 279 }
254 280
255 private function on_metadata(metadata:Object):void { 281 private function on_metadata(metadata:Object):void {