正在显示
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; |
-
请 注册 或 登录 后发表评论