正在显示
15 个修改的文件
包含
152 行增加
和
113 行删除
@@ -276,6 +276,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw | @@ -276,6 +276,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw | ||
276 | * nginx v1.5.0: 139524 lines <br/> | 276 | * nginx v1.5.0: 139524 lines <br/> |
277 | 277 | ||
278 | ### History | 278 | ### History |
279 | +* v0.9, 2013-12-25, fix the bitrate bug(in Bps), use enhanced microphone. | ||
279 | * v0.9, 2013-12-22, demo video meeting or chat(srs+cherrypy+jquery+bootstrap). | 280 | * v0.9, 2013-12-22, demo video meeting or chat(srs+cherrypy+jquery+bootstrap). |
280 | * v0.9, 2013-12-22, merge from wenjie, support banwidth test. | 281 | * v0.9, 2013-12-22, merge from wenjie, support banwidth test. |
281 | * v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level | 282 | * v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/swfobject.js"></script> | 9 | <script type="text/javascript" src="js/swfobject.js"></script> |
10 | <script type="text/javascript" src="js/srs.js"></script> | 10 | <script type="text/javascript" src="js/srs.js"></script> |
11 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
11 | <style> | 12 | <style> |
12 | body{ | 13 | body{ |
13 | padding-top: 55px; | 14 | padding-top: 55px; |
@@ -53,31 +53,6 @@ function update_nav() { | @@ -53,31 +53,6 @@ function update_nav() { | ||
53 | } | 53 | } |
54 | 54 | ||
55 | /** | 55 | /** |
56 | -* log specified, there must be a log element as: | ||
57 | - <!-- for the log --> | ||
58 | - <div class="alert alert-info fade in" id="txt_log"> | ||
59 | - <button type="button" class="close" data-dismiss="alert">×</button> | ||
60 | - <strong><span id="txt_log_title">Usage:</span></strong> | ||
61 | - <span id="txt_log_msg">创建会议室,或者加入会议室</span> | ||
62 | - </div> | ||
63 | -*/ | ||
64 | -function info(desc) { | ||
65 | - $("#txt_log").addClass("alert-info").removeClass("alert-error").removeClass("alert-warn"); | ||
66 | - $("#txt_log_title").text("Info:"); | ||
67 | - $("#txt_log_msg").text(desc); | ||
68 | -} | ||
69 | -function warn(code, desc) { | ||
70 | - $("#txt_log").removeClass("alert-info").removeClass("alert-error").addClass("alert-warn"); | ||
71 | - $("#txt_log_title").text("Warn:"); | ||
72 | - $("#txt_log_msg").text("code: " + code + ", " + desc); | ||
73 | -} | ||
74 | -function error(code, desc) { | ||
75 | - $("#txt_log").removeClass("alert-info").addClass("alert-error").removeClass("alert-warn"); | ||
76 | - $("#txt_log_title").text("Error:"); | ||
77 | - $("#txt_log_msg").text("code: " + code + ", " + desc); | ||
78 | -} | ||
79 | - | ||
80 | -/** | ||
81 | * parse the query string to object. | 56 | * parse the query string to object. |
82 | */ | 57 | */ |
83 | function parse_query_string(){ | 58 | function parse_query_string(){ |
@@ -247,10 +222,8 @@ function srs_init_publish(rtmp_url) { | @@ -247,10 +222,8 @@ function srs_init_publish(rtmp_url) { | ||
247 | } | 222 | } |
248 | } | 223 | } |
249 | 224 | ||
250 | -/** | ||
251 | -* when publisher ready, init the page elements. | ||
252 | -*/ | ||
253 | -function srs_publisher_initialize_page( | 225 | +// without default values set. |
226 | +function srs_initialize_codec_page( | ||
254 | cameras, microphones, | 227 | cameras, microphones, |
255 | sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | 228 | sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate |
256 | ) { | 229 | ) { |
@@ -265,14 +238,36 @@ function srs_publisher_initialize_page( | @@ -265,14 +238,36 @@ function srs_publisher_initialize_page( | ||
265 | break; | 238 | break; |
266 | } | 239 | } |
267 | } | 240 | } |
241 | + // optional: select the first "integrated" signed. | ||
242 | + for (var i = 0; i < cameras.length; i++) { | ||
243 | + if (cameras[i].toLowerCase().indexOf("integrated") >= 0) { | ||
244 | + $(sl_cameras + " option[value='" + i + "']").attr("selected", true); | ||
245 | + break; | ||
246 | + } | ||
247 | + } | ||
268 | 248 | ||
269 | $(sl_microphones).empty(); | 249 | $(sl_microphones).empty(); |
270 | for (var i = 0; i < microphones.length; i++) { | 250 | for (var i = 0; i < microphones.length; i++) { |
271 | $(sl_microphones).append("<option value='" + i + "'>" + microphones[i] + "</option"); | 251 | $(sl_microphones).append("<option value='" + i + "'>" + microphones[i] + "</option"); |
272 | } | 252 | } |
253 | + // optional: select the first no "default" signed. | ||
254 | + for (var i = 0; i < microphones.length; i++) { | ||
255 | + if (microphones[i].toLowerCase().indexOf("default") == -1) { | ||
256 | + $(sl_microphones + " option[value='" + i + "']").attr("selected", true); | ||
257 | + break; | ||
258 | + } | ||
259 | + } | ||
260 | + // optional: select the first "realtek" signed. | ||
261 | + for (var i = 0; i < microphones.length; i++) { | ||
262 | + if (microphones[i].toLowerCase().indexOf("realtek") >= 0) { | ||
263 | + $(sl_microphones + " option[value='" + i + "']").attr("selected", true); | ||
264 | + break; | ||
265 | + } | ||
266 | + } | ||
273 | 267 | ||
274 | $(sl_vcodec).empty(); | 268 | $(sl_vcodec).empty(); |
275 | var vcodecs = ["h264", "vp6"]; | 269 | var vcodecs = ["h264", "vp6"]; |
270 | + vcodecs = ["h264"]; // h264 only. | ||
276 | for (var i = 0; i < vcodecs.length; i++) { | 271 | for (var i = 0; i < vcodecs.length; i++) { |
277 | $(sl_vcodec).append("<option value='" + vcodecs[i] + "'>" + vcodecs[i] + "</option"); | 272 | $(sl_vcodec).append("<option value='" + vcodecs[i] + "'>" + vcodecs[i] + "</option"); |
278 | } | 273 | } |
@@ -282,7 +277,6 @@ function srs_publisher_initialize_page( | @@ -282,7 +277,6 @@ function srs_publisher_initialize_page( | ||
282 | for (var i = 0; i < profiles.length; i++) { | 277 | for (var i = 0; i < profiles.length; i++) { |
283 | $(sl_profile).append("<option value='" + profiles[i] + "'>" + profiles[i] + "</option"); | 278 | $(sl_profile).append("<option value='" + profiles[i] + "'>" + profiles[i] + "</option"); |
284 | } | 279 | } |
285 | - $(sl_profile + " option[value='main']").attr("selected", true); | ||
286 | 280 | ||
287 | $(sl_level).empty(); | 281 | $(sl_level).empty(); |
288 | var levels = ["1", "1b", "1.1", "1.2", "1.3", | 282 | var levels = ["1", "1b", "1.1", "1.2", "1.3", |
@@ -290,7 +284,6 @@ function srs_publisher_initialize_page( | @@ -290,7 +284,6 @@ function srs_publisher_initialize_page( | ||
290 | for (var i = 0; i < levels.length; i++) { | 284 | for (var i = 0; i < levels.length; i++) { |
291 | $(sl_level).append("<option value='" + levels[i] + "'>" + levels[i] + "</option"); | 285 | $(sl_level).append("<option value='" + levels[i] + "'>" + levels[i] + "</option"); |
292 | } | 286 | } |
293 | - $(sl_level + " option[value='4.1']").attr("selected", true); | ||
294 | 287 | ||
295 | $(sl_gop).empty(); | 288 | $(sl_gop).empty(); |
296 | var gops = ["0.3", "0.5", "1", "2", "3", "4", | 289 | var gops = ["0.3", "0.5", "1", "2", "3", "4", |
@@ -298,7 +291,6 @@ function srs_publisher_initialize_page( | @@ -298,7 +291,6 @@ function srs_publisher_initialize_page( | ||
298 | for (var i = 0; i < gops.length; i++) { | 291 | for (var i = 0; i < gops.length; i++) { |
299 | $(sl_gop).append("<option value='" + gops[i] + "'>" + gops[i] + "秒</option"); | 292 | $(sl_gop).append("<option value='" + gops[i] + "'>" + gops[i] + "秒</option"); |
300 | } | 293 | } |
301 | - $(sl_gop + " option[value='10']").attr("selected", true); | ||
302 | 294 | ||
303 | $(sl_size).empty(); | 295 | $(sl_size).empty(); |
304 | var sizes = ["176x144", "320x240", "352x240", | 296 | var sizes = ["176x144", "320x240", "352x240", |
@@ -307,14 +299,12 @@ function srs_publisher_initialize_page( | @@ -307,14 +299,12 @@ function srs_publisher_initialize_page( | ||
307 | for (i = 0; i < sizes.length; i++) { | 299 | for (i = 0; i < sizes.length; i++) { |
308 | $(sl_size).append("<option value='" + sizes[i] + "'>" + sizes[i] + "</option"); | 300 | $(sl_size).append("<option value='" + sizes[i] + "'>" + sizes[i] + "</option"); |
309 | } | 301 | } |
310 | - $(sl_size + " option[value='640x480']").attr("selected", true); | ||
311 | 302 | ||
312 | $(sl_fps).empty(); | 303 | $(sl_fps).empty(); |
313 | var fpses = ["5", "10", "15", "20", "24", "25", "29.97", "30"]; | 304 | var fpses = ["5", "10", "15", "20", "24", "25", "29.97", "30"]; |
314 | for (i = 0; i < fpses.length; i++) { | 305 | for (i = 0; i < fpses.length; i++) { |
315 | $(sl_fps).append("<option value='" + fpses[i] + "'>" + Number(fpses[i]).toFixed(2) + " 帧/秒</option"); | 306 | $(sl_fps).append("<option value='" + fpses[i] + "'>" + Number(fpses[i]).toFixed(2) + " 帧/秒</option"); |
316 | } | 307 | } |
317 | - $(sl_fps + " option[value='20']").attr("selected", true); | ||
318 | 308 | ||
319 | $(sl_bitrate).empty(); | 309 | $(sl_bitrate).empty(); |
320 | var bitrates = ["50", "200", "350", "500", "650", "800", | 310 | var bitrates = ["50", "200", "350", "500", "650", "800", |
@@ -322,6 +312,40 @@ function srs_publisher_initialize_page( | @@ -322,6 +312,40 @@ function srs_publisher_initialize_page( | ||
322 | for (i = 0; i < bitrates.length; i++) { | 312 | for (i = 0; i < bitrates.length; i++) { |
323 | $(sl_bitrate).append("<option value='" + bitrates[i] + "'>" + bitrates[i] + " kbps</option"); | 313 | $(sl_bitrate).append("<option value='" + bitrates[i] + "'>" + bitrates[i] + " kbps</option"); |
324 | } | 314 | } |
315 | +} | ||
316 | +/** | ||
317 | +* when publisher ready, init the page elements. | ||
318 | +*/ | ||
319 | +function srs_publisher_initialize_page( | ||
320 | + cameras, microphones, | ||
321 | + sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | ||
322 | +) { | ||
323 | + srs_initialize_codec_page( | ||
324 | + cameras, microphones, | ||
325 | + sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | ||
326 | + ); | ||
327 | + | ||
328 | + //var profiles = ["baseline", "main"]; | ||
329 | + $(sl_profile + " option[value='main']").attr("selected", true); | ||
330 | + | ||
331 | + //var levels = ["1", "1b", "1.1", "1.2", "1.3", | ||
332 | + // "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1"]; | ||
333 | + $(sl_level + " option[value='4.1']").attr("selected", true); | ||
334 | + | ||
335 | + //var gops = ["0.3", "0.5", "1", "2", "3", "4", | ||
336 | + // "5", "6", "7", "8", "9", "10", "15", "20"]; | ||
337 | + $(sl_gop + " option[value='10']").attr("selected", true); | ||
338 | + | ||
339 | + //var sizes = ["176x144", "320x240", "352x240", | ||
340 | + // "352x288", "460x240", "640x480", "720x480", "720x576", "800x600", | ||
341 | + // "1024x768", "1280x720", "1360x768", "1920x1080"]; | ||
342 | + $(sl_size + " option[value='640x480']").attr("selected", true); | ||
343 | + | ||
344 | + //var fpses = ["5", "10", "15", "20", "24", "25", "29.97", "30"]; | ||
345 | + $(sl_fps + " option[value='20']").attr("selected", true); | ||
346 | + | ||
347 | + //var bitrates = ["50", "200", "350", "500", "650", "800", | ||
348 | + // "950", "1000", "1200", "1500", "1800", "2000", "3000", "5000"]; | ||
325 | $(sl_bitrate + " option[value='500']").attr("selected", true); | 349 | $(sl_bitrate + " option[value='500']").attr("selected", true); |
326 | } | 350 | } |
327 | /** | 351 | /** |
@@ -331,75 +355,33 @@ function srs_chat_initialize_page( | @@ -331,75 +355,33 @@ function srs_chat_initialize_page( | ||
331 | cameras, microphones, | 355 | cameras, microphones, |
332 | sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | 356 | sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate |
333 | ) { | 357 | ) { |
334 | - $(sl_cameras).empty(); | ||
335 | - for (var i = 0; i < cameras.length; i++) { | ||
336 | - $(sl_cameras).append("<option value='" + i + "'>" + cameras[i] + "</option"); | ||
337 | - } | ||
338 | - // optional: select the first no "virtual" signed. | ||
339 | - for (var i = 0; i < cameras.length; i++) { | ||
340 | - if (cameras[i].toLowerCase().indexOf("virtual") == -1) { | ||
341 | - $(sl_cameras + " option[value='" + i + "']").attr("selected", true); | ||
342 | - break; | ||
343 | - } | ||
344 | - } | ||
345 | - | ||
346 | - $(sl_microphones).empty(); | ||
347 | - for (var i = 0; i < microphones.length; i++) { | ||
348 | - $(sl_microphones).append("<option value='" + i + "'>" + microphones[i] + "</option"); | ||
349 | - } | ||
350 | - | ||
351 | - $(sl_vcodec).empty(); | ||
352 | - var vcodecs = ["h264", "vp6"]; | ||
353 | - for (var i = 0; i < vcodecs.length; i++) { | ||
354 | - $(sl_vcodec).append("<option value='" + vcodecs[i] + "'>" + vcodecs[i] + "</option"); | ||
355 | - } | 358 | + srs_initialize_codec_page( |
359 | + cameras, microphones, | ||
360 | + sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | ||
361 | + ); | ||
356 | 362 | ||
357 | - $(sl_profile).empty(); | ||
358 | - var profiles = ["baseline", "main"]; | ||
359 | - for (var i = 0; i < profiles.length; i++) { | ||
360 | - $(sl_profile).append("<option value='" + profiles[i] + "'>" + profiles[i] + "</option"); | ||
361 | - } | 363 | + //var profiles = ["baseline", "main"]; |
362 | $(sl_profile + " option[value='baseline']").attr("selected", true); | 364 | $(sl_profile + " option[value='baseline']").attr("selected", true); |
363 | 365 | ||
364 | - $(sl_level).empty(); | ||
365 | - var levels = ["1", "1b", "1.1", "1.2", "1.3", | ||
366 | - "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1"]; | ||
367 | - for (var i = 0; i < levels.length; i++) { | ||
368 | - $(sl_level).append("<option value='" + levels[i] + "'>" + levels[i] + "</option"); | ||
369 | - } | ||
370 | - $(sl_level + " option[value='3.1']").attr("selected", true); | 366 | + //var levels = ["1", "1b", "1.1", "1.2", "1.3", |
367 | + // "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1"]; | ||
368 | + $(sl_level + " option[value='2.1']").attr("selected", true); | ||
371 | 369 | ||
372 | - $(sl_gop).empty(); | ||
373 | - var gops = ["0.3", "0.5", "1", "2", "3", "4", | ||
374 | - "5", "6", "7", "8", "9", "10", "15", "20"]; | ||
375 | - for (var i = 0; i < gops.length; i++) { | ||
376 | - $(sl_gop).append("<option value='" + gops[i] + "'>" + gops[i] + "秒</option"); | ||
377 | - } | 370 | + //var gops = ["0.3", "0.5", "1", "2", "3", "4", |
371 | + // "5", "6", "7", "8", "9", "10", "15", "20"]; | ||
378 | $(sl_gop + " option[value='0.5']").attr("selected", true); | 372 | $(sl_gop + " option[value='0.5']").attr("selected", true); |
379 | 373 | ||
380 | - $(sl_size).empty(); | ||
381 | - var sizes = ["176x144", "320x240", "352x240", | ||
382 | - "352x288", "460x240", "640x480", "720x480", "720x576", "800x600", | ||
383 | - "1024x768", "1280x720", "1360x768", "1920x1080"]; | ||
384 | - for (i = 0; i < sizes.length; i++) { | ||
385 | - $(sl_size).append("<option value='" + sizes[i] + "'>" + sizes[i] + "</option"); | ||
386 | - } | ||
387 | - $(sl_size + " option[value='460x240']").attr("selected", true); | 374 | + //var sizes = ["176x144", "320x240", "352x240", |
375 | + // "352x288", "460x240", "640x480", "720x480", "720x576", "800x600", | ||
376 | + // "1024x768", "1280x720", "1360x768", "1920x1080"]; | ||
377 | + $(sl_size + " option[value='320x240']").attr("selected", true); | ||
388 | 378 | ||
389 | - $(sl_fps).empty(); | ||
390 | - var fpses = ["5", "10", "15", "20", "24", "25", "29.97", "30"]; | ||
391 | - for (i = 0; i < fpses.length; i++) { | ||
392 | - $(sl_fps).append("<option value='" + fpses[i] + "'>" + Number(fpses[i]).toFixed(2) + " 帧/秒</option"); | ||
393 | - } | ||
394 | - $(sl_fps + " option[value='15']").attr("selected", true); | 379 | + //var fpses = ["5", "10", "15", "20", "24", "25", "29.97", "30"]; |
380 | + $(sl_fps + " option[value='10']").attr("selected", true); | ||
395 | 381 | ||
396 | - $(sl_bitrate).empty(); | ||
397 | - var bitrates = ["50", "200", "350", "500", "650", "800", | ||
398 | - "950", "1000", "1200", "1500", "1800", "2000", "3000", "5000"]; | ||
399 | - for (i = 0; i < bitrates.length; i++) { | ||
400 | - $(sl_bitrate).append("<option value='" + bitrates[i] + "'>" + bitrates[i] + " kbps</option"); | ||
401 | - } | ||
402 | - $(sl_bitrate + " option[value='350']").attr("selected", true); | 382 | + //var bitrates = ["50", "200", "350", "500", "650", "800", |
383 | + // "950", "1000", "1200", "1500", "1800", "2000", "3000", "5000"]; | ||
384 | + $(sl_bitrate + " option[value='200']").attr("selected", true); | ||
403 | } | 385 | } |
404 | /** | 386 | /** |
405 | * get the vcodec and acodec. | 387 | * get the vcodec and acodec. |
@@ -451,6 +433,7 @@ function SrsPlayer(container, width, height, private_object) { | @@ -451,6 +433,7 @@ function SrsPlayer(container, width, height, private_object) { | ||
451 | this.id = SrsPlayer.__id++; | 433 | this.id = SrsPlayer.__id++; |
452 | this.stream_url = null; | 434 | this.stream_url = null; |
453 | this.buffer_time = 0.8; // default to 0.8 | 435 | this.buffer_time = 0.8; // default to 0.8 |
436 | + this.volume = 1.0; // default to 100% | ||
454 | this.callbackObj = null; | 437 | this.callbackObj = null; |
455 | 438 | ||
456 | // callback set the following values. | 439 | // callback set the following values. |
@@ -502,12 +485,19 @@ SrsPlayer.prototype.start = function(url) { | @@ -502,12 +485,19 @@ SrsPlayer.prototype.start = function(url) { | ||
502 | /** | 485 | /** |
503 | * play the stream. | 486 | * play the stream. |
504 | * @param stream_url the url of stream, rtmp or http. | 487 | * @param stream_url the url of stream, rtmp or http. |
488 | +* @param volume the volume, 0 is mute, 1 is 100%, 2 is 200%. | ||
505 | */ | 489 | */ |
506 | -SrsPlayer.prototype.play = function(url) { | 490 | +SrsPlayer.prototype.play = function(url, volume) { |
507 | if (url) { | 491 | if (url) { |
508 | this.stream_url = url; | 492 | this.stream_url = url; |
509 | } | 493 | } |
510 | - this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time); | 494 | + |
495 | + // volume maybe 0, so never use if(volume) to check its value. | ||
496 | + if (volume != null && volume != undefined) { | ||
497 | + this.volume = volume; | ||
498 | + } | ||
499 | + | ||
500 | + this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time, this.volume); | ||
511 | } | 501 | } |
512 | SrsPlayer.prototype.stop = function() { | 502 | SrsPlayer.prototype.stop = function() { |
513 | for (var i = 0; i < SrsPlayer.__players.length; i++) { | 503 | for (var i = 0; i < SrsPlayer.__players.length; i++) { |
@@ -652,7 +642,7 @@ function SrsPublisher(container, width, height, private_object) { | @@ -652,7 +642,7 @@ function SrsPublisher(container, width, height, private_object) { | ||
652 | this.errors = { | 642 | this.errors = { |
653 | "100": "无法获取指定的摄像头", //error_camera_get | 643 | "100": "无法获取指定的摄像头", //error_camera_get |
654 | "101": "无法获取指定的麦克风", //error_microphone_get | 644 | "101": "无法获取指定的麦克风", //error_microphone_get |
655 | - "102": "摄像头为禁用状态,推流时请允许flash访问摄像头", //error_camera_muted | 645 | + "102": "摄像头为禁用状态,推流时请允许flash访问摄像头" //error_camera_muted |
656 | }; | 646 | }; |
657 | } | 647 | } |
658 | /** | 648 | /** |
trunk/research/players/js/srs.log.js
0 → 100755
1 | +/** | ||
2 | +* log specified, there must be a log element as: | ||
3 | + <!-- for the log --> | ||
4 | + <div class="alert alert-info fade in" id="txt_log"> | ||
5 | + <button type="button" class="close" data-dismiss="alert">×</button> | ||
6 | + <strong><span id="txt_log_title">标题:</span></strong> | ||
7 | + <span id="txt_log_msg">日志内容</span> | ||
8 | + </div> | ||
9 | +*/ | ||
10 | +function info(desc) { | ||
11 | + $("#txt_log").addClass("alert-info").removeClass("alert-error").removeClass("alert-warn"); | ||
12 | + $("#txt_log_title").text("Info:"); | ||
13 | + $("#txt_log_msg").text(desc); | ||
14 | +} | ||
15 | +function warn(code, desc) { | ||
16 | + $("#txt_log").removeClass("alert-info").removeClass("alert-error").addClass("alert-warn"); | ||
17 | + $("#txt_log_title").text("Warn:"); | ||
18 | + $("#txt_log_msg").text("code: " + code + ", " + desc); | ||
19 | +} | ||
20 | +function error(code, desc) { | ||
21 | + $("#txt_log").removeClass("alert-info").addClass("alert-error").removeClass("alert-warn"); | ||
22 | + $("#txt_log_title").text("Error:"); | ||
23 | + $("#txt_log_msg").text("code: " + code + ", " + desc); | ||
24 | +} |
@@ -7,6 +7,7 @@ | @@ -7,6 +7,7 @@ | ||
7 | <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script> | 7 | <script type="text/javascript" src="js/jquery-1.10.2.min.js"></script> |
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/srs.js"></script> | 9 | <script type="text/javascript" src="js/srs.js"></script> |
10 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
10 | <style> | 11 | <style> |
11 | body{ | 12 | body{ |
12 | padding-top: 55px; | 13 | padding-top: 55px; |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/swfobject.js"></script> | 9 | <script type="text/javascript" src="js/swfobject.js"></script> |
10 | <script type="text/javascript" src="js/srs.js"></script> | 10 | <script type="text/javascript" src="js/srs.js"></script> |
11 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
11 | <style> | 12 | <style> |
12 | body{ | 13 | body{ |
13 | padding-top: 55px; | 14 | padding-top: 55px; |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/swfobject.js"></script> | 9 | <script type="text/javascript" src="js/swfobject.js"></script> |
10 | <script type="text/javascript" src="js/srs.js"></script> | 10 | <script type="text/javascript" src="js/srs.js"></script> |
11 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
11 | <style> | 12 | <style> |
12 | body{ | 13 | body{ |
13 | padding-top: 55px; | 14 | padding-top: 55px; |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/swfobject.js"></script> | 9 | <script type="text/javascript" src="js/swfobject.js"></script> |
10 | <script type="text/javascript" src="js/srs.js"></script> | 10 | <script type="text/javascript" src="js/srs.js"></script> |
11 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
11 | <style> | 12 | <style> |
12 | body{ | 13 | body{ |
13 | padding-top: 55px; | 14 | padding-top: 55px; |
@@ -420,7 +421,7 @@ | @@ -420,7 +421,7 @@ | ||
420 | if (realtime_player) { | 421 | if (realtime_player) { |
421 | // directly play the url for the realtime player. | 422 | // directly play the url for the realtime player. |
422 | realtime_player.stop(); | 423 | realtime_player.stop(); |
423 | - realtime_player.play(url); | 424 | + realtime_player.play(url, 0); |
424 | } | 425 | } |
425 | } | 426 | } |
426 | }); | 427 | }); |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/swfobject.js"></script> | 9 | <script type="text/javascript" src="js/swfobject.js"></script> |
10 | <script type="text/javascript" src="js/srs.js"></script> | 10 | <script type="text/javascript" src="js/srs.js"></script> |
11 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
11 | <style> | 12 | <style> |
12 | body{ | 13 | body{ |
13 | padding-top: 55px; | 14 | padding-top: 55px; |
@@ -10,6 +10,7 @@ package | @@ -10,6 +10,7 @@ package | ||
10 | import flash.events.NetStatusEvent; | 10 | import flash.events.NetStatusEvent; |
11 | import flash.events.TimerEvent; | 11 | import flash.events.TimerEvent; |
12 | import flash.external.ExternalInterface; | 12 | import flash.external.ExternalInterface; |
13 | + import flash.media.SoundTransform; | ||
13 | import flash.media.Video; | 14 | import flash.media.Video; |
14 | import flash.net.NetConnection; | 15 | import flash.net.NetConnection; |
15 | import flash.net.NetStream; | 16 | import flash.net.NetStream; |
@@ -19,6 +20,8 @@ package | @@ -19,6 +20,8 @@ package | ||
19 | import flash.utils.Timer; | 20 | import flash.utils.Timer; |
20 | import flash.utils.setTimeout; | 21 | import flash.utils.setTimeout; |
21 | 22 | ||
23 | + import flashx.textLayout.formats.Float; | ||
24 | + | ||
22 | public class srs_player extends Sprite | 25 | public class srs_player extends Sprite |
23 | { | 26 | { |
24 | // user set id. | 27 | // user set id. |
@@ -280,8 +283,9 @@ package | @@ -280,8 +283,9 @@ package | ||
280 | * @param _width, the player width. | 283 | * @param _width, the player width. |
281 | * @param _height, the player height. | 284 | * @param _height, the player height. |
282 | * @param buffer_time, the buffer time in seconds. recommend to >=0.5 | 285 | * @param buffer_time, the buffer time in seconds. recommend to >=0.5 |
286 | + * @param volume, the volume, 0 is mute, 1 is 100%, 2 is 200%. | ||
283 | */ | 287 | */ |
284 | - private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number):void { | 288 | + private function js_call_play(url:String, _width:int, _height:int, buffer_time:Number, volume:Number):void { |
285 | this.user_url = url; | 289 | this.user_url = url; |
286 | this.user_w = _width; | 290 | this.user_w = _width; |
287 | this.user_h = _height; | 291 | this.user_h = _height; |
@@ -313,6 +317,7 @@ package | @@ -313,6 +317,7 @@ package | ||
313 | } | 317 | } |
314 | 318 | ||
315 | media_stream = new NetStream(media_conn); | 319 | media_stream = new NetStream(media_conn); |
320 | + media_stream.soundTransform = new SoundTransform(volume); | ||
316 | media_stream.bufferTime = buffer_time; | 321 | media_stream.bufferTime = buffer_time; |
317 | media_stream.client = {}; | 322 | media_stream.client = {}; |
318 | media_stream.client.onMetaData = system_on_metadata; | 323 | media_stream.client.onMetaData = system_on_metadata; |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/swfobject.js"></script> | 9 | <script type="text/javascript" src="js/swfobject.js"></script> |
10 | <script type="text/javascript" src="js/srs.js"></script> | 10 | <script type="text/javascript" src="js/srs.js"></script> |
11 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
11 | <style> | 12 | <style> |
12 | body{ | 13 | body{ |
13 | padding-top: 55px; | 14 | padding-top: 55px; |
@@ -10,6 +10,9 @@ package | @@ -10,6 +10,9 @@ package | ||
10 | import flash.media.H264Profile; | 10 | import flash.media.H264Profile; |
11 | import flash.media.H264VideoStreamSettings; | 11 | import flash.media.H264VideoStreamSettings; |
12 | import flash.media.Microphone; | 12 | import flash.media.Microphone; |
13 | + import flash.media.MicrophoneEnhancedMode; | ||
14 | + import flash.media.MicrophoneEnhancedOptions; | ||
15 | + import flash.media.SoundCodec; | ||
13 | import flash.media.Video; | 16 | import flash.media.Video; |
14 | import flash.net.NetConnection; | 17 | import flash.net.NetConnection; |
15 | import flash.net.NetStream; | 18 | import flash.net.NetStream; |
@@ -135,27 +138,31 @@ package | @@ -135,27 +138,31 @@ package | ||
135 | this.js_call_stop(); | 138 | this.js_call_stop(); |
136 | 139 | ||
137 | // microphone and camera | 140 | // microphone and camera |
138 | - var m:Microphone = Microphone.getMicrophone(acodec.device_code); | ||
139 | - if(m == null){ | 141 | + var microphone:Microphone = null; |
142 | + //microphone = Microphone.getEnhancedMicrophone(acodec.device_code); | ||
143 | + if (!microphone) { | ||
144 | + microphone = Microphone.getMicrophone(acodec.device_code); | ||
145 | + } | ||
146 | + if(microphone == null){ | ||
140 | this.system_error(this.error_microphone_get, "failed to open microphone " + acodec.device_code + "(" + acodec.device_name + ")"); | 147 | this.system_error(this.error_microphone_get, "failed to open microphone " + acodec.device_code + "(" + acodec.device_name + ")"); |
141 | return; | 148 | return; |
142 | } | 149 | } |
143 | // ignore muted, for flash will require user to access it. | 150 | // ignore muted, for flash will require user to access it. |
144 | 151 | ||
145 | // Remark: the name is the index! | 152 | // Remark: the name is the index! |
146 | - var c:Camera = Camera.getCamera(vcodec.device_code); | ||
147 | - if(c == null){ | 153 | + var camera:Camera = Camera.getCamera(vcodec.device_code); |
154 | + if(camera == null){ | ||
148 | this.system_error(this.error_camera_get, "failed to open camera " + vcodec.device_code + "(" + vcodec.device_name + ")"); | 155 | this.system_error(this.error_camera_get, "failed to open camera " + vcodec.device_code + "(" + vcodec.device_name + ")"); |
149 | return; | 156 | return; |
150 | } | 157 | } |
151 | // ignore muted, for flash will require user to access it. | 158 | // ignore muted, for flash will require user to access it. |
152 | // but we still warn user. | 159 | // but we still warn user. |
153 | - if(c && c.muted){ | 160 | + if(camera && camera.muted){ |
154 | this.system_warn(this.error_camera_muted, "Access Denied, camera " + vcodec.device_code + "(" + vcodec.device_name + ") is muted"); | 161 | this.system_warn(this.error_camera_muted, "Access Denied, camera " + vcodec.device_code + "(" + vcodec.device_name + ") is muted"); |
155 | } | 162 | } |
156 | 163 | ||
157 | - this.media_camera = c; | ||
158 | - this.media_microphone = m; | 164 | + this.media_camera = camera; |
165 | + this.media_microphone = microphone; | ||
159 | 166 | ||
160 | this.media_conn = new NetConnection(); | 167 | this.media_conn = new NetConnection(); |
161 | this.media_conn.client = {}; | 168 | this.media_conn.client = {}; |
@@ -188,14 +195,14 @@ package | @@ -188,14 +195,14 @@ package | ||
188 | // TODO: FIXME: failed event. | 195 | // TODO: FIXME: failed event. |
189 | }); | 196 | }); |
190 | 197 | ||
191 | - __build_video_codec(media_stream, c, vcodec); | ||
192 | - __build_audio_codec(media_stream, m, acodec); | 198 | + __build_video_codec(media_stream, camera, vcodec); |
199 | + __build_audio_codec(media_stream, microphone, acodec); | ||
193 | 200 | ||
194 | if (media_microphone) { | 201 | if (media_microphone) { |
195 | - media_stream.attachAudio(m); | 202 | + media_stream.attachAudio(microphone); |
196 | } | 203 | } |
197 | if (media_camera) { | 204 | if (media_camera) { |
198 | - media_stream.attachCamera(c); | 205 | + media_stream.attachCamera(camera); |
199 | } | 206 | } |
200 | 207 | ||
201 | var streamName:String = url.substr(url.lastIndexOf("/")); | 208 | var streamName:String = url.substr(url.lastIndexOf("/")); |
@@ -264,6 +271,10 @@ package | @@ -264,6 +271,10 @@ package | ||
264 | // if your sound capture device supports this value. Otherwise, the default value is the next available capture level above 8 kHz that | 271 | // if your sound capture device supports this value. Otherwise, the default value is the next available capture level above 8 kHz that |
265 | // your sound capture device supports, usually 11 kHz. | 272 | // your sound capture device supports, usually 11 kHz. |
266 | m.rate = microRate; | 273 | m.rate = microRate; |
274 | + | ||
275 | + // see: http://www.adobe.com/cn/devnet/flashplayer/articles/acoustic-echo-cancellation.html | ||
276 | + m.codec = SoundCodec.SPEEX; | ||
277 | + m.framesPerPacket = 1; | ||
267 | } | 278 | } |
268 | private function __build_video_codec(stream:NetStream, c:Camera, vcodec:Object):void { | 279 | private function __build_video_codec(stream:NetStream, c:Camera, vcodec:Object):void { |
269 | if (!c) { | 280 | if (!c) { |
@@ -332,9 +343,9 @@ package | @@ -332,9 +343,9 @@ package | ||
332 | // (highest quality, no compression). To specify that picture quality can vary as needed to avoid exceeding bandwidth, | 343 | // (highest quality, no compression). To specify that picture quality can vary as needed to avoid exceeding bandwidth, |
333 | // pass 0 for quality. | 344 | // pass 0 for quality. |
334 | // winlin: | 345 | // winlin: |
335 | - // bandwidth is in bps not kbps. 500*1000 = 500kbps. | 346 | + // bandwidth is in Bps not kbps. |
336 | // quality=1 is lowest quality, 100 is highest quality. | 347 | // quality=1 is lowest quality, 100 is highest quality. |
337 | - c.setQuality(cameraBitrate * 1000, cameraQuality); | 348 | + c.setQuality(cameraBitrate / 8.0 * 1000, cameraQuality); |
338 | } | 349 | } |
339 | } | 350 | } |
340 | } | 351 | } |
@@ -8,6 +8,7 @@ | @@ -8,6 +8,7 @@ | ||
8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> | 8 | <script type="text/javascript" src="js/bootstrap.min.js"></script> |
9 | <script type="text/javascript" src="js/swfobject.js"></script> | 9 | <script type="text/javascript" src="js/swfobject.js"></script> |
10 | <script type="text/javascript" src="js/srs.js"></script> | 10 | <script type="text/javascript" src="js/srs.js"></script> |
11 | + <script type="text/javascript" src="js/srs.log.js"></script> | ||
11 | <style> | 12 | <style> |
12 | body{ | 13 | body{ |
13 | padding-top: 55px; | 14 | padding-top: 55px; |
-
请 注册 或 登录 后发表评论