正在显示
1 个修改的文件
包含
0 行增加
和
793 行删除
trunk/research/players/js/srs.js
已删除
100644 → 0
| 1 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 2 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 3 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | -* player specified size. | ||
| 7 | -*/ | ||
| 8 | -function srs_get_player_modal() { return 740; } | ||
| 9 | -function srs_get_player_width() { return srs_get_player_modal() - 30; } | ||
| 10 | -function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } | ||
| 11 | - | ||
| 12 | -// to query the swf anti cache. | ||
| 13 | -function srs_get_version_code() { return "1.9"; } | ||
| 14 | -// get the default vhost for players. | ||
| 15 | -function srs_get_player_vhost() { return "players"; } | ||
| 16 | -// the api server port, for chat room. | ||
| 17 | -function srs_get_api_server_port() { return 8085; } | ||
| 18 | -// get the stream published to vhost, | ||
| 19 | -// generally we need to transcode the stream to support HLS and filters. | ||
| 20 | -// for example, src_vhost is "players", we transcode stream to vhost "players_pub". | ||
| 21 | -// if not equals to the player vhost, return the orignal vhost. | ||
| 22 | -function srs_get_player_publish_vhost(src_vhost) { return (src_vhost != srs_get_player_vhost())? src_vhost:(src_vhost + "_pub"); } | ||
| 23 | -// for chat, use rtmp only vhost, low latecy, without gop cache. | ||
| 24 | -function srs_get_player_chat_vhost(src_vhost) { return (src_vhost != srs_get_player_vhost())? src_vhost:(src_vhost + "_pub_rtmp"); } | ||
| 25 | - | ||
| 26 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 27 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 28 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 29 | -/** | ||
| 30 | -* padding the output. | ||
| 31 | -* padding(3, 5, '0') is 00003 | ||
| 32 | -* padding(3, 5, 'x') is xxxx3 | ||
| 33 | -* @see http://blog.csdn.net/win_lin/article/details/12065413 | ||
| 34 | -*/ | ||
| 35 | -function padding(number, length, prefix) { | ||
| 36 | - if(String(number).length >= length){ | ||
| 37 | - return String(number); | ||
| 38 | - } | ||
| 39 | - return padding(prefix+number, length, prefix); | ||
| 40 | -} | ||
| 41 | - | ||
| 42 | -/** | ||
| 43 | -* update the navigator, add same query string. | ||
| 44 | -*/ | ||
| 45 | -function update_nav() { | ||
| 46 | - $("#nav_srs_player").attr("href", "srs_player.html" + window.location.search); | ||
| 47 | - $("#nav_srs_publisher").attr("href", "srs_publisher.html" + window.location.search); | ||
| 48 | - $("#nav_srs_chat").attr("href", "srs_chat.html" + window.location.search); | ||
| 49 | - $("#nav_srs_bwt").attr("href", "srs_bwt.html" + window.location.search); | ||
| 50 | - $("#nav_jwplayer6").attr("href", "jwplayer6.html" + window.location.search); | ||
| 51 | - $("#nav_osmf").attr("href", "osmf.html" + window.location.search); | ||
| 52 | - $("#nav_vlc").attr("href", "vlc.html" + window.location.search); | ||
| 53 | -} | ||
| 54 | - | ||
| 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. | ||
| 82 | -*/ | ||
| 83 | -function parse_query_string(){ | ||
| 84 | - var obj = {}; | ||
| 85 | - | ||
| 86 | - // parse the host(hostname:http_port), pathname(dir/filename) | ||
| 87 | - obj.host = window.location.host; | ||
| 88 | - obj.hostname = window.location.hostname; | ||
| 89 | - obj.http_port = (window.location.port == "")? 80:window.location.port; | ||
| 90 | - obj.pathname = window.location.pathname; | ||
| 91 | - if (obj.pathname.lastIndexOf("/") <= 0) { | ||
| 92 | - obj.dir = "/"; | ||
| 93 | - obj.filename = ""; | ||
| 94 | - } else { | ||
| 95 | - obj.dir = obj.pathname.substr(0, obj.pathname.lastIndexOf("/")); | ||
| 96 | - obj.filename = obj.pathname.substr(obj.pathname.lastIndexOf("/")); | ||
| 97 | - } | ||
| 98 | - | ||
| 99 | - // parse the query string. | ||
| 100 | - var query_string = String(window.location.search).replace(" ", "").split("?")[1]; | ||
| 101 | - if(query_string == undefined){ | ||
| 102 | - return obj; | ||
| 103 | - } | ||
| 104 | - | ||
| 105 | - var queries = query_string.split("&"); | ||
| 106 | - $(queries).each(function(){ | ||
| 107 | - var query = this.split("="); | ||
| 108 | - obj[query[0]] = query[1]; | ||
| 109 | - }); | ||
| 110 | - | ||
| 111 | - return obj; | ||
| 112 | -} | ||
| 113 | - | ||
| 114 | -/** | ||
| 115 | -@param server the ip of server. default to window.location.hostname | ||
| 116 | -@param vhost the vhost of rtmp. default to window.location.hostname | ||
| 117 | -@param port the port of rtmp. default to 1935 | ||
| 118 | -@param app the app of rtmp. default to live. | ||
| 119 | -@param stream the stream of rtmp. default to livestream. | ||
| 120 | -*/ | ||
| 121 | -function build_default_rtmp_url() { | ||
| 122 | - var query = parse_query_string(); | ||
| 123 | - | ||
| 124 | - var server = (query.server == undefined)? window.location.hostname:query.server; | ||
| 125 | - var port = (query.port == undefined)? 1935:query.port; | ||
| 126 | - var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost; | ||
| 127 | - var app = (query.app == undefined)? "live":query.app; | ||
| 128 | - var stream = (query.stream == undefined)? "livestream":query.stream; | ||
| 129 | - | ||
| 130 | - if (server == vhost || vhost == "") { | ||
| 131 | - return "rtmp://" + server + ":" + port + "/" + app + "/" + stream; | ||
| 132 | - } else { | ||
| 133 | - return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream; | ||
| 134 | - } | ||
| 135 | -} | ||
| 136 | -// for the chat to init the publish url. | ||
| 137 | -function build_default_publish_rtmp_url() { | ||
| 138 | - var query = parse_query_string(); | ||
| 139 | - | ||
| 140 | - var server = (query.server == undefined)? window.location.hostname:query.server; | ||
| 141 | - var port = (query.port == undefined)? 1935:query.port; | ||
| 142 | - var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost; | ||
| 143 | - var app = (query.app == undefined)? "live":query.app; | ||
| 144 | - var stream = (query.stream == undefined)? "livestream":query.stream; | ||
| 145 | - | ||
| 146 | - if (server == vhost || vhost == "") { | ||
| 147 | - return "rtmp://" + server + ":" + port + "/" + app + "/" + stream; | ||
| 148 | - } else { | ||
| 149 | - vhost = srs_get_player_chat_vhost(vhost); | ||
| 150 | - return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream; | ||
| 151 | - } | ||
| 152 | -} | ||
| 153 | - | ||
| 154 | -/** | ||
| 155 | -@param server the ip of server. default to window.location.hostname | ||
| 156 | -@param vhost the vhost of hls. default to window.location.hostname | ||
| 157 | -@param hls_vhost the vhost of hls. override the server if specified. | ||
| 158 | -@param hls_port the port of hls. default to window.location.port | ||
| 159 | -@param app the app of hls. default to live. | ||
| 160 | -@param stream the stream of hls. default to livestream. | ||
| 161 | -*/ | ||
| 162 | -function build_default_hls_url() { | ||
| 163 | - var query = parse_query_string(); | ||
| 164 | - | ||
| 165 | - // for http, use hls_vhost to override server if specified. | ||
| 166 | - var server = window.location.hostname; | ||
| 167 | - if (query.server != undefined) { | ||
| 168 | - server = query.server; | ||
| 169 | - } else if (query.hls_vhost != undefined) { | ||
| 170 | - server = query.hls_vhost; | ||
| 171 | - } | ||
| 172 | - | ||
| 173 | - var port = (query.hls_port == undefined)? window.location.port:query.hls_port; | ||
| 174 | - var app = (query.app == undefined)? "live":query.app; | ||
| 175 | - var stream = (query.stream == undefined)? "livestream":query.stream; | ||
| 176 | - | ||
| 177 | - if (port == "" || port == null || port == undefined) { | ||
| 178 | - port = 80; | ||
| 179 | - } | ||
| 180 | - | ||
| 181 | - return "http://" + server + ":" + port + "/" + app + "/" + stream + ".m3u8"; | ||
| 182 | -} | ||
| 183 | - | ||
| 184 | -/** | ||
| 185 | -* parse the rtmp url, | ||
| 186 | -* for example: rtmp://demo.srs.com:1935/live...vhost...players/livestream | ||
| 187 | -* @return object {server, port, vhost, app, stream} | ||
| 188 | -*/ | ||
| 189 | -function srs_parse_rtmp_url(rtmp_url) { | ||
| 190 | - // @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri | ||
| 191 | - var a = document.createElement("a"); | ||
| 192 | - a.href = rtmp_url.replace("rtmp://", "http://"); | ||
| 193 | - | ||
| 194 | - var vhost = a.hostname; | ||
| 195 | - var port = (a.port == "")? "1935":a.port; | ||
| 196 | - var app = a.pathname.substr(1, a.pathname.lastIndexOf("/") - 1); | ||
| 197 | - var stream = a.pathname.substr(a.pathname.lastIndexOf("/") + 1); | ||
| 198 | - | ||
| 199 | - // parse the vhost in the params of app, that srs supports. | ||
| 200 | - app = app.replace("...vhost...", "?vhost="); | ||
| 201 | - if (app.indexOf("?") >= 0) { | ||
| 202 | - var params = app.substr(app.indexOf("?")); | ||
| 203 | - app = app.substr(0, app.indexOf("?")); | ||
| 204 | - | ||
| 205 | - if (params.indexOf("vhost=") > 0) { | ||
| 206 | - vhost = params.substr(params.indexOf("vhost=") + "vhost=".length); | ||
| 207 | - if (vhost.indexOf("&") > 0) { | ||
| 208 | - vhost = vhost.substr(0, vhost.indexOf("&")); | ||
| 209 | - } | ||
| 210 | - } | ||
| 211 | - } | ||
| 212 | - | ||
| 213 | - var ret = { | ||
| 214 | - server: a.hostname, port: port, | ||
| 215 | - vhost: vhost, app: app, stream: stream | ||
| 216 | - }; | ||
| 217 | - | ||
| 218 | - return ret; | ||
| 219 | -} | ||
| 220 | - | ||
| 221 | -/** | ||
| 222 | -* initialize the page. | ||
| 223 | -* @param rtmp_url the div id contains the rtmp stream url to play | ||
| 224 | -* @param hls_url the div id contains the hls stream url to play | ||
| 225 | -* @param modal_player the div id contains the modal player | ||
| 226 | -*/ | ||
| 227 | -function srs_init(rtmp_url, hls_url, modal_player) { | ||
| 228 | - update_nav(); | ||
| 229 | - | ||
| 230 | - if (rtmp_url) { | ||
| 231 | - $(rtmp_url).val(build_default_rtmp_url()); | ||
| 232 | - } | ||
| 233 | - if (hls_url) { | ||
| 234 | - $(hls_url).val(build_default_hls_url()); | ||
| 235 | - } | ||
| 236 | - if (modal_player) { | ||
| 237 | - $(modal_player).width(srs_get_player_modal() + "px"); | ||
| 238 | - $(modal_player).css("margin-left", "-" + srs_get_player_modal() / 2 +"px"); | ||
| 239 | - } | ||
| 240 | -} | ||
| 241 | - | ||
| 242 | -// for the chat to init the publish url. | ||
| 243 | -function srs_init_publish(rtmp_url) { | ||
| 244 | - update_nav(); | ||
| 245 | - | ||
| 246 | - if (rtmp_url) { | ||
| 247 | - $(rtmp_url).val(build_default_publish_rtmp_url()); | ||
| 248 | - } | ||
| 249 | -} | ||
| 250 | - | ||
| 251 | -// for bw to init url | ||
| 252 | -// url: scheme://host:port/path?query#fragment | ||
| 253 | -function srs_init_bwt(rtmp_url, hls_url) { | ||
| 254 | - update_nav(); | ||
| 255 | - | ||
| 256 | - if (rtmp_url) { | ||
| 257 | - //var query = parse_query_string(); | ||
| 258 | - var search_filed = String(window.location.search).replace(" ", "").split("?")[1]; | ||
| 259 | - $(rtmp_url).val("rtmp://" + window.location.host + ":" + 1935 + "/app?" + search_filed); | ||
| 260 | - } | ||
| 261 | - if (hls_url) { | ||
| 262 | - $(hls_url).val(build_default_hls_url()); | ||
| 263 | - } | ||
| 264 | -} | ||
| 265 | - | ||
| 266 | -function srs_bwt_check_url(url) { | ||
| 267 | - if (url.indexOf("key") != -1 && url.indexOf("vhost") != -1) { | ||
| 268 | - return true; | ||
| 269 | - } | ||
| 270 | - | ||
| 271 | - return false; | ||
| 272 | -} | ||
| 273 | - | ||
| 274 | -function srs_bwt_build_default_url() { | ||
| 275 | - var url_default = "rtmp://" + window.location.host + ":" + 1935 + "/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"; | ||
| 276 | - return url_default; | ||
| 277 | -} | ||
| 278 | - | ||
| 279 | -/** | ||
| 280 | -* when publisher ready, init the page elements. | ||
| 281 | -*/ | ||
| 282 | -function srs_publisher_initialize_page( | ||
| 283 | - cameras, microphones, | ||
| 284 | - sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | ||
| 285 | -) { | ||
| 286 | - $(sl_cameras).empty(); | ||
| 287 | - for (var i = 0; i < cameras.length; i++) { | ||
| 288 | - $(sl_cameras).append("<option value='" + i + "'>" + cameras[i] + "</option"); | ||
| 289 | - } | ||
| 290 | - // optional: select the first no "virtual" signed. | ||
| 291 | - for (var i = 0; i < cameras.length; i++) { | ||
| 292 | - if (cameras[i].toLowerCase().indexOf("virtual") == -1) { | ||
| 293 | - $(sl_cameras + " option[value='" + i + "']").attr("selected", true); | ||
| 294 | - break; | ||
| 295 | - } | ||
| 296 | - } | ||
| 297 | - | ||
| 298 | - $(sl_microphones).empty(); | ||
| 299 | - for (var i = 0; i < microphones.length; i++) { | ||
| 300 | - $(sl_microphones).append("<option value='" + i + "'>" + microphones[i] + "</option"); | ||
| 301 | - } | ||
| 302 | - | ||
| 303 | - $(sl_vcodec).empty(); | ||
| 304 | - var vcodecs = ["h264", "vp6"]; | ||
| 305 | - for (var i = 0; i < vcodecs.length; i++) { | ||
| 306 | - $(sl_vcodec).append("<option value='" + vcodecs[i] + "'>" + vcodecs[i] + "</option"); | ||
| 307 | - } | ||
| 308 | - | ||
| 309 | - $(sl_profile).empty(); | ||
| 310 | - var profiles = ["baseline", "main"]; | ||
| 311 | - for (var i = 0; i < profiles.length; i++) { | ||
| 312 | - $(sl_profile).append("<option value='" + profiles[i] + "'>" + profiles[i] + "</option"); | ||
| 313 | - } | ||
| 314 | - $(sl_profile + " option[value='main']").attr("selected", true); | ||
| 315 | - | ||
| 316 | - $(sl_level).empty(); | ||
| 317 | - var levels = ["1", "1b", "1.1", "1.2", "1.3", | ||
| 318 | - "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1"]; | ||
| 319 | - for (var i = 0; i < levels.length; i++) { | ||
| 320 | - $(sl_level).append("<option value='" + levels[i] + "'>" + levels[i] + "</option"); | ||
| 321 | - } | ||
| 322 | - $(sl_level + " option[value='4.1']").attr("selected", true); | ||
| 323 | - | ||
| 324 | - $(sl_gop).empty(); | ||
| 325 | - var gops = ["0.3", "0.5", "1", "2", "3", "4", | ||
| 326 | - "5", "6", "7", "8", "9", "10", "15", "20"]; | ||
| 327 | - for (var i = 0; i < gops.length; i++) { | ||
| 328 | - $(sl_gop).append("<option value='" + gops[i] + "'>" + gops[i] + "秒</option"); | ||
| 329 | - } | ||
| 330 | - $(sl_gop + " option[value='10']").attr("selected", true); | ||
| 331 | - | ||
| 332 | - $(sl_size).empty(); | ||
| 333 | - var sizes = ["176x144", "320x240", "352x240", | ||
| 334 | - "352x288", "460x240", "640x480", "720x480", "720x576", "800x600", | ||
| 335 | - "1024x768", "1280x720", "1360x768", "1920x1080"]; | ||
| 336 | - for (i = 0; i < sizes.length; i++) { | ||
| 337 | - $(sl_size).append("<option value='" + sizes[i] + "'>" + sizes[i] + "</option"); | ||
| 338 | - } | ||
| 339 | - $(sl_size + " option[value='640x480']").attr("selected", true); | ||
| 340 | - | ||
| 341 | - $(sl_fps).empty(); | ||
| 342 | - var fpses = ["5", "10", "15", "20", "24", "25", "29.97", "30"]; | ||
| 343 | - for (i = 0; i < fpses.length; i++) { | ||
| 344 | - $(sl_fps).append("<option value='" + fpses[i] + "'>" + Number(fpses[i]).toFixed(2) + " 帧/秒</option"); | ||
| 345 | - } | ||
| 346 | - $(sl_fps + " option[value='20']").attr("selected", true); | ||
| 347 | - | ||
| 348 | - $(sl_bitrate).empty(); | ||
| 349 | - var bitrates = ["50", "200", "350", "500", "650", "800", | ||
| 350 | - "950", "1000", "1200", "1500", "1800", "2000", "3000", "5000"]; | ||
| 351 | - for (i = 0; i < bitrates.length; i++) { | ||
| 352 | - $(sl_bitrate).append("<option value='" + bitrates[i] + "'>" + bitrates[i] + " kbps</option"); | ||
| 353 | - } | ||
| 354 | - $(sl_bitrate + " option[value='500']").attr("selected", true); | ||
| 355 | -} | ||
| 356 | -/** | ||
| 357 | -* for chat, use low latecy settings. | ||
| 358 | -*/ | ||
| 359 | -function srs_chat_initialize_page( | ||
| 360 | - cameras, microphones, | ||
| 361 | - sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | ||
| 362 | -) { | ||
| 363 | - $(sl_cameras).empty(); | ||
| 364 | - for (var i = 0; i < cameras.length; i++) { | ||
| 365 | - $(sl_cameras).append("<option value='" + i + "'>" + cameras[i] + "</option"); | ||
| 366 | - } | ||
| 367 | - // optional: select the first no "virtual" signed. | ||
| 368 | - for (var i = 0; i < cameras.length; i++) { | ||
| 369 | - if (cameras[i].toLowerCase().indexOf("virtual") == -1) { | ||
| 370 | - $(sl_cameras + " option[value='" + i + "']").attr("selected", true); | ||
| 371 | - break; | ||
| 372 | - } | ||
| 373 | - } | ||
| 374 | - | ||
| 375 | - $(sl_microphones).empty(); | ||
| 376 | - for (var i = 0; i < microphones.length; i++) { | ||
| 377 | - $(sl_microphones).append("<option value='" + i + "'>" + microphones[i] + "</option"); | ||
| 378 | - } | ||
| 379 | - | ||
| 380 | - $(sl_vcodec).empty(); | ||
| 381 | - var vcodecs = ["h264", "vp6"]; | ||
| 382 | - for (var i = 0; i < vcodecs.length; i++) { | ||
| 383 | - $(sl_vcodec).append("<option value='" + vcodecs[i] + "'>" + vcodecs[i] + "</option"); | ||
| 384 | - } | ||
| 385 | - | ||
| 386 | - $(sl_profile).empty(); | ||
| 387 | - var profiles = ["baseline", "main"]; | ||
| 388 | - for (var i = 0; i < profiles.length; i++) { | ||
| 389 | - $(sl_profile).append("<option value='" + profiles[i] + "'>" + profiles[i] + "</option"); | ||
| 390 | - } | ||
| 391 | - $(sl_profile + " option[value='baseline']").attr("selected", true); | ||
| 392 | - | ||
| 393 | - $(sl_level).empty(); | ||
| 394 | - var levels = ["1", "1b", "1.1", "1.2", "1.3", | ||
| 395 | - "2", "2.1", "2.2", "3", "3.1", "3.2", "4", "4.1", "4.2", "5", "5.1"]; | ||
| 396 | - for (var i = 0; i < levels.length; i++) { | ||
| 397 | - $(sl_level).append("<option value='" + levels[i] + "'>" + levels[i] + "</option"); | ||
| 398 | - } | ||
| 399 | - $(sl_level + " option[value='3.1']").attr("selected", true); | ||
| 400 | - | ||
| 401 | - $(sl_gop).empty(); | ||
| 402 | - var gops = ["0.3", "0.5", "1", "2", "3", "4", | ||
| 403 | - "5", "6", "7", "8", "9", "10", "15", "20"]; | ||
| 404 | - for (var i = 0; i < gops.length; i++) { | ||
| 405 | - $(sl_gop).append("<option value='" + gops[i] + "'>" + gops[i] + "秒</option"); | ||
| 406 | - } | ||
| 407 | - $(sl_gop + " option[value='0.5']").attr("selected", true); | ||
| 408 | - | ||
| 409 | - $(sl_size).empty(); | ||
| 410 | - var sizes = ["176x144", "320x240", "352x240", | ||
| 411 | - "352x288", "460x240", "640x480", "720x480", "720x576", "800x600", | ||
| 412 | - "1024x768", "1280x720", "1360x768", "1920x1080"]; | ||
| 413 | - for (i = 0; i < sizes.length; i++) { | ||
| 414 | - $(sl_size).append("<option value='" + sizes[i] + "'>" + sizes[i] + "</option"); | ||
| 415 | - } | ||
| 416 | - $(sl_size + " option[value='460x240']").attr("selected", true); | ||
| 417 | - | ||
| 418 | - $(sl_fps).empty(); | ||
| 419 | - var fpses = ["5", "10", "15", "20", "24", "25", "29.97", "30"]; | ||
| 420 | - for (i = 0; i < fpses.length; i++) { | ||
| 421 | - $(sl_fps).append("<option value='" + fpses[i] + "'>" + Number(fpses[i]).toFixed(2) + " 帧/秒</option"); | ||
| 422 | - } | ||
| 423 | - $(sl_fps + " option[value='15']").attr("selected", true); | ||
| 424 | - | ||
| 425 | - $(sl_bitrate).empty(); | ||
| 426 | - var bitrates = ["50", "200", "350", "500", "650", "800", | ||
| 427 | - "950", "1000", "1200", "1500", "1800", "2000", "3000", "5000"]; | ||
| 428 | - for (i = 0; i < bitrates.length; i++) { | ||
| 429 | - $(sl_bitrate).append("<option value='" + bitrates[i] + "'>" + bitrates[i] + " kbps</option"); | ||
| 430 | - } | ||
| 431 | - $(sl_bitrate + " option[value='350']").attr("selected", true); | ||
| 432 | -} | ||
| 433 | -/** | ||
| 434 | -* get the vcodec and acodec. | ||
| 435 | -*/ | ||
| 436 | -function srs_publiser_get_codec( | ||
| 437 | - vcodec, acodec, | ||
| 438 | - sl_cameras, sl_microphones, sl_vcodec, sl_profile, sl_level, sl_gop, sl_size, sl_fps, sl_bitrate | ||
| 439 | -) { | ||
| 440 | - acodec.device_code = $(sl_microphones).val(); | ||
| 441 | - acodec.device_name = $(sl_microphones).text(); | ||
| 442 | - | ||
| 443 | - vcodec.device_code = $(sl_cameras).find("option:selected").val(); | ||
| 444 | - vcodec.device_name = $(sl_cameras).find("option:selected").text(); | ||
| 445 | - | ||
| 446 | - vcodec.codec = $(sl_vcodec).find("option:selected").val(); | ||
| 447 | - vcodec.profile = $(sl_profile).find("option:selected").val(); | ||
| 448 | - vcodec.level = $(sl_level).find("option:selected").val(); | ||
| 449 | - vcodec.fps = $(sl_fps).find("option:selected").val(); | ||
| 450 | - vcodec.gop = $(sl_gop).find("option:selected").val(); | ||
| 451 | - vcodec.size = $(sl_size).find("option:selected").val(); | ||
| 452 | - vcodec.bitrate = $(sl_bitrate).find("option:selected").val(); | ||
| 453 | -} | ||
| 454 | - | ||
| 455 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 456 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 457 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 458 | -/** | ||
| 459 | -* the SrsPlayer object. | ||
| 460 | -* @param container the html container id. | ||
| 461 | -* @param width a float value specifies the width of player. | ||
| 462 | -* @param height a float value specifies the height of player. | ||
| 463 | -* @param private_object [optional] an object that used as private object, | ||
| 464 | -* for example, the logic chat object which owner this player. | ||
| 465 | -*/ | ||
| 466 | -function SrsPlayer(container, width, height, private_object) { | ||
| 467 | - if (!SrsPlayer.__id) { | ||
| 468 | - SrsPlayer.__id = 100; | ||
| 469 | - } | ||
| 470 | - if (!SrsPlayer.__players) { | ||
| 471 | - SrsPlayer.__players = []; | ||
| 472 | - } | ||
| 473 | - | ||
| 474 | - SrsPlayer.__players.push(this); | ||
| 475 | - | ||
| 476 | - this.private_object = private_object; | ||
| 477 | - this.container = container; | ||
| 478 | - this.width = width; | ||
| 479 | - this.height = height; | ||
| 480 | - this.id = SrsPlayer.__id++; | ||
| 481 | - this.stream_url = null; | ||
| 482 | - this.buffer_time = 0.8; // default to 0.8 | ||
| 483 | - this.callbackObj = null; | ||
| 484 | - | ||
| 485 | - // callback set the following values. | ||
| 486 | - this.meatadata = {}; // for on_player_metadata | ||
| 487 | - this.time = 0; // current stream time. | ||
| 488 | - this.buffer_length = 0; // current stream buffer length. | ||
| 489 | -} | ||
| 490 | -/** | ||
| 491 | -* user can set some callback, then start the player. | ||
| 492 | -* @param url the default url. | ||
| 493 | -* callbacks: | ||
| 494 | -* on_player_ready():int, when srs player ready, user can play. | ||
| 495 | -* on_player_metadata(metadata:Object):int, when srs player get metadata. | ||
| 496 | -*/ | ||
| 497 | -SrsPlayer.prototype.start = function(url) { | ||
| 498 | - if (url) { | ||
| 499 | - this.stream_url = url; | ||
| 500 | - } | ||
| 501 | - | ||
| 502 | - // embed the flash. | ||
| 503 | - var flashvars = {}; | ||
| 504 | - flashvars.id = this.id; | ||
| 505 | - flashvars.on_player_ready = "__srs_on_player_ready"; | ||
| 506 | - flashvars.on_player_metadata = "__srs_on_player_metadata"; | ||
| 507 | - flashvars.on_player_timer = "__srs_on_player_timer"; | ||
| 508 | - | ||
| 509 | - var params = {}; | ||
| 510 | - params.wmode = "opaque"; | ||
| 511 | - params.allowFullScreen = "true"; | ||
| 512 | - params.allowScriptAccess = "always"; | ||
| 513 | - | ||
| 514 | - var attributes = {}; | ||
| 515 | - | ||
| 516 | - var self = this; | ||
| 517 | - | ||
| 518 | - swfobject.embedSWF( | ||
| 519 | - "srs_player/release/srs_player.swf?_version="+srs_get_version_code(), | ||
| 520 | - this.container, | ||
| 521 | - this.width, this.height, | ||
| 522 | - "11.1", "js/AdobeFlashPlayerInstall.swf", | ||
| 523 | - flashvars, params, attributes, | ||
| 524 | - function(callbackObj){ | ||
| 525 | - self.callbackObj = callbackObj; | ||
| 526 | - } | ||
| 527 | - ); | ||
| 528 | - | ||
| 529 | - return this; | ||
| 530 | -} | ||
| 531 | -/** | ||
| 532 | -* play the stream. | ||
| 533 | -* @param stream_url the url of stream, rtmp or http. | ||
| 534 | -*/ | ||
| 535 | -SrsPlayer.prototype.play = function(url) { | ||
| 536 | - if (url) { | ||
| 537 | - this.stream_url = url; | ||
| 538 | - } | ||
| 539 | - this.callbackObj.ref.__play(this.stream_url, this.width, this.height, this.buffer_time); | ||
| 540 | -} | ||
| 541 | -SrsPlayer.prototype.stop = function() { | ||
| 542 | - for (var i = 0; i < SrsPlayer.__players.length; i++) { | ||
| 543 | - var player = SrsPlayer.__players[i]; | ||
| 544 | - | ||
| 545 | - if (player.id != this.id) { | ||
| 546 | - continue; | ||
| 547 | - } | ||
| 548 | - | ||
| 549 | - SrsPlayer.__players.splice(i, 1); | ||
| 550 | - break; | ||
| 551 | - } | ||
| 552 | - | ||
| 553 | - this.callbackObj.ref.__stop(); | ||
| 554 | -} | ||
| 555 | -SrsPlayer.prototype.pause = function() { | ||
| 556 | - this.callbackObj.ref.__pause(); | ||
| 557 | -} | ||
| 558 | -SrsPlayer.prototype.resume = function() { | ||
| 559 | - this.callbackObj.ref.__resume(); | ||
| 560 | -} | ||
| 561 | -/** | ||
| 562 | -* to set the DAR, for example, DAR=16:9 | ||
| 563 | -* @param num, for example, 9. | ||
| 564 | -* use metadata height if 0. | ||
| 565 | -* use user specified height if -1. | ||
| 566 | -* @param den, for example, 16. | ||
| 567 | -* use metadata width if 0. | ||
| 568 | -* use user specified width if -1. | ||
| 569 | -*/ | ||
| 570 | -SrsPlayer.prototype.dar = function(num, den) { | ||
| 571 | - this.callbackObj.ref.__dar(num, den); | ||
| 572 | -} | ||
| 573 | -/** | ||
| 574 | -* set the fullscreen size data. | ||
| 575 | -* @refer the refer fullscreen mode. it can be: | ||
| 576 | -* video: use video orignal size. | ||
| 577 | -* screen: use screen size to rescale video. | ||
| 578 | -* @param percent, the rescale percent, where | ||
| 579 | -* 100 means 100%. | ||
| 580 | -*/ | ||
| 581 | -SrsPlayer.prototype.set_fs = function(refer, percent) { | ||
| 582 | - this.callbackObj.ref.__set_fs(refer, percent); | ||
| 583 | -} | ||
| 584 | -/** | ||
| 585 | -* set the stream buffer time in seconds. | ||
| 586 | -* @buffer_time the buffer time in seconds. | ||
| 587 | -*/ | ||
| 588 | -SrsPlayer.prototype.set_bt = function(buffer_time) { | ||
| 589 | - this.buffer_time = buffer_time; | ||
| 590 | - this.callbackObj.ref.__set_bt(buffer_time); | ||
| 591 | -} | ||
| 592 | -SrsPlayer.prototype.on_player_ready = function() { | ||
| 593 | -} | ||
| 594 | -SrsPlayer.prototype.on_player_metadata = function(metadata) { | ||
| 595 | - // ignore. | ||
| 596 | -} | ||
| 597 | -SrsPlayer.prototype.on_player_timer = function(time, buffer_length) { | ||
| 598 | - // ignore. | ||
| 599 | -} | ||
| 600 | -function __srs_find_player(id) { | ||
| 601 | - for (var i = 0; i < SrsPlayer.__players.length; i++) { | ||
| 602 | - var player = SrsPlayer.__players[i]; | ||
| 603 | - | ||
| 604 | - if (player.id != id) { | ||
| 605 | - continue; | ||
| 606 | - } | ||
| 607 | - | ||
| 608 | - return player; | ||
| 609 | - } | ||
| 610 | - | ||
| 611 | - throw new Error("player not found. id=" + id); | ||
| 612 | -} | ||
| 613 | -function __srs_on_player_ready(id) { | ||
| 614 | - var player = __srs_find_player(id); | ||
| 615 | - player.on_player_ready(); | ||
| 616 | -} | ||
| 617 | -function __srs_on_player_metadata(id, metadata) { | ||
| 618 | - var player = __srs_find_player(id); | ||
| 619 | - | ||
| 620 | - // user may override the on_player_metadata, | ||
| 621 | - // so set the data before invoke it. | ||
| 622 | - player.metadata = metadata; | ||
| 623 | - | ||
| 624 | - player.on_player_metadata(metadata); | ||
| 625 | -} | ||
| 626 | -function __srs_on_player_timer(id, time, buffer_length) { | ||
| 627 | - var player = __srs_find_player(id); | ||
| 628 | - | ||
| 629 | - buffer_length = Math.max(0, buffer_length); | ||
| 630 | - buffer_length = Math.min(player.buffer_time, buffer_length); | ||
| 631 | - | ||
| 632 | - time = Math.max(0, time); | ||
| 633 | - | ||
| 634 | - // user may override the on_player_timer, | ||
| 635 | - // so set the data before invoke it. | ||
| 636 | - player.time = time; | ||
| 637 | - player.buffer_length = buffer_length; | ||
| 638 | - | ||
| 639 | - player.on_player_timer(time, buffer_length); | ||
| 640 | -} | ||
| 641 | - | ||
| 642 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 643 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 644 | -////////////////////////////////////////////////////////////////////////////////// | ||
| 645 | -/** | ||
| 646 | -* the SrsPublisher object. | ||
| 647 | -* @param container the html container id. | ||
| 648 | -* @param width a float value specifies the width of publisher. | ||
| 649 | -* @param height a float value specifies the height of publisher. | ||
| 650 | -* @param private_object [optional] an object that used as private object, | ||
| 651 | -* for example, the logic chat object which owner this publisher. | ||
| 652 | -*/ | ||
| 653 | -function SrsPublisher(container, width, height, private_object) { | ||
| 654 | - if (!SrsPublisher.__id) { | ||
| 655 | - SrsPublisher.__id = 100; | ||
| 656 | - } | ||
| 657 | - if (!SrsPublisher.__publishers) { | ||
| 658 | - SrsPublisher.__publishers = []; | ||
| 659 | - } | ||
| 660 | - | ||
| 661 | - SrsPublisher.__publishers.push(this); | ||
| 662 | - | ||
| 663 | - this.private_object = private_object; | ||
| 664 | - this.container = container; | ||
| 665 | - this.width = width; | ||
| 666 | - this.height = height; | ||
| 667 | - this.id = SrsPublisher.__id++; | ||
| 668 | - this.callbackObj = null; | ||
| 669 | - | ||
| 670 | - // set the values when publish. | ||
| 671 | - this.url = null; | ||
| 672 | - this.vcodec = {}; | ||
| 673 | - this.acodec = {}; | ||
| 674 | - | ||
| 675 | - // callback set the following values. | ||
| 676 | - this.cameras = []; | ||
| 677 | - this.microphones = []; | ||
| 678 | - this.code = 0; | ||
| 679 | - | ||
| 680 | - // error code defines. | ||
| 681 | - this.errors = { | ||
| 682 | - "100": "无法获取指定的摄像头", //error_camera_get | ||
| 683 | - "101": "无法获取指定的麦克风", //error_microphone_get | ||
| 684 | - "102": "摄像头为禁用状态,推流时请允许flash访问摄像头", //error_camera_muted | ||
| 685 | - }; | ||
| 686 | -} | ||
| 687 | -/** | ||
| 688 | -* user can set some callback, then start the publisher. | ||
| 689 | -* callbacks: | ||
| 690 | -* on_publisher_ready(cameras, microphones):int, when srs publisher ready, user can publish. | ||
| 691 | -* on_publisher_error(code, desc):int, when srs publisher error, callback this method. | ||
| 692 | -* on_publisher_warn(code, desc):int, when srs publisher warn, callback this method. | ||
| 693 | -*/ | ||
| 694 | -SrsPublisher.prototype.start = function() { | ||
| 695 | - // embed the flash. | ||
| 696 | - var flashvars = {}; | ||
| 697 | - flashvars.id = this.id; | ||
| 698 | - flashvars.on_publisher_ready = "__srs_on_publisher_ready"; | ||
| 699 | - flashvars.on_publisher_error = "__srs_on_publisher_error"; | ||
| 700 | - flashvars.on_publisher_warn = "__srs_on_publisher_warn"; | ||
| 701 | - | ||
| 702 | - var params = {}; | ||
| 703 | - params.wmode = "opaque"; | ||
| 704 | - params.allowFullScreen = "true"; | ||
| 705 | - params.allowScriptAccess = "always"; | ||
| 706 | - | ||
| 707 | - var attributes = {}; | ||
| 708 | - | ||
| 709 | - var self = this; | ||
| 710 | - | ||
| 711 | - swfobject.embedSWF( | ||
| 712 | - "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(), | ||
| 713 | - this.container, | ||
| 714 | - this.width, this.height, | ||
| 715 | - "11.1", "js/AdobeFlashPlayerInstall.swf", | ||
| 716 | - flashvars, params, attributes, | ||
| 717 | - function(callbackObj){ | ||
| 718 | - self.callbackObj = callbackObj; | ||
| 719 | - } | ||
| 720 | - ); | ||
| 721 | - | ||
| 722 | - return this; | ||
| 723 | -} | ||
| 724 | -/** | ||
| 725 | -* publish stream to server. | ||
| 726 | -* @param url a string indicates the rtmp url to publish. | ||
| 727 | -* @param vcodec an object contains the video codec info. | ||
| 728 | -* @param acodec an object contains the audio codec info. | ||
| 729 | -*/ | ||
| 730 | -SrsPublisher.prototype.publish = function(url, vcodec, acodec) { | ||
| 731 | - this.url = url; | ||
| 732 | - this.vcodec = vcodec; | ||
| 733 | - this.acodec = acodec; | ||
| 734 | - | ||
| 735 | - this.callbackObj.ref.__publish(url, this.width, this.height, vcodec, acodec); | ||
| 736 | -} | ||
| 737 | -SrsPublisher.prototype.stop = function() { | ||
| 738 | - this.callbackObj.ref.__stop(); | ||
| 739 | -} | ||
| 740 | -/** | ||
| 741 | -* when publisher ready. | ||
| 742 | -* @param cameras a string array contains the names of cameras. | ||
| 743 | -* @param microphones a string array contains the names of microphones. | ||
| 744 | -*/ | ||
| 745 | -SrsPublisher.prototype.on_publisher_ready = function(cameras, microphones) { | ||
| 746 | -} | ||
| 747 | -/** | ||
| 748 | -* when publisher error. | ||
| 749 | -* @code the error code. | ||
| 750 | -* @desc the error desc message. | ||
| 751 | -*/ | ||
| 752 | -SrsPublisher.prototype.on_publisher_error = function(code, desc) { | ||
| 753 | - throw new Error("publisher error. code=" + code + ", desc=" + desc); | ||
| 754 | -} | ||
| 755 | -SrsPublisher.prototype.on_publisher_warn = function(code, desc) { | ||
| 756 | - throw new Error("publisher warn. code=" + code + ", desc=" + desc); | ||
| 757 | -} | ||
| 758 | -function __srs_find_publisher(id) { | ||
| 759 | - for (var i = 0; i < SrsPublisher.__publishers.length; i++) { | ||
| 760 | - var publisher = SrsPublisher.__publishers[i]; | ||
| 761 | - | ||
| 762 | - if (publisher.id != id) { | ||
| 763 | - continue; | ||
| 764 | - } | ||
| 765 | - | ||
| 766 | - return publisher; | ||
| 767 | - } | ||
| 768 | - | ||
| 769 | - throw new Error("publisher not found. id=" + id); | ||
| 770 | -} | ||
| 771 | -function __srs_on_publisher_ready(id, cameras, microphones) { | ||
| 772 | - var publisher = __srs_find_publisher(id); | ||
| 773 | - | ||
| 774 | - publisher.cameras = cameras; | ||
| 775 | - publisher.microphones = microphones; | ||
| 776 | - | ||
| 777 | - publisher.on_publisher_ready(cameras, microphones); | ||
| 778 | -} | ||
| 779 | -function __srs_on_publisher_error(id, code) { | ||
| 780 | - var publisher = __srs_find_publisher(id); | ||
| 781 | - | ||
| 782 | - publisher.code = code; | ||
| 783 | - | ||
| 784 | - publisher.on_publisher_error(code, publisher.errors[""+code]); | ||
| 785 | -} | ||
| 786 | -function __srs_on_publisher_warn(id, code) { | ||
| 787 | - var publisher = __srs_find_publisher(id); | ||
| 788 | - | ||
| 789 | - publisher.code = code; | ||
| 790 | - | ||
| 791 | - publisher.on_publisher_warn(code, publisher.errors[""+code]); | ||
| 792 | -} | ||
| 793 | - |
-
请 注册 或 登录 后发表评论