winlin

refine the demo pages, move scripts after body.

@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 <script type="text/javascript" src="players/js/jquery-1.10.2.min.js"></script> 6 <script type="text/javascript" src="players/js/jquery-1.10.2.min.js"></script>
7 <script type="text/javascript" src="players/js/srs.page.js"></script> 7 <script type="text/javascript" src="players/js/srs.page.js"></script>
8 <script type="text/javascript" src="players/js/srs.utility.js"></script> 8 <script type="text/javascript" src="players/js/srs.utility.js"></script>
  9 + <script type="text/javascript" src="players/js/winlin.utility.js"></script>
9 </head> 10 </head>
10 <body> 11 <body>
11 <script type="text/javascript"> 12 <script type="text/javascript">
@@ -4,35 +4,11 @@ @@ -4,35 +4,11 @@
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
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>  
9 - <script type="text/javascript" src="js/swfobject.js"></script>  
10 - <script type="text/javascript" src="js/srs.page.js"></script>  
11 - <script type="text/javascript" src="js/srs.utility.js"></script>  
12 <style> 7 <style>
13 body{ 8 body{
14 padding-top: 55px; 9 padding-top: 55px;
15 } 10 }
16 </style> 11 </style>
17 - <script type="text/javascript">  
18 - $(function(){  
19 - update_nav();  
20 -  
21 - var query = parse_query_string();  
22 - var url = "srs_chat.html?vhost=" + srs_get_player_vhost();  
23 -  
24 - for (var key in query.user_query) {  
25 - if (key == "vhost") {  
26 - continue;  
27 - }  
28 - url += "&" + key + "=" + query[key];  
29 - }  
30 -  
31 - setTimeout(function(){  
32 - window.location.href = url;  
33 - }, 100);  
34 - });  
35 - </script>  
36 </head> 12 </head>
37 <body> 13 <body>
38 <div class="navbar navbar-fixed-top"> 14 <div class="navbar navbar-fixed-top">
@@ -59,5 +35,30 @@ @@ -59,5 +35,30 @@
59 <p><a href="https://github.com/simple-rtmp-server/srs">SRS Team &copy; 2013</a></p> 35 <p><a href="https://github.com/simple-rtmp-server/srs">SRS Team &copy; 2013</a></p>
60 </footer> 36 </footer>
61 </div> 37 </div>
  38 +<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  39 +<script type="text/javascript" src="js/bootstrap.min.js"></script>
  40 +<script type="text/javascript" src="js/swfobject.js"></script>
  41 +<script type="text/javascript" src="js/srs.page.js"></script>
  42 +<script type="text/javascript" src="js/srs.utility.js"></script>
  43 +<script type="text/javascript" src="js/winlin.utility.js"></script>
  44 +<script type="text/javascript">
  45 + $(function(){
  46 + update_nav();
  47 +
  48 + var query = parse_query_string();
  49 + var url = "srs_chat.html?vhost=" + srs_get_player_vhost();
  50 +
  51 + for (var key in query.user_query) {
  52 + if (key == "vhost") {
  53 + continue;
  54 + }
  55 + url += "&" + key + "=" + query[key];
  56 + }
  57 +
  58 + setTimeout(function(){
  59 + window.location.href = url;
  60 + }, 100);
  61 + });
  62 +</script>
62 </body> 63 </body>
63 64
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 ////////////////////////////////////////////////////////////////////////////////// 3 //////////////////////////////////////////////////////////////////////////////////
4 4
5 // to query the swf anti cache. 5 // to query the swf anti cache.
6 -function srs_get_version_code() { return "1.23"; } 6 +function srs_get_version_code() { return "1.25"; }
7 7
8 /** 8 /**
9 * player specified size. 9 * player specified size.
@@ -135,6 +135,12 @@ function build_default_hls_url() { @@ -135,6 +135,12 @@ function build_default_hls_url() {
135 * @param hls_url the div id contains the hls stream url to play 135 * @param hls_url the div id contains the hls stream url to play
136 * @param modal_player the div id contains the modal player 136 * @param modal_player the div id contains the modal player
137 */ 137 */
  138 +function srs_init_rtmp(rtmp_url, modal_player) {
  139 + srs_init(rtmp_url, null, modal_player);
  140 +}
  141 +function srs_init_hls(hls_url, modal_player) {
  142 + srs_init(null, hls_url, modal_player);
  143 +}
138 function srs_init(rtmp_url, hls_url, modal_player) { 144 function srs_init(rtmp_url, hls_url, modal_player) {
139 update_nav(); 145 update_nav();
140 146
1 /** 1 /**
2 -* padding the output.  
3 -* padding(3, 5, '0') is 00003  
4 -* padding(3, 5, 'x') is xxxx3  
5 -* @see http://blog.csdn.net/win_lin/article/details/12065413  
6 -*/  
7 -function padding(number, length, prefix) {  
8 - if(String(number).length >= length){  
9 - return String(number);  
10 - }  
11 - return padding(prefix+number, length, prefix);  
12 -}  
13 -  
14 -/**  
15 -* parse the query string to object.  
16 -* parse the url location object as: host(hostname:http_port), pathname(dir/filename)  
17 -* for example, url http://192.168.1.168:1980/ui/players.html?vhost=player.vhost.com&app=test&stream=livestream  
18 -* parsed to object:  
19 -{  
20 - host : "192.168.1.168:1980",  
21 - hostname : "192.168.1.168",  
22 - http_port : 1980,  
23 - pathname : "/ui/players.html",  
24 - dir : "/ui",  
25 - filename : "/players.html",  
26 -  
27 - vhost : "player.vhost.com",  
28 - app : "test",  
29 - stream : "livestream"  
30 -}  
31 -*/  
32 -function parse_query_string(){  
33 - var obj = {};  
34 -  
35 - // add the uri object.  
36 - // parse the host(hostname:http_port), pathname(dir/filename)  
37 - obj.host = window.location.host;  
38 - obj.hostname = window.location.hostname;  
39 - obj.http_port = (window.location.port == "")? 80:window.location.port;  
40 - obj.pathname = window.location.pathname;  
41 - if (obj.pathname.lastIndexOf("/") <= 0) {  
42 - obj.dir = "/";  
43 - obj.filename = "";  
44 - } else {  
45 - obj.dir = obj.pathname.substr(0, obj.pathname.lastIndexOf("/"));  
46 - obj.filename = obj.pathname.substr(obj.pathname.lastIndexOf("/"));  
47 - }  
48 -  
49 - // pure user query object.  
50 - obj.user_query = {};  
51 -  
52 - // parse the query string.  
53 - var query_string = String(window.location.search).replace(" ", "").split("?")[1];  
54 - if(query_string == undefined){  
55 - return obj;  
56 - }  
57 -  
58 - var queries = query_string.split("&");  
59 - $(queries).each(function(){  
60 - var query = this.split("=");  
61 - obj[query[0]] = query[1];  
62 - obj.user_query[query[0]] = query[1];  
63 - });  
64 -  
65 - return obj;  
66 -}  
67 -  
68 -/**  
69 * parse the rtmp url, 2 * parse the rtmp url,
70 * for example: rtmp://demo.srs.com:1935/live...vhost...players/livestream 3 * for example: rtmp://demo.srs.com:1935/live...vhost...players/livestream
71 * @return object {server, port, vhost, app, stream} 4 * @return object {server, port, vhost, app, stream}
72 */ 5 */
73 function srs_parse_rtmp_url(rtmp_url) { 6 function srs_parse_rtmp_url(rtmp_url) {
74 - // @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri  
75 - var a = document.createElement("a");  
76 - a.href = rtmp_url.replace("rtmp://", "http://");  
77 -  
78 - var vhost = a.hostname;  
79 - var port = (a.port == "")? "1935":a.port;  
80 - var app = a.pathname.substr(1, a.pathname.lastIndexOf("/") - 1);  
81 - var stream = a.pathname.substr(a.pathname.lastIndexOf("/") + 1);  
82 -  
83 - // parse the vhost in the params of app, that srs supports.  
84 - app = app.replace("...vhost...", "?vhost=");  
85 - if (app.indexOf("?") >= 0) {  
86 - var params = app.substr(app.indexOf("?"));  
87 - app = app.substr(0, app.indexOf("?"));  
88 -  
89 - if (params.indexOf("vhost=") > 0) {  
90 - vhost = params.substr(params.indexOf("vhost=") + "vhost=".length);  
91 - if (vhost.indexOf("&") > 0) {  
92 - vhost = vhost.substr(0, vhost.indexOf("&"));  
93 - }  
94 - }  
95 - }  
96 -  
97 - var ret = {  
98 - server: a.hostname, port: port,  
99 - vhost: vhost, app: app, stream: stream  
100 - };  
101 -  
102 - return ret;  
103 -}  
104 -  
105 -/**  
106 -* get the agent.  
107 -* @return an object specifies some browser.  
108 -* for example, get_browser_agents().MSIE  
109 -*/  
110 -function get_browser_agents() {  
111 - var agent = navigator.userAgent;  
112 -  
113 - /**  
114 - WindowsPC platform, Win7:  
115 - chrome 31.0.1650.63:  
116 - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36  
117 - (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36  
118 - firefox 23.0.1:  
119 - Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101  
120 - Firefox/23.0  
121 - safari 5.1.7(7534.57.2):  
122 - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2  
123 - (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2  
124 - opera 15.0.1147.153:  
125 - Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36  
126 - (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36  
127 - OPR/15.0.1147.153  
128 - 360 6.2.1.272:  
129 - Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;  
130 - Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;  
131 - .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;  
132 - .NET4.0E)  
133 - IE 10.0.9200.16750(update: 10.0.12):  
134 - Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;  
135 - Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;  
136 - .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;  
137 - .NET4.0E)  
138 - */  
139 -  
140 - return {  
141 - // platform  
142 - Android: agent.indexOf("Android") != -1,  
143 - Windows: agent.indexOf("Windows") != -1,  
144 - iPhone: agent.indexOf("iPhone") != -1,  
145 - // Windows Browsers  
146 - Chrome: agent.indexOf("Chrome") != -1,  
147 - Firefox: agent.indexOf("Firefox") != -1,  
148 - QQBrowser: agent.indexOf("QQBrowser") != -1,  
149 - MSIE: agent.indexOf("MSIE") != -1,  
150 - // Android Browsers  
151 - Opera: agent.indexOf("Presto") != -1,  
152 - MQQBrowser: agent.indexOf("MQQBrowser") != -1  
153 - }; 7 + return parse_rtmp_url(rtmp_url);
154 } 8 }
  1 +// winlin.utility.js
  2 +
  3 +/**
  4 + * common utilities
  5 + * depends: jquery1.10
  6 + * https://code.csdn.net/snippets/147103
  7 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  8 + * v 1.0.10
  9 + */
  10 +
  11 +/**
  12 + * padding the output.
  13 + * padding(3, 5, '0') is 00003
  14 + * padding(3, 5, 'x') is xxxx3
  15 + * @see http://blog.csdn.net/win_lin/article/details/12065413
  16 + */
  17 +function padding(number, length, prefix) {
  18 + if(String(number).length >= length){
  19 + return String(number);
  20 + }
  21 + return padding(prefix+number, length, prefix);
  22 +}
  23 +
  24 +/**
  25 + * extends system array, to remove all specified elem.
  26 + * @param arr the array to remove elem from.
  27 + * @param elem the elem to remove.
  28 + * @remark all elem will be removed.
  29 + * for example,
  30 + * arr = [10, 15, 20, 30, 20, 40]
  31 + * system_array_remove(arr, 10) // arr=[15, 20, 30, 20, 40]
  32 + * system_array_remove(arr, 20) // arr=[15, 30, 40]
  33 + */
  34 +function system_array_remove(arr, elem) {
  35 + if (!arr) {
  36 + return;
  37 + }
  38 +
  39 + var removed = true;
  40 + var i = 0;
  41 + while (removed) {
  42 + removed = false;
  43 + for (; i < arr.length; i++) {
  44 + if (elem == arr[i]) {
  45 + arr.splice(i, 1);
  46 + removed = true;
  47 + break;
  48 + }
  49 + }
  50 + }
  51 +}
  52 +
  53 +/**
  54 + * whether the array contains specified element.
  55 + * @param arr the array to find.
  56 + * @param elem_or_function the element value or compare function.
  57 + * @returns true contains elem; otherwise false.
  58 + * for example,
  59 + * arr = [10, 15, 20, 30, 20, 40]
  60 + * system_array_contains(arr, 10) // true
  61 + * system_array_contains(arr, 11) // false
  62 + * system_array_contains(arr, function(elem){return elem == 30;}); // true
  63 + * system_array_contains(arr, function(elem){return elem == 60;}); // false
  64 + */
  65 +function system_array_contains(arr, elem_or_function) {
  66 + return system_array_get(arr, elem_or_function) != null;
  67 +}
  68 +
  69 +/**
  70 + * get the specified element from array
  71 + * @param arr the array to find.
  72 + * @param elem_or_function the element value or compare function.
  73 + * @returns the matched elem; otherwise null.
  74 + * for example,
  75 + * arr = [10, 15, 20, 30, 20, 40]
  76 + * system_array_get(arr, 10) // 10
  77 + * system_array_get(arr, 11) // null
  78 + * system_array_get(arr, function(elem){return elem == 30;}); // 30
  79 + * system_array_get(arr, function(elem){return elem == 60;}); // null
  80 + */
  81 +function system_array_get(arr, elem_or_function) {
  82 + for (var i = 0; i < arr.length; i++) {
  83 + if (typeof elem_or_function == "function") {
  84 + if (elem_or_function(arr[i])) {
  85 + return arr[i];
  86 + }
  87 + } else {
  88 + if (elem_or_function == arr[i]) {
  89 + return arr[i];
  90 + }
  91 + }
  92 + }
  93 + return null;
  94 +}
  95 +
  96 +/**
  97 + * to iterate on array.
  98 + * @param arr the array to iterate on.
  99 + * @param pfn the function to apply on it
  100 + * for example,
  101 + * arr = [10, 15, 20, 30, 20, 40]
  102 + * system_array_foreach(arr, function(elem, index){
  103 + * console.log('index=' + index + ',elem=' + elem);
  104 + * });
  105 + */
  106 +function system_array_foreach(arr, pfn) {
  107 + for (var i = 0; i < arr.length; i++) {
  108 + if (pfn) {
  109 + pfn(arr[i], i)
  110 + }
  111 + }
  112 +}
  113 +
  114 +/**
  115 + * array sort asc, for example:
  116 + * [a, b] in [10, 11, 9]
  117 + * then sort to: [9, 10, 11]
  118 + * Usage, for example:
  119 + obj.data.data.sort(function(a, b){
  120 + return array_sort_asc(a.metadata.meta_id, b.metadata.meta_id);
  121 + });
  122 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  123 + * @remark, if need desc, use -1*array_sort_asc(a,b)
  124 + */
  125 +function array_sort_asc(elem_a, elem_b) {
  126 + if (elem_a > elem_b) {
  127 + return 1;
  128 + }
  129 + return (elem_a < elem_b)? -1 : 0;
  130 +}
  131 +function array_sort_desc(elem_a, elem_b) {
  132 + return -1 * array_sort_asc(elem_a, elem_b);
  133 +}
  134 +function system_array_sort_asc(elem_a, elem_b) {
  135 + return array_sort_asc(elem_a, elem_b);
  136 +}
  137 +function system_array_sort_desc(elem_a, elem_b) {
  138 + return -1 * array_sort_asc(elem_a, elem_b);
  139 +}
  140 +
  141 +/**
  142 + * parse the query string to object.
  143 + * parse the url location object as: host(hostname:http_port), pathname(dir/filename)
  144 + * for example, url http://192.168.1.168:1980/ui/players.html?vhost=player.vhost.com&app=test&stream=livestream
  145 + * parsed to object:
  146 + {
  147 + host : "192.168.1.168:1980",
  148 + hostname : "192.168.1.168",
  149 + http_port : 1980,
  150 + pathname : "/ui/players.html",
  151 + dir : "/ui",
  152 + filename : "/players.html",
  153 +
  154 + vhost : "player.vhost.com",
  155 + app : "test",
  156 + stream : "livestream"
  157 + }
  158 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  159 + */
  160 +function parse_query_string(){
  161 + var obj = {};
  162 +
  163 + // add the uri object.
  164 + // parse the host(hostname:http_port), pathname(dir/filename)
  165 + obj.host = window.location.host;
  166 + obj.hostname = window.location.hostname;
  167 + obj.http_port = (window.location.port == "")? 80:window.location.port;
  168 + obj.pathname = window.location.pathname;
  169 + if (obj.pathname.lastIndexOf("/") <= 0) {
  170 + obj.dir = "/";
  171 + obj.filename = "";
  172 + } else {
  173 + obj.dir = obj.pathname.substr(0, obj.pathname.lastIndexOf("/"));
  174 + obj.filename = obj.pathname.substr(obj.pathname.lastIndexOf("/"));
  175 + }
  176 +
  177 + // pure user query object.
  178 + obj.user_query = {};
  179 +
  180 + // parse the query string.
  181 + var query_string = String(window.location.search).replace(" ", "").split("?")[1];
  182 + if(query_string == undefined){
  183 + query_string = String(window.location.hash).replace(" ", "").split("#")[1];
  184 + if(query_string == undefined){
  185 + return obj;
  186 + }
  187 + }
  188 +
  189 + var queries = query_string.split("&");
  190 + $(queries).each(function(){
  191 + var query = this.split("=");
  192 + obj[query[0]] = query[1];
  193 + obj.user_query[query[0]] = query[1];
  194 + });
  195 +
  196 + return obj;
  197 +}
  198 +
  199 +/**
  200 + * parse the rtmp url,
  201 + * for example: rtmp://demo.srs.com:1935/live...vhost...players/livestream
  202 + * @return object {server, port, vhost, app, stream}
  203 + * for exmaple, rtmp_url is rtmp://demo.srs.com:1935/live...vhost...players/livestream
  204 + * parsed to object:
  205 + {
  206 + server: "demo.srs.com",
  207 + port: 1935,
  208 + vhost: "players",
  209 + app: "live",
  210 + stream: "livestream"
  211 + }
  212 + */
  213 +function parse_rtmp_url(rtmp_url) {
  214 + // @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri
  215 + var a = document.createElement("a");
  216 + a.href = rtmp_url.replace("rtmp://", "http://");
  217 +
  218 + var vhost = a.hostname;
  219 + var port = (a.port == "")? "1935":a.port;
  220 + var app = a.pathname.substr(1, a.pathname.lastIndexOf("/") - 1);
  221 + var stream = a.pathname.substr(a.pathname.lastIndexOf("/") + 1);
  222 +
  223 + // parse the vhost in the params of app, that srs supports.
  224 + app = app.replace("...vhost...", "?vhost=");
  225 + if (app.indexOf("?") >= 0) {
  226 + var params = app.substr(app.indexOf("?"));
  227 + app = app.substr(0, app.indexOf("?"));
  228 +
  229 + if (params.indexOf("vhost=") > 0) {
  230 + vhost = params.substr(params.indexOf("vhost=") + "vhost=".length);
  231 + if (vhost.indexOf("&") > 0) {
  232 + vhost = vhost.substr(0, vhost.indexOf("&"));
  233 + }
  234 + }
  235 + }
  236 +
  237 + var ret = {
  238 + server: a.hostname, port: port,
  239 + vhost: vhost, app: app, stream: stream
  240 + };
  241 +
  242 + return ret;
  243 +}
  244 +
  245 +/**
  246 + * get the agent.
  247 + * @return an object specifies some browser.
  248 + * for example, get_browser_agents().MSIE
  249 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  250 + */
  251 +function get_browser_agents() {
  252 + var agent = navigator.userAgent;
  253 +
  254 + /**
  255 + WindowsPC platform, Win7:
  256 + chrome 31.0.1650.63:
  257 + Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
  258 + (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
  259 + firefox 23.0.1:
  260 + Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101
  261 + Firefox/23.0
  262 + safari 5.1.7(7534.57.2):
  263 + Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2
  264 + (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2
  265 + opera 15.0.1147.153:
  266 + Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36
  267 + (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
  268 + OPR/15.0.1147.153
  269 + 360 6.2.1.272:
  270 + Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;
  271 + Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;
  272 + .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;
  273 + .NET4.0E)
  274 + IE 10.0.9200.16750(update: 10.0.12):
  275 + Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64;
  276 + Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729;
  277 + .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C;
  278 + .NET4.0E)
  279 + */
  280 +
  281 + return {
  282 + // platform
  283 + Android: agent.indexOf("Android") != -1,
  284 + Windows: agent.indexOf("Windows") != -1,
  285 + iPhone: agent.indexOf("iPhone") != -1,
  286 + // Windows Browsers
  287 + Chrome: agent.indexOf("Chrome") != -1,
  288 + Firefox: agent.indexOf("Firefox") != -1,
  289 + QQBrowser: agent.indexOf("QQBrowser") != -1,
  290 + MSIE: agent.indexOf("MSIE") != -1,
  291 + // Android Browsers
  292 + Opera: agent.indexOf("Presto") != -1,
  293 + MQQBrowser: agent.indexOf("MQQBrowser") != -1
  294 + };
  295 +}
  296 +
  297 +/**
  298 + * format relative seconds to HH:MM:SS,
  299 + * for example, 210s formated to 00:03:30
  300 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  301 + * @usage relative_seconds_to_HHMMSS(210)
  302 + */
  303 +function relative_seconds_to_HHMMSS(seconds){
  304 + var date = new Date();
  305 + date.setTime(Number(seconds) * 1000);
  306 +
  307 + var ret = padding(date.getUTCHours(), 2, '0')
  308 + + ":" + padding(date.getUTCMinutes(), 2, '0')
  309 + + ":" + padding(date.getUTCSeconds(), 2, '0');
  310 +
  311 + return ret;
  312 +}
  313 +
  314 +/**
  315 + * format absolute seconds to HH:MM:SS,
  316 + * for example, 1389146480s (2014-01-08 10:01:20 GMT+0800) formated to 10:01:20
  317 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  318 + * @usage absolute_seconds_to_HHMMSS(new Date().getTime() / 1000)
  319 + */
  320 +function absolute_seconds_to_HHMMSS(seconds){
  321 + var date = new Date();
  322 + date.setTime(Number(seconds) * 1000);
  323 +
  324 + var ret = padding(date.getHours(), 2, '0')
  325 + + ":" + padding(date.getMinutes(), 2, '0')
  326 + + ":" + padding(date.getSeconds(), 2, '0');
  327 +
  328 + return ret;
  329 +}
  330 +
  331 +/**
  332 + * format absolute seconds to YYYY-mm-dd,
  333 + * for example, 1389146480s (2014-01-08 10:01:20 GMT+0800) formated to 2014-01-08
  334 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  335 + * @usage absolute_seconds_to_YYYYmmdd(new Date().getTime() / 1000)
  336 + */
  337 +function absolute_seconds_to_YYYYmmdd(seconds) {
  338 + var date = new Date();
  339 + date.setTime(Number(seconds) * 1000);
  340 +
  341 + var ret = date.getFullYear()
  342 + + "-" + padding(date.getMonth() + 1, 2, '0')
  343 + + "-" + padding(date.getDate(), 2, '0');
  344 +
  345 + return ret;
  346 +}
  347 +
  348 +/**
  349 + * parse the date in str to Date object.
  350 + * @param str the date in str, format as "YYYY-mm-dd", for example, 2014-12-11
  351 + * @returns a date object.
  352 + * @usage YYYYmmdd_parse("2014-12-11")
  353 + */
  354 +function YYYYmmdd_parse(str) {
  355 + var date = new Date();
  356 + date.setTime(Date.parse(str));
  357 + return date;
  358 +}
  359 +
  360 +/**
  361 + * async refresh function call. to avoid multiple call.
  362 + * @remark AsyncRefresh is for jquery to refresh the speicified pfn in a page;
  363 + * if angularjs, use AsyncRefresh2 to change pfn, cancel previous request for angularjs use singleton object.
  364 + * @param refresh_interval the default refresh interval ms.
  365 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  366 + * the pfn can be implements as following:
  367 + var async_refresh = new AsyncRefresh(pfn, 3000);
  368 + function pfn() {
  369 + if (!async_refresh.refresh_is_enabled()) {
  370 + async_refresh.request(100);
  371 + return;
  372 + }
  373 + $.ajax({
  374 + type: 'GET', async: true, url: 'xxxxx',
  375 + complete: function(){
  376 + if (!async_refresh.refresh_is_enabled()) {
  377 + async_refresh.request(0);
  378 + } else {
  379 + async_refresh.request(async_refresh.refresh_interval);
  380 + }
  381 + },
  382 + success: function(res){
  383 + // if donot allow refresh, directly return.
  384 + if (!async_refresh.refresh_is_enabled()) {
  385 + return;
  386 + }
  387 +
  388 + // render the res.
  389 + }
  390 + });
  391 + }
  392 + */
  393 +function AsyncRefresh(pfn, refresh_interval) {
  394 + this.refresh_interval = refresh_interval;
  395 +
  396 + this.__handler = null;
  397 + this.__pfn = pfn;
  398 +
  399 + this.__enabled = true;
  400 +}
  401 +/**
  402 + * disable the refresher, the pfn must check the refresh state.
  403 + */
  404 +AsyncRefresh.prototype.refresh_disable = function() {
  405 + this.__enabled = false;
  406 +}
  407 +AsyncRefresh.prototype.refresh_enable = function() {
  408 + this.__enabled = true;
  409 +}
  410 +AsyncRefresh.prototype.refresh_is_enabled = function() {
  411 + return this.__enabled;
  412 +}
  413 +/**
  414 + * start new async request
  415 + * @param timeout the timeout in ms.
  416 + * user can use the refresh_interval of the AsyncRefresh object,
  417 + * which initialized in constructor.
  418 + */
  419 +AsyncRefresh.prototype.request = function(timeout) {
  420 + if (this.__handler) {
  421 + clearTimeout(this.__handler);
  422 + }
  423 +
  424 + this.__handler = setTimeout(this.__pfn, timeout);
  425 +}
  426 +
  427 +/**
  428 + * async refresh v2, support cancellable refresh, and change the refresh pfn.
  429 + * @remakr for angularjs. if user only need jquery, maybe AsyncRefresh is better.
  430 + * @see: http://blog.csdn.net/win_lin/article/details/17994347
  431 + * Usage:
  432 + bsmControllers.controller('CServers', ['$scope', 'MServer', function($scope, MServer){
  433 + async_refresh2.refresh_change(function(){
  434 + // 获取服务器列表
  435 + MServer.servers_load({}, function(data){
  436 + $scope.servers = data.data.servers;
  437 + async_refresh2.request();
  438 + });
  439 + }, 3000);
  440 +
  441 + async_refresh2.request(0);
  442 + }]);
  443 + bsmControllers.controller('CStreams', ['$scope', 'MStream', function($scope, MStream){
  444 + async_refresh2.refresh_change(function(){
  445 + // 获取流列表
  446 + MStream.streams_load({}, function(data){
  447 + $scope.streams = data.data.streams;
  448 + async_refresh2.request();
  449 + });
  450 + }, 3000);
  451 +
  452 + async_refresh2.request(0);
  453 + }]);
  454 + */
  455 +function AsyncRefresh2() {
  456 + /**
  457 + * the function callback before call the pfn.
  458 + * the protype is function():bool, which return true to invoke, false to abort the call.
  459 + * null to ignore this callback.
  460 + *
  461 + * for example, user can abort the refresh by find the class popover:
  462 + * async_refresh2.on_before_call_pfn = function() {
  463 + * if ($(".popover").length > 0) {
  464 + * async_refresh2.request();
  465 + * return false;
  466 + * }
  467 + * return true;
  468 + * };
  469 + */
  470 + this.on_before_call_pfn = null;
  471 +
  472 + // use a anonymous function to call, and check the enabled when actually invoke.
  473 + this.__call = {
  474 + pfn: null,
  475 + timeout: 0,
  476 + __enabled: false,
  477 + __handler: null
  478 + };
  479 +}
  480 +// singleton
  481 +var async_refresh2 = new AsyncRefresh2();
  482 +/**
  483 + * initialize or refresh change. cancel previous request, setup new request.
  484 + * @param pfn a function():void to request after timeout. null to disable refresher.
  485 + * @param timeout the timeout in ms, to call pfn. null to disable refresher.
  486 + */
  487 +AsyncRefresh2.prototype.initialize = function(pfn, timeout) {
  488 + this.refresh_change(pfn, timeout);
  489 +}
  490 +/**
  491 + * stop refresh, the refresh pfn is set to null.
  492 + */
  493 +AsyncRefresh2.prototype.stop = function() {
  494 + this.refresh_change(null, null);
  495 +}
  496 +/**
  497 + * change refresh pfn, the old pfn will set to disabled.
  498 + */
  499 +AsyncRefresh2.prototype.refresh_change = function(pfn, timeout) {
  500 + // cancel the previous call.
  501 + if (this.__call.__handler) {
  502 + clearTimeout(this.__handler);
  503 + }
  504 + this.__call.__enabled = false;
  505 +
  506 + // setup new call.
  507 + this.__call = {
  508 + pfn: pfn,
  509 + timeout: timeout,
  510 + __enabled: true,
  511 + __handler: null
  512 + };
  513 +}
  514 +/**
  515 + * start new request, we never auto start the request,
  516 + * user must start new request when previous completed.
  517 + * @param timeout [optional] if not specified, use the timeout in initialize or refresh_change.
  518 + */
  519 +AsyncRefresh2.prototype.request = function(timeout) {
  520 + var self = this;
  521 + var this_call = this.__call;
  522 +
  523 + // clear previous timeout.
  524 + if (this_call.__handler) {
  525 + clearTimeout(this_call.__handler);
  526 + }
  527 +
  528 + // override the timeout
  529 + if (timeout == undefined) {
  530 + timeout = this_call.timeout;
  531 + }
  532 +
  533 + // if user disabled refresher.
  534 + if (this_call.pfn == null || timeout == null) {
  535 + return;
  536 + }
  537 +
  538 + this_call.__handler = setTimeout(function(){
  539 + // cancelled by refresh_change, ignore.
  540 + if (!this_call.__enabled) {
  541 + return;
  542 + }
  543 +
  544 + // callback if the handler installled.
  545 + if (self.on_before_call_pfn) {
  546 + if (!self.on_before_call_pfn()) {
  547 + return;
  548 + }
  549 + }
  550 +
  551 + // do the actual call.
  552 + this_call.pfn();
  553 + }, timeout);
  554 +}
  555 +
  556 +// other components.
  557 +/**
  558 + * jquery/bootstrap pager.
  559 + * depends: jquery1.10, boostrap2
  560 + * https://code.csdn.net/snippets/146160
  561 + * @see: http://blog.csdn.net/win_lin/article/details/17628631
  562 + */
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 <script type="text/javascript" src="js/srs.player.js"></script> 11 <script type="text/javascript" src="js/srs.player.js"></script>
12 <script type="text/javascript" src="js/srs.publisher.js"></script> 12 <script type="text/javascript" src="js/srs.publisher.js"></script>
13 <script type="text/javascript" src="js/srs.utility.js"></script> 13 <script type="text/javascript" src="js/srs.utility.js"></script>
  14 + <script type="text/javascript" src="js/winlin.utility.js"></script>
14 <style> 15 <style>
15 body{ 16 body{
16 padding-top: 55px; 17 padding-top: 55px;
@@ -5,9 +5,10 @@ @@ -5,9 +5,10 @@
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 </head> 6 </head>
7 <body> 7 <body>
8 - <script type="text/javascript"> 8 +</body>
  9 +<script type="text/javascript">
9 setTimeout(function(){ 10 setTimeout(function(){
10 window.location.href = "players/index.html" + window.location.search; 11 window.location.href = "players/index.html" + window.location.search;
11 }, 500); 12 }, 500);
12 - </script>  
13 -</body>  
  13 +</script>
  14 +</html>
@@ -4,14 +4,6 @@ @@ -4,14 +4,6 @@
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
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>  
9 - <script type="text/javascript" src="js/swfobject.js"></script>  
10 - <script type="text/javascript" src="js/srs.page.js"></script>  
11 - <script type="text/javascript" src="js/srs.log.js"></script>  
12 - <script type="text/javascript" src="js/srs.player.js"></script>  
13 - <script type="text/javascript" src="js/srs.publisher.js"></script>  
14 - <script type="text/javascript" src="js/srs.utility.js"></script>  
15 <style> 7 <style>
16 body{ 8 body{
17 padding-top: 55px; 9 padding-top: 55px;
@@ -21,7 +13,63 @@ @@ -21,7 +13,63 @@
21 margin-left: -350px; 13 margin-left: -350px;
22 } 14 }
23 </style> 15 </style>
24 - <script type="text/javascript"> 16 +</head>
  17 +<body>
  18 +<div class="navbar navbar-fixed-top">
  19 + <div class="navbar-inner">
  20 + <div class="container">
  21 + <a id="srs_index" class="brand" href="#">SRS</a>
  22 + <div class="nav-collapse collapse">
  23 + <ul class="nav">
  24 + <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li>
  25 + <li><a id="nav_srs_publisher" href="srs_publisher.html">SRS编码器</a></li>
  26 + <li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>
  27 + <li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>
  28 + <li><a id="nav_jwplayer6" href="jwplayer6.html">JWPlayer6播放器</a></li>
  29 + <li class="active"><a id="nav_osmf" href="osmf.html">AdobeOSMF播放器</a></li>
  30 + <li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>
  31 + </ul>
  32 + </div>
  33 + </div>
  34 + </div>
  35 +</div>
  36 +<div class="container">
  37 + <div class="alert alert-info fade in">
  38 + <button type="button" class="close" data-dismiss="alert">×</button>
  39 + <strong><span>Usage:</span></strong> <span>输入地址后点击播放按钮</span>
  40 + </div>
  41 + <div class="form-inline">
  42 + URL:
  43 + <input type="text" id="txt_url" class="input-xxlarge" value=""></input>
  44 + <button class="btn btn-primary" id="btn_play">播放视频</button>
  45 + </div>
  46 + <div id="main_modal" class="modal hide fade">
  47 + <div class="modal-header">
  48 + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
  49 + <h3>AdobeOSMF</h3>
  50 + </div>
  51 + <div class="modal-body" id="player">
  52 + </div>
  53 + <div class="modal-footer">
  54 + <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button>
  55 + </div>
  56 + </div>
  57 + <hr>
  58 + <footer>
  59 + <p><a href="https://github.com/simple-rtmp-server/srs">SRS Team &copy; 2013</a></p>
  60 + </footer>
  61 +</div>
  62 +</body>
  63 +<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  64 +<script type="text/javascript" src="js/bootstrap.min.js"></script>
  65 +<script type="text/javascript" src="js/swfobject.js"></script>
  66 +<script type="text/javascript" src="js/srs.page.js"></script>
  67 +<script type="text/javascript" src="js/srs.log.js"></script>
  68 +<script type="text/javascript" src="js/srs.player.js"></script>
  69 +<script type="text/javascript" src="js/srs.publisher.js"></script>
  70 +<script type="text/javascript" src="js/srs.utility.js"></script>
  71 +<script type="text/javascript" src="js/winlin.utility.js"></script>
  72 +<script type="text/javascript">
25 function osmf_play(url) { 73 function osmf_play(url) {
26 $("#div_container").remove(); 74 $("#div_container").remove();
27 75
@@ -57,7 +105,7 @@ @@ -57,7 +105,7 @@
57 // get the vhost and port to set the default url. 105 // get the vhost and port to set the default url.
58 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo 106 // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
59 // url set to: rtmp://demo:1935/live/livestream 107 // url set to: rtmp://demo:1935/live/livestream
60 - srs_init("#txt_url", null, "#main_modal"); 108 + srs_init_rtmp("#txt_url", "#main_modal");
61 109
62 $("#main_modal").on("hide", function(){ 110 $("#main_modal").on("hide", function(){
63 osmf_play("http://localhost"); 111 osmf_play("http://localhost");
@@ -72,51 +120,5 @@ @@ -72,51 +120,5 @@
72 $("#main_modal").modal({show:true, keyboard:false}); 120 $("#main_modal").modal({show:true, keyboard:false});
73 }); 121 });
74 }); 122 });
75 - </script>  
76 -</head>  
77 -<body>  
78 -<div class="navbar navbar-fixed-top">  
79 - <div class="navbar-inner">  
80 - <div class="container">  
81 - <a id="srs_index" class="brand" href="#">SRS</a>  
82 - <div class="nav-collapse collapse">  
83 - <ul class="nav">  
84 - <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li>  
85 - <li><a id="nav_srs_publisher" href="srs_publisher.html">SRS编码器</a></li>  
86 - <li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>  
87 - <li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>  
88 - <li><a id="nav_jwplayer6" href="jwplayer6.html">JWPlayer6播放器</a></li>  
89 - <li class="active"><a id="nav_osmf" href="osmf.html">AdobeOSMF播放器</a></li>  
90 - <li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>  
91 - </ul>  
92 - </div>  
93 - </div>  
94 - </div>  
95 -</div>  
96 -<div class="container">  
97 - <div class="alert alert-info fade in">  
98 - <button type="button" class="close" data-dismiss="alert">×</button>  
99 - <strong><span>Usage:</span></strong> <span>输入地址后点击播放按钮</span>  
100 - </div>  
101 - <div class="form-inline">  
102 - URL:  
103 - <input type="text" id="txt_url" class="input-xxlarge" value=""></input>  
104 - <button class="btn btn-primary" id="btn_play">播放视频</button>  
105 - </div>  
106 - <div id="main_modal" class="modal hide fade">  
107 - <div class="modal-header">  
108 - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>  
109 - <h3>AdobeOSMF</h3>  
110 - </div>  
111 - <div class="modal-body" id="player">  
112 - </div>  
113 - <div class="modal-footer">  
114 - <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button>  
115 - </div>  
116 - </div>  
117 - <hr>  
118 - <footer>  
119 - <p><a href="https://github.com/simple-rtmp-server/srs">SRS Team &copy; 2013</a></p>  
120 - </footer>  
121 -</div>  
122 -</body> 123 +</script>
  124 +</html>
@@ -3,14 +3,16 @@ @@ -3,14 +3,16 @@
3 <head> 3 <head>
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 - <script type="text/javascript" src="players/js/jquery-1.10.2.min.js"></script>  
7 - <script type="text/javascript" src="players/js/srs.page.js"></script>  
8 - <script type="text/javascript" src="players/js/srs.utility.js"></script>  
9 </head> 6 </head>
10 <body> 7 <body>
11 - <script type="text/javascript"> 8 +</body>
  9 +<script type="text/javascript" src="players/js/jquery-1.10.2.min.js"></script>
  10 +<script type="text/javascript" src="players/js/srs.page.js"></script>
  11 +<script type="text/javascript" src="players/js/srs.utility.js"></script>
  12 +<script type="text/javascript" src="players/js/winlin.utility.js"></script>
  13 +<script type="text/javascript">
12 setTimeout(function(){ 14 setTimeout(function(){
13 window.location.href = "players/index.html" + window.location.search; 15 window.location.href = "players/index.html" + window.location.search;
14 }, 500); 16 }, 500);
15 - </script>  
16 -</body> 17 +</script>
  18 +</html>
@@ -4,15 +4,6 @@ @@ -4,15 +4,6 @@
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
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>  
9 - <script type="text/javascript" src="js/swfobject.js"></script>  
10 - <script type="text/javascript" src="js/srs.page.js"></script>  
11 - <script type="text/javascript" src="js/srs.log.js"></script>  
12 - <script type="text/javascript" src="js/srs.player.js"></script>  
13 - <script type="text/javascript" src="js/srs.publisher.js"></script>  
14 - <script type="text/javascript" src="js/srs.utility.js"></script>  
15 - <script type="text/javascript" src="srs_bwt/src/srs.bandwidth.js"></script>  
16 <style> 7 <style>
17 body{ 8 body{
18 padding-top: 55px; 9 padding-top: 55px;
@@ -22,62 +13,6 @@ @@ -22,62 +13,6 @@
22 margin-left: -350px; 13 margin-left: -350px;
23 } 14 }
24 </style> 15 </style>
25 - <script type="text/javascript">  
26 - var bandwidth = null;  
27 -  
28 - $(function(){  
29 - srs_init_bwt("#txt_url");  
30 -  
31 - $("#btn_play").click(on_click_play);  
32 - $("#main_modal").on("show", on_start_bandwidth_test);  
33 - $("#main_modal").on("hide", on_stop_bandwidth_test);  
34 - });  
35 -  
36 - function on_click_play() {  
37 - $("#check_status").text("");  
38 - $("#check_info").text("");  
39 - $("#progress_bar").width("0%");  
40 - $("#main_modal").modal({show:true, keyboard:false});  
41 - }  
42 - function on_start_bandwidth_test() {  
43 - $("#div_container").remove();  
44 - $("#progress_bar").removeClass("bar-danger");  
45 -  
46 - var div_container = $("<div/>");  
47 - $(div_container).attr("id", "div_container");  
48 - $("#player").append(div_container);  
49 -  
50 - var player = $("<div/>");  
51 - $(player).attr("id", "player_id");  
52 - $(div_container).append(player);  
53 -  
54 - var url = $("#txt_url").val();  
55 -  
56 - bandwidth = new SrsBandwidth("player_id", 100, 1);  
57 - bandwidth.on_bandwidth_ready = function() {  
58 - this.check_bandwidth(url);  
59 - }  
60 - bandwidth.on_update_progress = function(percent) {  
61 - $("#progress_bar").width(percent + "%");  
62 - }  
63 - bandwidth.on_update_status = function(status) {  
64 - $("#check_status").text(status);  
65 - }  
66 - bandwidth.on_srs_info = function(srs_server, srs_primary, srs_authors, srs_id, srs_pid, srs_server_ip) {  
67 - $("#check_info").text(  
68 - "server:" + srs_server + ", primary:" + srs_primary + ", authors:" + srs_authors +  
69 - ", srs_id:" + srs_id + ", srs_pid:" + srs_pid + ", ip:" + srs_server_ip  
70 - );  
71 - }  
72 - bandwidth.on_error = function(code) {  
73 - $("#progress_bar").addClass("bar-danger");  
74 - }  
75 - bandwidth.render(url);  
76 - }  
77 - function on_stop_bandwidth_test() {  
78 - bandwidth.stop();  
79 - }  
80 - </script>  
81 </head> 16 </head>
82 <body> 17 <body>
83 <div class="navbar navbar-fixed-top"> 18 <div class="navbar navbar-fixed-top">
@@ -139,4 +74,70 @@ @@ -139,4 +74,70 @@
139 </div> 74 </div>
140 </div> 75 </div>
141 </body> 76 </body>
  77 +<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  78 +<script type="text/javascript" src="js/bootstrap.min.js"></script>
  79 +<script type="text/javascript" src="js/swfobject.js"></script>
  80 +<script type="text/javascript" src="js/srs.page.js"></script>
  81 +<script type="text/javascript" src="js/srs.log.js"></script>
  82 +<script type="text/javascript" src="js/srs.player.js"></script>
  83 +<script type="text/javascript" src="js/srs.publisher.js"></script>
  84 +<script type="text/javascript" src="js/srs.utility.js"></script>
  85 +<script type="text/javascript" src="js/winlin.utility.js"></script>
  86 +<script type="text/javascript" src="srs_bwt/src/srs.bandwidth.js"></script>
  87 +<script type="text/javascript">
  88 + var bandwidth = null;
  89 +
  90 + $(function(){
  91 + srs_init_bwt("#txt_url");
  92 +
  93 + $("#btn_play").click(on_click_play);
  94 + $("#main_modal").on("show", on_start_bandwidth_test);
  95 + $("#main_modal").on("hide", on_stop_bandwidth_test);
  96 + });
  97 +
  98 + function on_click_play() {
  99 + $("#check_status").text("");
  100 + $("#check_info").text("");
  101 + $("#progress_bar").width("0%");
  102 + $("#main_modal").modal({show:true, keyboard:false});
  103 + }
  104 + function on_start_bandwidth_test() {
  105 + $("#div_container").remove();
  106 + $("#progress_bar").removeClass("bar-danger");
  107 +
  108 + var div_container = $("<div/>");
  109 + $(div_container).attr("id", "div_container");
  110 + $("#player").append(div_container);
  111 +
  112 + var player = $("<div/>");
  113 + $(player).attr("id", "player_id");
  114 + $(div_container).append(player);
142 115
  116 + var url = $("#txt_url").val();
  117 +
  118 + bandwidth = new SrsBandwidth("player_id", 100, 1);
  119 + bandwidth.on_bandwidth_ready = function() {
  120 + this.check_bandwidth(url);
  121 + }
  122 + bandwidth.on_update_progress = function(percent) {
  123 + $("#progress_bar").width(percent + "%");
  124 + }
  125 + bandwidth.on_update_status = function(status) {
  126 + $("#check_status").text(status);
  127 + }
  128 + bandwidth.on_srs_info = function(srs_server, srs_primary, srs_authors, srs_id, srs_pid, srs_server_ip) {
  129 + $("#check_info").text(
  130 + "server:" + srs_server + ", primary:" + srs_primary + ", authors:" + srs_authors +
  131 + ", srs_id:" + srs_id + ", srs_pid:" + srs_pid + ", ip:" + srs_server_ip
  132 + );
  133 + }
  134 + bandwidth.on_error = function(code) {
  135 + $("#progress_bar").addClass("bar-danger");
  136 + }
  137 + bandwidth.render(url);
  138 + }
  139 + function on_stop_bandwidth_test() {
  140 + bandwidth.stop();
  141 + }
  142 +</script>
  143 +</html>
@@ -4,15 +4,6 @@ @@ -4,15 +4,6 @@
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
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>  
9 - <script type="text/javascript" src="js/swfobject.js"></script>  
10 - <script type="text/javascript" src="js/json2.js"></script>  
11 - <script type="text/javascript" src="js/srs.page.js"></script>  
12 - <script type="text/javascript" src="js/srs.log.js"></script>  
13 - <script type="text/javascript" src="js/srs.player.js"></script>  
14 - <script type="text/javascript" src="js/srs.publisher.js"></script>  
15 - <script type="text/javascript" src="js/srs.utility.js"></script>  
16 <style> 7 <style>
17 body{ 8 body{
18 padding-top: 55px; 9 padding-top: 55px;
@@ -21,7 +12,255 @@ @@ -21,7 +12,255 @@
21 width: 310px; 12 width: 310px;
22 } 13 }
23 </style> 14 </style>
24 - <script type="text/javascript"> 15 +</head>
  16 +<body>
  17 +<div class="navbar navbar-fixed-top">
  18 + <div class="navbar-inner">
  19 + <div class="container">
  20 + <a id="srs_index" class="brand" href="#">SRS</a>
  21 + <div class="nav-collapse collapse">
  22 + <ul class="nav">
  23 + <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li>
  24 + <li><a id="nav_srs_publisher" href="srs_publisher.html">SRS编码器</a></li>
  25 + <li class="active"><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>
  26 + <li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>
  27 + <li><a id="nav_jwplayer6" href="jwplayer6.html">JWPlayer6播放器</a></li>
  28 + <li><a id="nav_osmf" href="osmf.html">AdobeOSMF播放器</a></li>
  29 + <li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>
  30 + </ul>
  31 + </div>
  32 + </div>
  33 + </div>
  34 +</div>
  35 +<div class="container">
  36 + <!-- for the log -->
  37 + <div class="alert alert-info fade in" id="txt_log">
  38 + <button type="button" class="close" data-dismiss="alert">×</button>
  39 + <strong><span id="txt_log_title">Usage:</span></strong>
  40 + <span id="txt_log_msg">输入名字,设点“加入会议”按钮</span>
  41 + </div>
  42 +
  43 + <div class="control-group">
  44 + <div class="form-inline">
  45 + <button class="btn input-small" id="btn_video_settings">摄像头</button>
  46 + <button class="btn input-small" id="btn_audio_settings">麦克风</button>
  47 + <input type="text" id="txt_name" class="input-large" placeholder="请输入您的名字..." value=""></input>
  48 + <button class="btn input-small" id="btn_join">加入会议</button>
  49 + <input type="text" id="txt_url" class="input-mini hide" value=""></input>
  50 + </div>
  51 + </div>
  52 + <table id="lst_chats" class="table">
  53 + <tr>
  54 + <td id="td_0">
  55 + <div class="accordion-group">
  56 + <div class="accordion-heading">
  57 + <span class="accordion-toggle">
  58 + <strong>[我的] 本地摄像头</strong>
  59 + </span>
  60 + </div>
  61 + <div class="accordion-body collapse in">
  62 + <div class="accordion-inner">
  63 + <div id="local_publisher"></div>
  64 + </div>
  65 + </div>
  66 + </div>
  67 + </td>
  68 + <td id="td_1">
  69 + <div class="accordion-group">
  70 + <div class="accordion-heading">
  71 + <span class="accordion-toggle">
  72 + <strong>[我的] 远程服务器流</strong>
  73 + <a id="realtime_player_url" href="#" data-toggle="tooltip" data-placement="top" title="">
  74 + 播放地址<img src="img/tooltip.png"/>
  75 + </a>
  76 + </span>
  77 + </div>
  78 + <div class="accordion-body collapse in">
  79 + <div class="accordion-inner">
  80 + <div id="realtime_player"></div>
  81 + </div>
  82 + </div>
  83 + </div>
  84 + </td>
  85 + <td id="td_2"></td>
  86 + </tr>
  87 + </table>
  88 + <div class="container hide" id="template">
  89 + <div class="accordion-group" id="collapse_main">
  90 + <div class="accordion-heading" title="点击展开或收起,收起后停止播放流,展开时从服务器请求流">
  91 + <span id="headerN" class="accordion-toggle" data-toggle="collapse" href="#collapseN">
  92 + <strong>[<a href="#"><span id="user_name">XX</span></a>]</strong>
  93 + <strong>加入时间</strong>[<span id="join_date"></span>]
  94 + <a id="user_player_url" href="#" data-toggle="tooltip" data-placement="top" title="">
  95 + 播放地址<img src="img/tooltip.png"/>
  96 + </a>
  97 + </span>
  98 + </div>
  99 + <div id="collapseM" class="accordion-body collapse in">
  100 + <div class="accordion-inner">
  101 + <div id="chat_player">
  102 + <div id="chat_player_raw">
  103 + </div>
  104 + </div>
  105 + </div>
  106 + </div>
  107 + </div>
  108 + </div>
  109 + <table class="table">
  110 + </table>
  111 + <div id="video_modal" class="modal hide fade">
  112 + <div class="modal-header">
  113 + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
  114 + <h3>视频编码</h3>
  115 + </div>
  116 + <div class="modal-body">
  117 + <div class="form-horizontal">
  118 + <div class="control-group">
  119 + <label class="control-label" for="sl_cameras">
  120 + 摄像头
  121 + <a id="sl_cameras_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  122 + <img src="img/tooltip.png"/>
  123 + </a>
  124 + </label>
  125 + <div class="controls">
  126 + <select class="span4" id="sl_cameras"></select>
  127 + </div>
  128 + </div>
  129 + <div class="control-group">
  130 + <label class="control-label" for="sl_vcodec">
  131 + Codec
  132 + <a id="sl_cameras_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  133 + <img src="img/tooltip.png"/>
  134 + </a>
  135 + </label>
  136 + <div class="controls">
  137 + <select class="span2" id="sl_vcodec"></select>
  138 + </div>
  139 + </div>
  140 + <div class="control-group">
  141 + <label class="control-label" for="sl_profile">
  142 + Profile
  143 + <a id="sl_profile_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  144 + <img src="img/tooltip.png"/>
  145 + </a>
  146 + </label>
  147 + <div class="controls">
  148 + <select class="span2" id="sl_profile"></select>
  149 + </div>
  150 + </div>
  151 + <div class="control-group">
  152 + <label class="control-label" for="sl_level">
  153 + Level
  154 + <a id="sl_level_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  155 + <img src="img/tooltip.png"/>
  156 + </a>
  157 + </label>
  158 + <div class="controls">
  159 + <select class="span2" id="sl_level"></select>
  160 + </div>
  161 + </div>
  162 + <div class="control-group">
  163 + <label class="control-label" for="sl_gop">
  164 + GOP
  165 + <a id="sl_gop_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  166 + <img src="img/tooltip.png"/>
  167 + </a>
  168 + </label>
  169 + <div class="controls">
  170 + <select class="span2" id="sl_gop"></select>
  171 + </div>
  172 + </div>
  173 + <div class="control-group">
  174 + <label class="control-label" for="sl_size">
  175 + 尺寸
  176 + <a id="sl_size_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  177 + <img src="img/tooltip.png"/>
  178 + </a>
  179 + </label>
  180 + <div class="controls">
  181 + <select class="span2" id="sl_size"></select>
  182 + </div>
  183 + </div>
  184 + <div class="control-group">
  185 + <label class="control-label" for="sl_fps">
  186 + 帧率
  187 + <a id="sl_fps_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  188 + <img src="img/tooltip.png"/>
  189 + </a>
  190 + </label>
  191 + <div class="controls">
  192 + <select class="span2" id="sl_fps"></select>
  193 + </div>
  194 + </div>
  195 + <div class="control-group">
  196 + <label class="control-label" for="sl_bitrate">
  197 + 码率
  198 + <a id="sl_bitrate_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  199 + <img src="img/tooltip.png"/>
  200 + </a>
  201 + </label>
  202 + <div class="controls">
  203 + <select class="span2" id="sl_bitrate"></select>
  204 + </div>
  205 + </div>
  206 + </div>
  207 + </div>
  208 + <div class="modal-footer">
  209 + <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">设置</button>
  210 + </div>
  211 + </div>
  212 + <div id="audio_modal" class="modal hide fade">
  213 + <div class="modal-header">
  214 + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
  215 + <h3>音频编码</h3>
  216 + </div>
  217 + <div class="modal-body">
  218 + <div class="form-horizontal">
  219 + <div class="control-group">
  220 + <label class="control-label" for="sl_microphones">
  221 + 麦克风
  222 + <a id="worker_id_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  223 + <img src="img/tooltip.png"/>
  224 + </a>
  225 + </label>
  226 + <div class="controls">
  227 + <select class="span4" id="sl_microphones"></select>
  228 + </div>
  229 + </div>
  230 + <div class="control-group">
  231 + <label class="control-label" for="sl_acodec">
  232 + 编码
  233 + <a id="sl_acodec_tips" href="#" data-toggle="tooltip" data-placement="right" title="">
  234 + <img src="img/tooltip.png"/>
  235 + </a>
  236 + </label>
  237 + <div class="controls">
  238 + <select class="span2" id="sl_acodec"></select>
  239 + </div>
  240 + </div>
  241 + </div>
  242 + </div>
  243 + <div class="modal-footer">
  244 + <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">设置</button>
  245 + </div>
  246 + </div>
  247 + <hr/>
  248 + <footer>
  249 + <p><a href="https://github.com/simple-rtmp-server/srs">SRS Team &copy; 2013</a></p>
  250 + </footer>
  251 +</div>
  252 +</body>
  253 +<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  254 +<script type="text/javascript" src="js/bootstrap.min.js"></script>
  255 +<script type="text/javascript" src="js/swfobject.js"></script>
  256 +<script type="text/javascript" src="js/json2.js"></script>
  257 +<script type="text/javascript" src="js/srs.page.js"></script>
  258 +<script type="text/javascript" src="js/srs.log.js"></script>
  259 +<script type="text/javascript" src="js/srs.player.js"></script>
  260 +<script type="text/javascript" src="js/srs.publisher.js"></script>
  261 +<script type="text/javascript" src="js/srs.utility.js"></script>
  262 +<script type="text/javascript" src="js/winlin.utility.js"></script>
  263 +<script type="text/javascript">
25 var srs_publisher = null; 264 var srs_publisher = null;
26 var realtime_player = null; 265 var realtime_player = null;
27 var api_server = null; 266 var api_server = null;
@@ -546,243 +785,6 @@ @@ -546,243 +785,6 @@
546 } 785 }
547 }); 786 });
548 } 787 }
549 - </script>  
550 -</head>  
551 -<body>  
552 -<div class="navbar navbar-fixed-top">  
553 - <div class="navbar-inner">  
554 - <div class="container">  
555 - <a id="srs_index" class="brand" href="#">SRS</a>  
556 - <div class="nav-collapse collapse">  
557 - <ul class="nav">  
558 - <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li>  
559 - <li><a id="nav_srs_publisher" href="srs_publisher.html">SRS编码器</a></li>  
560 - <li class="active"><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>  
561 - <li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>  
562 - <li><a id="nav_jwplayer6" href="jwplayer6.html">JWPlayer6播放器</a></li>  
563 - <li><a id="nav_osmf" href="osmf.html">AdobeOSMF播放器</a></li>  
564 - <li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>  
565 - </ul>  
566 - </div>  
567 - </div>  
568 - </div>  
569 -</div>  
570 -<div class="container">  
571 - <!-- for the log -->  
572 - <div class="alert alert-info fade in" id="txt_log">  
573 - <button type="button" class="close" data-dismiss="alert">×</button>  
574 - <strong><span id="txt_log_title">Usage:</span></strong>  
575 - <span id="txt_log_msg">输入名字,设点“加入会议”按钮</span>  
576 - </div>  
577 -  
578 - <div class="control-group">  
579 - <div class="form-inline">  
580 - <button class="btn input-small" id="btn_video_settings">摄像头</button>  
581 - <button class="btn input-small" id="btn_audio_settings">麦克风</button>  
582 - <input type="text" id="txt_name" class="input-large" placeholder="请输入您的名字..." value=""></input>  
583 - <button class="btn input-small" id="btn_join">加入会议</button>  
584 - <input type="text" id="txt_url" class="input-mini hide" value=""></input>  
585 - </div>  
586 - </div>  
587 - <table id="lst_chats" class="table">  
588 - <tr>  
589 - <td id="td_0">  
590 - <div class="accordion-group">  
591 - <div class="accordion-heading">  
592 - <span class="accordion-toggle">  
593 - <strong>[我的] 本地摄像头</strong>  
594 - </span>  
595 - </div>  
596 - <div class="accordion-body collapse in">  
597 - <div class="accordion-inner">  
598 - <div id="local_publisher"></div>  
599 - </div>  
600 - </div>  
601 - </div>  
602 - </td>  
603 - <td id="td_1">  
604 - <div class="accordion-group">  
605 - <div class="accordion-heading">  
606 - <span class="accordion-toggle">  
607 - <strong>[我的] 远程服务器流</strong>  
608 - <a id="realtime_player_url" href="#" data-toggle="tooltip" data-placement="top" title="">  
609 - 播放地址<img src="img/tooltip.png"/>  
610 - </a>  
611 - </span>  
612 - </div>  
613 - <div class="accordion-body collapse in">  
614 - <div class="accordion-inner">  
615 - <div id="realtime_player"></div>  
616 - </div>  
617 - </div>  
618 - </div>  
619 - </td>  
620 - <td id="td_2"></td>  
621 - </tr>  
622 - </table>  
623 - <div class="container hide" id="template">  
624 - <div class="accordion-group" id="collapse_main">  
625 - <div class="accordion-heading" title="点击展开或收起,收起后停止播放流,展开时从服务器请求流">  
626 - <span id="headerN" class="accordion-toggle" data-toggle="collapse" href="#collapseN">  
627 - <strong>[<a href="#"><span id="user_name">XX</span></a>]</strong>  
628 - <strong>加入时间</strong>[<span id="join_date"></span>]  
629 - <a id="user_player_url" href="#" data-toggle="tooltip" data-placement="top" title="">  
630 - 播放地址<img src="img/tooltip.png"/>  
631 - </a>  
632 - </span>  
633 - </div>  
634 - <div id="collapseM" class="accordion-body collapse in">  
635 - <div class="accordion-inner">  
636 - <div id="chat_player">  
637 - <div id="chat_player_raw">  
638 - </div>  
639 - </div>  
640 - </div>  
641 - </div>  
642 - </div>  
643 - </div>  
644 - <table class="table">  
645 - </table>  
646 - <div id="video_modal" class="modal hide fade">  
647 - <div class="modal-header">  
648 - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>  
649 - <h3>视频编码</h3>  
650 - </div>  
651 - <div class="modal-body">  
652 - <div class="form-horizontal">  
653 - <div class="control-group">  
654 - <label class="control-label" for="sl_cameras">  
655 - 摄像头  
656 - <a id="sl_cameras_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
657 - <img src="img/tooltip.png"/>  
658 - </a>  
659 - </label>  
660 - <div class="controls">  
661 - <select class="span4" id="sl_cameras"></select>  
662 - </div>  
663 - </div>  
664 - <div class="control-group">  
665 - <label class="control-label" for="sl_vcodec">  
666 - Codec  
667 - <a id="sl_cameras_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
668 - <img src="img/tooltip.png"/>  
669 - </a>  
670 - </label>  
671 - <div class="controls">  
672 - <select class="span2" id="sl_vcodec"></select>  
673 - </div>  
674 - </div>  
675 - <div class="control-group">  
676 - <label class="control-label" for="sl_profile">  
677 - Profile  
678 - <a id="sl_profile_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
679 - <img src="img/tooltip.png"/>  
680 - </a>  
681 - </label>  
682 - <div class="controls">  
683 - <select class="span2" id="sl_profile"></select>  
684 - </div>  
685 - </div>  
686 - <div class="control-group">  
687 - <label class="control-label" for="sl_level">  
688 - Level  
689 - <a id="sl_level_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
690 - <img src="img/tooltip.png"/>  
691 - </a>  
692 - </label>  
693 - <div class="controls">  
694 - <select class="span2" id="sl_level"></select>  
695 - </div>  
696 - </div>  
697 - <div class="control-group">  
698 - <label class="control-label" for="sl_gop">  
699 - GOP  
700 - <a id="sl_gop_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
701 - <img src="img/tooltip.png"/>  
702 - </a>  
703 - </label>  
704 - <div class="controls">  
705 - <select class="span2" id="sl_gop"></select>  
706 - </div>  
707 - </div>  
708 - <div class="control-group">  
709 - <label class="control-label" for="sl_size">  
710 - 尺寸  
711 - <a id="sl_size_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
712 - <img src="img/tooltip.png"/>  
713 - </a>  
714 - </label>  
715 - <div class="controls">  
716 - <select class="span2" id="sl_size"></select>  
717 - </div>  
718 - </div>  
719 - <div class="control-group">  
720 - <label class="control-label" for="sl_fps">  
721 - 帧率  
722 - <a id="sl_fps_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
723 - <img src="img/tooltip.png"/>  
724 - </a>  
725 - </label>  
726 - <div class="controls">  
727 - <select class="span2" id="sl_fps"></select>  
728 - </div>  
729 - </div>  
730 - <div class="control-group">  
731 - <label class="control-label" for="sl_bitrate">  
732 - 码率  
733 - <a id="sl_bitrate_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
734 - <img src="img/tooltip.png"/>  
735 - </a>  
736 - </label>  
737 - <div class="controls">  
738 - <select class="span2" id="sl_bitrate"></select>  
739 - </div>  
740 - </div>  
741 - </div>  
742 - </div>  
743 - <div class="modal-footer">  
744 - <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">设置</button>  
745 - </div>  
746 - </div>  
747 - <div id="audio_modal" class="modal hide fade">  
748 - <div class="modal-header">  
749 - <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>  
750 - <h3>音频编码</h3>  
751 - </div>  
752 - <div class="modal-body">  
753 - <div class="form-horizontal">  
754 - <div class="control-group">  
755 - <label class="control-label" for="sl_microphones">  
756 - 麦克风  
757 - <a id="worker_id_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
758 - <img src="img/tooltip.png"/>  
759 - </a>  
760 - </label>  
761 - <div class="controls">  
762 - <select class="span4" id="sl_microphones"></select>  
763 - </div>  
764 - </div>  
765 - <div class="control-group">  
766 - <label class="control-label" for="sl_acodec">  
767 - 编码  
768 - <a id="sl_acodec_tips" href="#" data-toggle="tooltip" data-placement="right" title="">  
769 - <img src="img/tooltip.png"/>  
770 - </a>  
771 - </label>  
772 - <div class="controls">  
773 - <select class="span2" id="sl_acodec"></select>  
774 - </div>  
775 - </div>  
776 - </div>  
777 - </div>  
778 - <div class="modal-footer">  
779 - <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true">设置</button>  
780 - </div>  
781 - </div>  
782 - <hr/>  
783 - <footer>  
784 - <p><a href="https://github.com/simple-rtmp-server/srs">SRS Team &copy; 2013</a></p>  
785 - </footer>  
786 -</div>  
787 -</body> 788 +</script>
  789 +</html>
788 790
@@ -4,15 +4,6 @@ @@ -4,15 +4,6 @@
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
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>  
9 - <script type="text/javascript" src="js/swfobject.js"></script>  
10 - <script type="text/javascript" src="js/json2.js"></script>  
11 - <script type="text/javascript" src="js/srs.page.js"></script>  
12 - <script type="text/javascript" src="js/srs.log.js"></script>  
13 - <script type="text/javascript" src="js/srs.player.js"></script>  
14 - <script type="text/javascript" src="js/srs.publisher.js"></script>  
15 - <script type="text/javascript" src="js/srs.utility.js"></script>  
16 <style> 7 <style>
17 body{ 8 body{
18 padding-top: 55px; 9 padding-top: 55px;
@@ -29,250 +20,6 @@ @@ -29,250 +20,6 @@
29 margin-bottom: 10px; 20 margin-bottom: 10px;
30 } 21 }
31 </style> 22 </style>
32 - <script type="text/javascript">  
33 - var srs_player = null;  
34 - var url = null;  
35 -  
36 - var __active_dar = null;  
37 - function select_dar(dar_id, num, den) {  
38 - srs_player.set_dar(num, den);  
39 -  
40 - if (__active_dar) {  
41 - __active_dar.removeClass("active");  
42 - }  
43 -  
44 - __active_dar = $(dar_id).parent();  
45 - __active_dar.addClass("active");  
46 - }  
47 -  
48 - var __active_size = null;  
49 - function select_fs_size(size_id, refer, percent) {  
50 - srs_player.set_fs(refer, percent);  
51 -  
52 - if (__active_size) {  
53 - __active_size.removeClass("active");  
54 - }  
55 -  
56 - __active_size = $(size_id).parent();  
57 - __active_size.addClass("active");  
58 - }  
59 -  
60 - var __active_bt = null;  
61 - function select_buffer_time(bt_id, buffer_time) {  
62 - srs_player.set_bt(buffer_time);  
63 -  
64 - if (__active_bt) {  
65 - __active_bt.removeClass("active");  
66 - }  
67 -  
68 - __active_bt = $(bt_id).parent();  
69 - __active_bt.addClass("active");  
70 - }  
71 -  
72 - $(function(){  
73 - // get the vhost and port to set the default url.  
74 - // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo  
75 - // url set to: rtmp://demo:1935/live/livestream  
76 - srs_init("#txt_url", null, "#main_modal");  
77 -  
78 - $("#fs_tips").tooltip({  
79 - title: "点击视频进入或退出全屏"  
80 - });  
81 -  
82 - $("#main_modal").on("show", function(){  
83 - if (srs_player) {  
84 - return;  
85 - }  
86 -  
87 - $("#div_container").remove();  
88 -  
89 - var div_container = $("<div/>");  
90 - $(div_container).attr("id", "div_container");  
91 - $("#player").append(div_container);  
92 -  
93 - var player = $("<div/>");  
94 - $(player).attr("id", "player_id");  
95 - $(div_container).append(player);  
96 -  
97 - srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height());  
98 - srs_player.on_player_ready = function() {  
99 - select_buffer_time("#btn_bt_0_1", 0.1);  
100 - this.play(url);  
101 - };  
102 - srs_player.on_player_metadata = function(metadata) {  
103 - $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");  
104 - select_dar("#btn_dar_original", 0, 0);  
105 - select_fs_size("#btn_fs_size_screen_100", "screen", 100);  
106 - };  
107 - srs_player.on_player_timer = function(time, buffer_length) {  
108 - var buffer = buffer_length / this.buffer_time * 100;  
109 - $("#pb_buffer").width(Number(buffer).toFixed(1) + "%");  
110 -  
111 - $("#pb_buffer_bg").attr("title",  
112 - "缓冲区长度:" + Number(buffer_length).toFixed(1) + "秒("  
113 - + Number(buffer).toFixed(1) + "%)");  
114 -  
115 - var time_str = "";  
116 - // day  
117 - time_str = padding(parseInt(time / 24 / 3600), 2, '0') + " ";  
118 - // hour  
119 - time = time % (24 * 3600);  
120 - time_str += padding(parseInt(time / 3600), 2, '0') + ":";  
121 - // minute  
122 - time = time % (3600);  
123 - time_str += padding(parseInt(time / 60), 2, '0') + ":";  
124 - // seconds  
125 - time = time % (60);  
126 - time_str += padding(parseInt(time), 2, '0');  
127 - // show  
128 - $("#txt_time").val(time_str);  
129 - };  
130 - srs_player.start();  
131 - });  
132 -  
133 - $("#main_modal").on("hide", function(){  
134 - if ($("#main_modal").is(":visible")) {  
135 - return;  
136 - }  
137 -  
138 - if (srs_player) {  
139 - srs_player.stop();  
140 - srs_player = null;  
141 - }  
142 - });  
143 -  
144 - $("#btn_play").click(function(){  
145 - url = $("#txt_url").val();  
146 - $("#main_modal").modal({show:true, keyboard:false});  
147 - });  
148 -  
149 - $("#btn_pause").click(function(){  
150 - if ($("#btn_pause").text() == "暂停") {  
151 - $("#btn_pause").text("继续");  
152 - srs_player.pause();  
153 - } else {  
154 - $("#btn_pause").text("暂停");  
155 - srs_player.resume();  
156 - }  
157 - });  
158 -  
159 - $("#srs_publish").click(function(){  
160 - url = $("#srs_publish").text();  
161 - $("#main_modal").modal({show:true, keyboard:false});  
162 - });  
163 - $("#srs_publish_ld").click(function(){  
164 - url = $("#srs_publish_ld").text();  
165 - $("#main_modal").modal({show:true, keyboard:false});  
166 - });  
167 - $("#srs_publish_sd").click(function(){  
168 - url = $("#srs_publish_sd").text();  
169 - $("#main_modal").modal({show:true, keyboard:false});  
170 - });  
171 - $("#srs_publish_fw").click(function(){  
172 - url = $("#srs_publish_fw").text();  
173 - $("#main_modal").modal({show:true, keyboard:false});  
174 - });  
175 - $("#srs_publish_fw_ld").click(function(){  
176 - url = $("#srs_publish_fw_ld").text();  
177 - $("#main_modal").modal({show:true, keyboard:false});  
178 - });  
179 - $("#srs_publish_fw_sd").click(function(){  
180 - url = $("#srs_publish_fw_sd").text();  
181 - $("#main_modal").modal({show:true, keyboard:false});  
182 - });  
183 -  
184 - var query = parse_query_string();  
185 - var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=live&hls_autostart=true";  
186 - $("#srs_publish_hls").attr("href", jwplayer_url + "&stream=livestream");  
187 - $("#srs_publish_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld");  
188 - $("#srs_publish_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd");  
189 - var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=forward/live&hls_autostart=true";  
190 - $("#srs_publish_fw_hls").attr("href", jwplayer_url + "&stream=livestream");  
191 - $("#srs_publish_fw_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld");  
192 - $("#srs_publish_fw_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd");  
193 -  
194 - if (true) {  
195 - $("#btn_dar_original").click(function(){  
196 - select_dar("#btn_dar_original", 0, 0);  
197 - });  
198 - $("#btn_dar_21_9").click(function(){  
199 - select_dar("#btn_dar_21_9", 21, 9);  
200 - });  
201 - $("#btn_dar_16_9").click(function(){  
202 - select_dar("#btn_dar_16_9", 16, 9);  
203 - });  
204 - $("#btn_dar_4_3").click(function(){  
205 - select_dar("#btn_dar_4_3", 4, 3);  
206 - });  
207 - $("#btn_dar_fill").click(function(){  
208 - select_dar("#btn_dar_fill", -1, -1);  
209 - });  
210 - }  
211 -  
212 - if (true) {  
213 - $("#btn_fs_size_video_100").click(function(){  
214 - select_fs_size("#btn_fs_size_video_100", "video", 100);  
215 - });  
216 - $("#btn_fs_size_video_75").click(function(){  
217 - select_fs_size("#btn_fs_size_video_75", "video", 75);  
218 - });  
219 - $("#btn_fs_size_video_50").click(function(){  
220 - select_fs_size("#btn_fs_size_video_50", "video", 50);  
221 - });  
222 - $("#btn_fs_size_screen_100").click(function(){  
223 - select_fs_size("#btn_fs_size_screen_100", "screen", 100);  
224 - });  
225 - $("#btn_fs_size_screen_75").click(function(){  
226 - select_fs_size("#btn_fs_size_screen_75", "screen", 75);  
227 - });  
228 - $("#btn_fs_size_screen_50").click(function(){  
229 - select_fs_size("#btn_fs_size_screen_50", "screen", 50);  
230 - });  
231 - }  
232 -  
233 - if (true) {  
234 - $("#btn_bt_0_1").click(function(){  
235 - select_buffer_time("#btn_bt_0_1", 0.1);  
236 - });  
237 - $("#btn_bt_0_2").click(function(){  
238 - select_buffer_time("#btn_bt_0_2", 0.2);  
239 - });  
240 - $("#btn_bt_0_3").click(function(){  
241 - select_buffer_time("#btn_bt_0_3", 0.3);  
242 - });  
243 - $("#btn_bt_0_5").click(function(){  
244 - select_buffer_time("#btn_bt_0_5", 0.5);  
245 - });  
246 - $("#btn_bt_0_8").click(function(){  
247 - select_buffer_time("#btn_bt_0_8", 0.8);  
248 - });  
249 - $("#btn_bt_1").click(function(){  
250 - select_buffer_time("#btn_bt_1", 1);  
251 - });  
252 - $("#btn_bt_2").click(function(){  
253 - select_buffer_time("#btn_bt_2", 2);  
254 - });  
255 - $("#btn_bt_3").click(function(){  
256 - select_buffer_time("#btn_bt_3", 3);  
257 - });  
258 - $("#btn_bt_5").click(function(){  
259 - select_buffer_time("#btn_bt_5", 5);  
260 - });  
261 - $("#btn_bt_10").click(function(){  
262 - select_buffer_time("#btn_bt_10", 10);  
263 - });  
264 - $("#btn_bt_30").click(function(){  
265 - select_buffer_time("#btn_bt_30", 30);  
266 - });  
267 - }  
268 -  
269 - var query = parse_query_string();  
270 - if (query.autostart == "true") {  
271 - url = $("#txt_url").val();  
272 - $("#main_modal").modal({show:true, keyboard:false});  
273 - }  
274 - });  
275 - </script>  
276 </head> 23 </head>
277 <body> 24 <body>
278 <div class="navbar navbar-fixed-top"> 25 <div class="navbar navbar-fixed-top">
@@ -539,3 +286,262 @@ @@ -539,3 +286,262 @@
539 </footer> 286 </footer>
540 </div> 287 </div>
541 </body> 288 </body>
  289 +<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  290 +<script type="text/javascript" src="js/bootstrap.min.js"></script>
  291 +<script type="text/javascript" src="js/swfobject.js"></script>
  292 +<script type="text/javascript" src="js/json2.js"></script>
  293 +<script type="text/javascript" src="js/srs.page.js"></script>
  294 +<script type="text/javascript" src="js/srs.log.js"></script>
  295 +<script type="text/javascript" src="js/srs.player.js"></script>
  296 +<script type="text/javascript" src="js/srs.publisher.js"></script>
  297 +<script type="text/javascript" src="js/srs.utility.js"></script>
  298 +<script type="text/javascript" src="js/winlin.utility.js"></script>
  299 +<script type="text/javascript">
  300 + var srs_player = null;
  301 + var url = null;
  302 +
  303 + var __active_dar = null;
  304 + function select_dar(dar_id, num, den) {
  305 + srs_player.set_dar(num, den);
  306 +
  307 + if (__active_dar) {
  308 + __active_dar.removeClass("active");
  309 + }
  310 +
  311 + __active_dar = $(dar_id).parent();
  312 + __active_dar.addClass("active");
  313 + }
  314 +
  315 + var __active_size = null;
  316 + function select_fs_size(size_id, refer, percent) {
  317 + srs_player.set_fs(refer, percent);
  318 +
  319 + if (__active_size) {
  320 + __active_size.removeClass("active");
  321 + }
  322 +
  323 + __active_size = $(size_id).parent();
  324 + __active_size.addClass("active");
  325 + }
  326 +
  327 + var __active_bt = null;
  328 + function select_buffer_time(bt_id, buffer_time) {
  329 + srs_player.set_bt(buffer_time);
  330 +
  331 + if (__active_bt) {
  332 + __active_bt.removeClass("active");
  333 + }
  334 +
  335 + __active_bt = $(bt_id).parent();
  336 + __active_bt.addClass("active");
  337 + }
  338 +
  339 + $(function(){
  340 + // get the vhost and port to set the default url.
  341 + // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
  342 + // url set to: rtmp://demo:1935/live/livestream
  343 + srs_init_rtmp("#txt_url", "#main_modal");
  344 +
  345 + $("#fs_tips").tooltip({
  346 + title: "点击视频进入或退出全屏"
  347 + });
  348 +
  349 + $("#main_modal").on("show", function(){
  350 + if (srs_player) {
  351 + return;
  352 + }
  353 +
  354 + $("#div_container").remove();
  355 +
  356 + var div_container = $("<div/>");
  357 + $(div_container).attr("id", "div_container");
  358 + $("#player").append(div_container);
  359 +
  360 + var player = $("<div/>");
  361 + $(player).attr("id", "player_id");
  362 + $(div_container).append(player);
  363 +
  364 + srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height());
  365 + srs_player.on_player_ready = function() {
  366 + select_buffer_time("#btn_bt_0_1", 0.1);
  367 + this.play(url);
  368 + };
  369 + srs_player.on_player_metadata = function(metadata) {
  370 + $("#btn_dar_original").text("视频原始比例" + "(" + metadata.width + ":" + metadata.height + ")");
  371 + select_dar("#btn_dar_original", 0, 0);
  372 + select_fs_size("#btn_fs_size_screen_100", "screen", 100);
  373 + };
  374 + srs_player.on_player_timer = function(time, buffer_length) {
  375 + var buffer = buffer_length / this.buffer_time * 100;
  376 + $("#pb_buffer").width(Number(buffer).toFixed(1) + "%");
  377 +
  378 + $("#pb_buffer_bg").attr("title",
  379 + "缓冲区长度:" + Number(buffer_length).toFixed(1) + "秒("
  380 + + Number(buffer).toFixed(1) + "%)");
  381 +
  382 + var time_str = "";
  383 + // day
  384 + time_str = padding(parseInt(time / 24 / 3600), 2, '0') + " ";
  385 + // hour
  386 + time = time % (24 * 3600);
  387 + time_str += padding(parseInt(time / 3600), 2, '0') + ":";
  388 + // minute
  389 + time = time % (3600);
  390 + time_str += padding(parseInt(time / 60), 2, '0') + ":";
  391 + // seconds
  392 + time = time % (60);
  393 + time_str += padding(parseInt(time), 2, '0');
  394 + // show
  395 + $("#txt_time").val(time_str);
  396 + };
  397 + srs_player.start();
  398 + });
  399 +
  400 + $("#main_modal").on("hide", function(){
  401 + if ($("#main_modal").is(":visible")) {
  402 + return;
  403 + }
  404 +
  405 + if (srs_player) {
  406 + srs_player.stop();
  407 + srs_player = null;
  408 + }
  409 + });
  410 +
  411 + $("#btn_play").click(function(){
  412 + url = $("#txt_url").val();
  413 + $("#main_modal").modal({show:true, keyboard:false});
  414 + });
  415 +
  416 + $("#btn_pause").click(function(){
  417 + if ($("#btn_pause").text() == "暂停") {
  418 + $("#btn_pause").text("继续");
  419 + srs_player.pause();
  420 + } else {
  421 + $("#btn_pause").text("暂停");
  422 + srs_player.resume();
  423 + }
  424 + });
  425 +
  426 + if (true) {
  427 + $("#srs_publish").click(function () {
  428 + url = $("#srs_publish").text();
  429 + $("#main_modal").modal({show: true, keyboard: false});
  430 + });
  431 + $("#srs_publish_ld").click(function () {
  432 + url = $("#srs_publish_ld").text();
  433 + $("#main_modal").modal({show: true, keyboard: false});
  434 + });
  435 + $("#srs_publish_sd").click(function () {
  436 + url = $("#srs_publish_sd").text();
  437 + $("#main_modal").modal({show: true, keyboard: false});
  438 + });
  439 + $("#srs_publish_fw").click(function () {
  440 + url = $("#srs_publish_fw").text();
  441 + $("#main_modal").modal({show: true, keyboard: false});
  442 + });
  443 + $("#srs_publish_fw_ld").click(function () {
  444 + url = $("#srs_publish_fw_ld").text();
  445 + $("#main_modal").modal({show: true, keyboard: false});
  446 + });
  447 + $("#srs_publish_fw_sd").click(function () {
  448 + url = $("#srs_publish_fw_sd").text();
  449 + $("#main_modal").modal({show: true, keyboard: false});
  450 + });
  451 + }
  452 +
  453 + var query = parse_query_string();
  454 + var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=live&hls_autostart=true";
  455 + if (true) {
  456 + $("#srs_publish_hls").attr("href", jwplayer_url + "&stream=livestream");
  457 + $("#srs_publish_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld");
  458 + $("#srs_publish_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd");
  459 + var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=forward/live&hls_autostart=true";
  460 + $("#srs_publish_fw_hls").attr("href", jwplayer_url + "&stream=livestream");
  461 + $("#srs_publish_fw_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld");
  462 + $("#srs_publish_fw_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd");
  463 + }
  464 +
  465 + if (true) {
  466 + $("#btn_dar_original").click(function(){
  467 + select_dar("#btn_dar_original", 0, 0);
  468 + });
  469 + $("#btn_dar_21_9").click(function(){
  470 + select_dar("#btn_dar_21_9", 21, 9);
  471 + });
  472 + $("#btn_dar_16_9").click(function(){
  473 + select_dar("#btn_dar_16_9", 16, 9);
  474 + });
  475 + $("#btn_dar_4_3").click(function(){
  476 + select_dar("#btn_dar_4_3", 4, 3);
  477 + });
  478 + $("#btn_dar_fill").click(function(){
  479 + select_dar("#btn_dar_fill", -1, -1);
  480 + });
  481 + }
  482 +
  483 + if (true) {
  484 + $("#btn_fs_size_video_100").click(function(){
  485 + select_fs_size("#btn_fs_size_video_100", "video", 100);
  486 + });
  487 + $("#btn_fs_size_video_75").click(function(){
  488 + select_fs_size("#btn_fs_size_video_75", "video", 75);
  489 + });
  490 + $("#btn_fs_size_video_50").click(function(){
  491 + select_fs_size("#btn_fs_size_video_50", "video", 50);
  492 + });
  493 + $("#btn_fs_size_screen_100").click(function(){
  494 + select_fs_size("#btn_fs_size_screen_100", "screen", 100);
  495 + });
  496 + $("#btn_fs_size_screen_75").click(function(){
  497 + select_fs_size("#btn_fs_size_screen_75", "screen", 75);
  498 + });
  499 + $("#btn_fs_size_screen_50").click(function(){
  500 + select_fs_size("#btn_fs_size_screen_50", "screen", 50);
  501 + });
  502 + }
  503 +
  504 + if (true) {
  505 + $("#btn_bt_0_1").click(function(){
  506 + select_buffer_time("#btn_bt_0_1", 0.1);
  507 + });
  508 + $("#btn_bt_0_2").click(function(){
  509 + select_buffer_time("#btn_bt_0_2", 0.2);
  510 + });
  511 + $("#btn_bt_0_3").click(function(){
  512 + select_buffer_time("#btn_bt_0_3", 0.3);
  513 + });
  514 + $("#btn_bt_0_5").click(function(){
  515 + select_buffer_time("#btn_bt_0_5", 0.5);
  516 + });
  517 + $("#btn_bt_0_8").click(function(){
  518 + select_buffer_time("#btn_bt_0_8", 0.8);
  519 + });
  520 + $("#btn_bt_1").click(function(){
  521 + select_buffer_time("#btn_bt_1", 1);
  522 + });
  523 + $("#btn_bt_2").click(function(){
  524 + select_buffer_time("#btn_bt_2", 2);
  525 + });
  526 + $("#btn_bt_3").click(function(){
  527 + select_buffer_time("#btn_bt_3", 3);
  528 + });
  529 + $("#btn_bt_5").click(function(){
  530 + select_buffer_time("#btn_bt_5", 5);
  531 + });
  532 + $("#btn_bt_10").click(function(){
  533 + select_buffer_time("#btn_bt_10", 10);
  534 + });
  535 + $("#btn_bt_30").click(function(){
  536 + select_buffer_time("#btn_bt_30", 30);
  537 + });
  538 + }
  539 +
  540 + var query = parse_query_string();
  541 + if (query.autostart == "true") {
  542 + url = $("#txt_url").val();
  543 + $("#main_modal").modal({show:true, keyboard:false});
  544 + }
  545 + });
  546 +</script>
  547 +</html>
@@ -38,3 +38,4 @@ @@ -38,3 +38,4 @@
38 <buildCSSFiles/> 38 <buildCSSFiles/>
39 <flashCatalyst validateFlashCatalystCompatibility="false"/> 39 <flashCatalyst validateFlashCatalystCompatibility="false"/>
40 </actionScriptProperties> 40 </actionScriptProperties>
  41 +
@@ -4,213 +4,11 @@ @@ -4,213 +4,11 @@
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
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>  
9 - <script type="text/javascript" src="js/swfobject.js"></script>  
10 - <script type="text/javascript" src="js/json2.js"></script>  
11 - <script type="text/javascript" src="js/srs.page.js"></script>  
12 - <script type="text/javascript" src="js/srs.log.js"></script>  
13 - <script type="text/javascript" src="js/srs.player.js"></script>  
14 - <script type="text/javascript" src="js/srs.publisher.js"></script>  
15 - <script type="text/javascript" src="js/srs.utility.js"></script>  
16 <style> 7 <style>
17 body{ 8 body{
18 padding-top: 55px; 9 padding-top: 55px;
19 } 10 }
20 </style> 11 </style>
21 - <script type="text/javascript">  
22 - var srs_publisher = null;  
23 - var remote_player = null;  
24 - var realtime_player = null;  
25 -  
26 - var query = parse_query_string();  
27 - $(function(){  
28 - // get the vhost and port to set the default url.  
29 - // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo  
30 - // url set to: rtmp://demo:1935/live/livestream  
31 - srs_init("#txt_url", null, null);  
32 -  
33 - if (query.agent == "true") {  
34 - document.write(navigator.userAgent);  
35 - return;  
36 - }  
37 -  
38 - $("#btn_video_settings").click(function(){  
39 - $("#video_modal").modal({show:true});  
40 - });  
41 - $("#btn_audio_settings").click(function(){  
42 - $("#audio_modal").modal({show:true});  
43 - });  
44 -  
45 - $("#remote_tips").tooltip({  
46 - title: "为了支持HLS输出,FLASH编码器输出的流需要经过转码(VP6=>H264,MP3=>aac),所以会黑屏较长时间,请耐心等待"  
47 - });  
48 - $("#low_latecy_tips").tooltip({  
49 - title: "服务器不转码直接转发FLASH编码器的流,所以延迟比支持HLS的流要低很多"  
50 - });  
51 - $("#realtime_player_url").tooltip({  
52 - title: "右键复制RTMP地址"  
53 - });  
54 - $("#remote_player_url").tooltip({  
55 - title: "右键复制RTMP地址"  
56 - });  
57 -  
58 - $("#btn_publish").click(on_user_publish);  
59 -  
60 - // for publish, we use randome stream name.  
61 - $("#txt_url").val($("#txt_url").val() + "." + new Date().getTime());  
62 -  
63 - // start the publisher.  
64 - srs_publisher = new SrsPublisher("local_publisher", 430, 185);  
65 - srs_publisher.on_publisher_ready = function(cameras, microphones) {  
66 - srs_publisher_initialize_page(  
67 - cameras, microphones,  
68 - "#sl_cameras", "#sl_microphones",  
69 - "#sl_vcodec", "#sl_profile", "#sl_level", "#sl_gop", "#sl_size",  
70 - "#sl_fps", "#sl_bitrate",  
71 - "#sl_acodec"  
72 - );  
73 - };  
74 - srs_publisher.on_publisher_error = function(code, desc) {  
75 - if (!on_publish_stop()) {  
76 - return;  
77 - }  
78 - error(code, desc + "请重试。");  
79 - };  
80 - srs_publisher.on_publisher_warn = function(code, desc) {  
81 - warn(code, desc);  
82 - };  
83 - srs_publisher.start();  
84 -  
85 - update_play_url();  
86 -  
87 - // if no play specified, donot show the player, for debug the publisher.  
88 - if (query.no_play != "true") {  
89 - // start the normal player with HLS supported.  
90 - remote_player = new SrsPlayer("remote_player", 430, 185);  
91 - remote_player.on_player_ready = function() {  
92 - this.set_bt(0.8);  
93 - };  
94 - remote_player.on_player_metadata = function(metadata) {  
95 - this.set_dar(0, 0);  
96 - this.set_fs("screen", 100);  
97 - }  
98 - remote_player.start();  
99 -  
100 - // start the realtime player.  
101 - realtime_player = new SrsPlayer("realtime_player", 430, 185);  
102 - realtime_player.on_player_ready = function() {  
103 - this.set_bt(0.8);  
104 - };  
105 - realtime_player.on_player_metadata = function(metadata) {  
106 - this.set_dar(0, 0);  
107 - this.set_fs("screen", 100);  
108 - }  
109 - realtime_player.start();  
110 - }  
111 - });  
112 -  
113 - function on_publish_stop() {  
114 - if (!srs_can_republish()) {  
115 - $("#btn_join").attr("disabled", true);  
116 - error(0, "您使用的浏览器很弱,请关闭页面后重新打开页面(刷新也不管用)。<br/>推荐使用Chrome/Firefox/Safari/Opera浏览器,支持重试");  
117 -  
118 - srs_log_disabled = true;  
119 - return false;  
120 - }  
121 -  
122 - return true;  
123 - }  
124 -  
125 - /**  
126 - * we generate the transcoded stream url for flash publish donot support HLS  
127 - * which requires aac, so the publish vhost maybe players for example, we  
128 - * use players_pub vhost(transcoded stream to which) for all clients,  
129 - * both players and players_pub are write HLS to the sample dir,  
130 - * it's ok for the players vhost disabled the HLS, only the  
131 - * players_pub enalbed HLS.  
132 - */  
133 - function update_play_url() {  
134 - var url = $("#txt_url").val();  
135 - var ret = srs_parse_rtmp_url(url);  
136 -  
137 - var remote_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app + "...vhost..." + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream;  
138 - $("#realtime_player_url").attr("href", url).attr("target", "_blank");  
139 - $("#remote_player_url").attr("href", remote_url).attr("target", "_blank");  
140 -  
141 - var srs_player_url = "http://" + query.host + query.dir + "/srs_player.html?";  
142 - srs_player_url += "vhost=" + srs_get_player_publish_vhost(ret.vhost) + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream;  
143 - srs_player_url += "&autostart=true";  
144 -  
145 - var srs_player_rt_url = "http://" + query.host + query.dir + "/srs_player.html?";  
146 - srs_player_rt_url += "vhost=" + ret.vhost + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream;  
147 - srs_player_rt_url += "&autostart=true";  
148 -  
149 - var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?";  
150 - jwplayer_url += "vhost=" + srs_get_player_publish_vhost(ret.vhost) + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream;  
151 - jwplayer_url += "&hls_autostart=true";  
152 -  
153 - var hls_url = "http://" + ret.server + ":" + query.http_port + "/" + ret.app + "/" + ret.stream + ".m3u8";  
154 -  
155 - $("#txt_play_realtime").text("RTMP低延时(点击打开)").attr("href", srs_player_rt_url).attr("target", "_blank");  
156 - $("#txt_play_url").text("RTMP已转码(点击打开)").attr("href", srs_player_url).attr("target", "_blank");  
157 - $("#txt_play_hls").text("HLS-m3u8(点击打开或右键复制)").attr("href", hls_url).attr("target", "_blank");  
158 - $("#txt_play_jwplayer").text("HLS-JWPlayer(点击打开)").attr("href", jwplayer_url).attr("target", "_blank");  
159 - }  
160 - function on_user_publish() {  
161 - if ($("#btn_publish").text() == "停止发布") {  
162 - srs_publisher.stop();  
163 - $("#btn_publish").text("发布视频");  
164 - //$("#txt_play_realtime").text("RTMP低延时(请发布视频)").attr("href", "#").attr("target", "_self");  
165 - //$("#txt_play_realtime").attr("href", "#").attr("target", "_self");  
166 - //$("#txt_play_url").text("RTMP已转码(请发布视频)").attr("href", "#").attr("target", "_self");  
167 - //$("#remote_player_url").attr("href", "#").attr("target", "_self");  
168 - //$("#txt_play_hls").text("HLS-m3u8(请发布视频)").attr("href", "#").attr("target", "_self");  
169 - //$("#txt_play_jwplayer").text("HLS-JWPlayer(请发布视频)").attr("href", "#").attr("target", "_self");  
170 -  
171 - if (!on_publish_stop()) {  
172 - return;  
173 - }  
174 - return;  
175 - }  
176 -  
177 - $("#btn_publish").text("停止发布");  
178 -  
179 - update_play_url();  
180 -  
181 - var url = $("#txt_url").val();  
182 - var vcodec = {};  
183 - var acodec = {};  
184 - srs_publiser_get_codec(  
185 - vcodec, acodec,  
186 - "#sl_cameras", "#sl_microphones",  
187 - "#sl_vcodec", "#sl_profile", "#sl_level", "#sl_gop", "#sl_size",  
188 - "#sl_fps", "#sl_bitrate",  
189 - "#sl_acodec"  
190 - );  
191 -  
192 - info("开始推流到服务器");  
193 - srs_publisher.publish(url, vcodec, acodec);  
194 -  
195 - if (realtime_player) {  
196 - // directly play the url for the realtime player.  
197 - realtime_player.stop();  
198 - realtime_player.play(url);  
199 - }  
200 -  
201 - if (remote_player) {  
202 - // the normal player should play the transcoded stream in another vhost.  
203 - // for example, publish stream to vhost players,  
204 - // the realtime player play the vhost players, which may donot support HLS,  
205 - // the normal player play the vhost players_pub, which transcoded to h264/aac with HLS.  
206 - var ret = srs_parse_rtmp_url(url);  
207 - var pub_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app;  
208 - pub_url += "?vhost=" + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream;  
209 - remote_player.stop();  
210 - remote_player.play(pub_url);  
211 - }  
212 - }  
213 - </script>  
214 </head> 12 </head>
215 <body> 13 <body>
216 <div class="navbar navbar-fixed-top"> 14 <div class="navbar navbar-fixed-top">
@@ -464,4 +262,208 @@ @@ -464,4 +262,208 @@
464 </footer> 262 </footer>
465 </div> 263 </div>
466 </body> 264 </body>
  265 +<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  266 +<script type="text/javascript" src="js/bootstrap.min.js"></script>
  267 +<script type="text/javascript" src="js/swfobject.js"></script>
  268 +<script type="text/javascript" src="js/json2.js"></script>
  269 +<script type="text/javascript" src="js/srs.page.js"></script>
  270 +<script type="text/javascript" src="js/srs.log.js"></script>
  271 +<script type="text/javascript" src="js/srs.player.js"></script>
  272 +<script type="text/javascript" src="js/srs.publisher.js"></script>
  273 +<script type="text/javascript" src="js/srs.utility.js"></script>
  274 +<script type="text/javascript" src="js/winlin.utility.js"></script>
  275 +<script type="text/javascript">
  276 + var srs_publisher = null;
  277 + var remote_player = null;
  278 + var realtime_player = null;
  279 +
  280 + var query = parse_query_string();
  281 + $(function(){
  282 + // get the vhost and port to set the default url.
  283 + // for example: http://192.168.1.213/players/jwplayer6.html?port=1935&vhost=demo
  284 + // url set to: rtmp://demo:1935/live/livestream
  285 + srs_init_rtmp("#txt_url", null);
  286 +
  287 + if (query.agent == "true") {
  288 + document.write(navigator.userAgent);
  289 + return;
  290 + }
  291 +
  292 + $("#btn_video_settings").click(function(){
  293 + $("#video_modal").modal({show:true});
  294 + });
  295 + $("#btn_audio_settings").click(function(){
  296 + $("#audio_modal").modal({show:true});
  297 + });
  298 +
  299 + $("#remote_tips").tooltip({
  300 + title: "为了支持HLS输出,FLASH编码器输出的流需要经过转码(VP6=>H264,MP3=>aac),所以会黑屏较长时间,请耐心等待"
  301 + });
  302 + $("#low_latecy_tips").tooltip({
  303 + title: "服务器不转码直接转发FLASH编码器的流,所以延迟比支持HLS的流要低很多"
  304 + });
  305 + $("#realtime_player_url").tooltip({
  306 + title: "右键复制RTMP地址"
  307 + });
  308 + $("#remote_player_url").tooltip({
  309 + title: "右键复制RTMP地址"
  310 + });
  311 +
  312 + $("#btn_publish").click(on_user_publish);
  313 +
  314 + // for publish, we use randome stream name.
  315 + $("#txt_url").val($("#txt_url").val() + "." + new Date().getTime());
  316 +
  317 + // start the publisher.
  318 + srs_publisher = new SrsPublisher("local_publisher", 430, 185);
  319 + srs_publisher.on_publisher_ready = function(cameras, microphones) {
  320 + srs_publisher_initialize_page(
  321 + cameras, microphones,
  322 + "#sl_cameras", "#sl_microphones",
  323 + "#sl_vcodec", "#sl_profile", "#sl_level", "#sl_gop", "#sl_size",
  324 + "#sl_fps", "#sl_bitrate",
  325 + "#sl_acodec"
  326 + );
  327 + };
  328 + srs_publisher.on_publisher_error = function(code, desc) {
  329 + if (!on_publish_stop()) {
  330 + return;
  331 + }
  332 + error(code, desc + "请重试。");
  333 + };
  334 + srs_publisher.on_publisher_warn = function(code, desc) {
  335 + warn(code, desc);
  336 + };
  337 + srs_publisher.start();
  338 +
  339 + update_play_url();
  340 +
  341 + // if no play specified, donot show the player, for debug the publisher.
  342 + if (query.no_play != "true") {
  343 + // start the normal player with HLS supported.
  344 + remote_player = new SrsPlayer("remote_player", 430, 185);
  345 + remote_player.on_player_ready = function() {
  346 + this.set_bt(0.8);
  347 + };
  348 + remote_player.on_player_metadata = function(metadata) {
  349 + this.set_dar(0, 0);
  350 + this.set_fs("screen", 100);
  351 + }
  352 + remote_player.start();
  353 +
  354 + // start the realtime player.
  355 + realtime_player = new SrsPlayer("realtime_player", 430, 185);
  356 + realtime_player.on_player_ready = function() {
  357 + this.set_bt(0.8);
  358 + };
  359 + realtime_player.on_player_metadata = function(metadata) {
  360 + this.set_dar(0, 0);
  361 + this.set_fs("screen", 100);
  362 + }
  363 + realtime_player.start();
  364 + }
  365 + });
  366 +
  367 + function on_publish_stop() {
  368 + if (!srs_can_republish()) {
  369 + $("#btn_join").attr("disabled", true);
  370 + error(0, "您使用的浏览器很弱,请关闭页面后重新打开页面(刷新也不管用)。<br/>推荐使用Chrome/Firefox/Safari/Opera浏览器,支持重试");
  371 +
  372 + srs_log_disabled = true;
  373 + return false;
  374 + }
  375 +
  376 + return true;
  377 + }
  378 +
  379 + /**
  380 + * we generate the transcoded stream url for flash publish donot support HLS
  381 + * which requires aac, so the publish vhost maybe players for example, we
  382 + * use players_pub vhost(transcoded stream to which) for all clients,
  383 + * both players and players_pub are write HLS to the sample dir,
  384 + * it's ok for the players vhost disabled the HLS, only the
  385 + * players_pub enalbed HLS.
  386 + */
  387 + function update_play_url() {
  388 + var url = $("#txt_url").val();
  389 + var ret = srs_parse_rtmp_url(url);
  390 +
  391 + var remote_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app + "...vhost..." + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream;
  392 + $("#realtime_player_url").attr("href", url).attr("target", "_blank");
  393 + $("#remote_player_url").attr("href", remote_url).attr("target", "_blank");
  394 +
  395 + var srs_player_url = "http://" + query.host + query.dir + "/srs_player.html?";
  396 + srs_player_url += "vhost=" + srs_get_player_publish_vhost(ret.vhost) + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream;
  397 + srs_player_url += "&autostart=true";
  398 +
  399 + var srs_player_rt_url = "http://" + query.host + query.dir + "/srs_player.html?";
  400 + srs_player_rt_url += "vhost=" + ret.vhost + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream;
  401 + srs_player_rt_url += "&autostart=true";
  402 +
  403 + var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?";
  404 + jwplayer_url += "vhost=" + srs_get_player_publish_vhost(ret.vhost) + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream;
  405 + jwplayer_url += "&hls_autostart=true";
  406 +
  407 + var hls_url = "http://" + ret.server + ":" + query.http_port + "/" + ret.app + "/" + ret.stream + ".m3u8";
  408 +
  409 + $("#txt_play_realtime").text("RTMP低延时(点击打开)").attr("href", srs_player_rt_url).attr("target", "_blank");
  410 + $("#txt_play_url").text("RTMP已转码(点击打开)").attr("href", srs_player_url).attr("target", "_blank");
  411 + $("#txt_play_hls").text("HLS-m3u8(点击打开或右键复制)").attr("href", hls_url).attr("target", "_blank");
  412 + $("#txt_play_jwplayer").text("HLS-JWPlayer(点击打开)").attr("href", jwplayer_url).attr("target", "_blank");
  413 + }
  414 + function on_user_publish() {
  415 + if ($("#btn_publish").text() == "停止发布") {
  416 + srs_publisher.stop();
  417 + $("#btn_publish").text("发布视频");
  418 + //$("#txt_play_realtime").text("RTMP低延时(请发布视频)").attr("href", "#").attr("target", "_self");
  419 + //$("#txt_play_realtime").attr("href", "#").attr("target", "_self");
  420 + //$("#txt_play_url").text("RTMP已转码(请发布视频)").attr("href", "#").attr("target", "_self");
  421 + //$("#remote_player_url").attr("href", "#").attr("target", "_self");
  422 + //$("#txt_play_hls").text("HLS-m3u8(请发布视频)").attr("href", "#").attr("target", "_self");
  423 + //$("#txt_play_jwplayer").text("HLS-JWPlayer(请发布视频)").attr("href", "#").attr("target", "_self");
  424 +
  425 + if (!on_publish_stop()) {
  426 + return;
  427 + }
  428 + return;
  429 + }
  430 +
  431 + $("#btn_publish").text("停止发布");
  432 +
  433 + update_play_url();
  434 +
  435 + var url = $("#txt_url").val();
  436 + var vcodec = {};
  437 + var acodec = {};
  438 + srs_publiser_get_codec(
  439 + vcodec, acodec,
  440 + "#sl_cameras", "#sl_microphones",
  441 + "#sl_vcodec", "#sl_profile", "#sl_level", "#sl_gop", "#sl_size",
  442 + "#sl_fps", "#sl_bitrate",
  443 + "#sl_acodec"
  444 + );
  445 +
  446 + info("开始推流到服务器");
  447 + srs_publisher.publish(url, vcodec, acodec);
  448 +
  449 + if (realtime_player) {
  450 + // directly play the url for the realtime player.
  451 + realtime_player.stop();
  452 + realtime_player.play(url);
  453 + }
  454 +
  455 + if (remote_player) {
  456 + // the normal player should play the transcoded stream in another vhost.
  457 + // for example, publish stream to vhost players,
  458 + // the realtime player play the vhost players, which may donot support HLS,
  459 + // the normal player play the vhost players_pub, which transcoded to h264/aac with HLS.
  460 + var ret = srs_parse_rtmp_url(url);
  461 + var pub_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app;
  462 + pub_url += "?vhost=" + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream;
  463 + remote_player.stop();
  464 + remote_player.play(pub_url);
  465 + }
  466 + }
  467 +</script>
  468 +</html>
467 469
@@ -4,21 +4,11 @@ @@ -4,21 +4,11 @@
4 <title>SRS</title> 4 <title>SRS</title>
5 <meta charset="utf-8"> 5 <meta charset="utf-8">
6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/> 6 <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
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>  
9 - <script type="text/javascript" src="js/swfobject.js"></script>  
10 - <script type="text/javascript" src="js/srs.page.js"></script>  
11 <style> 7 <style>
12 body{ 8 body{
13 padding-top: 55px; 9 padding-top: 55px;
14 } 10 }
15 </style> 11 </style>
16 - <script type="text/javascript">  
17 - $(function(){  
18 - update_nav();  
19 - $("#main_frame").attr("src", "http://www.videolan.org/vlc/");  
20 - });  
21 - </script>  
22 </head> 12 </head>
23 <body> 13 <body>
24 <div class="navbar navbar-fixed-top"> 14 <div class="navbar navbar-fixed-top">
@@ -49,4 +39,15 @@ @@ -49,4 +39,15 @@
49 </footer> 39 </footer>
50 </div> 40 </div>
51 </body> 41 </body>
  42 +<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
  43 +<script type="text/javascript" src="js/bootstrap.min.js"></script>
  44 +<script type="text/javascript" src="js/swfobject.js"></script>
  45 +<script type="text/javascript" src="js/srs.page.js"></script>
  46 +<script type="text/javascript">
  47 + $(function(){
  48 + update_nav();
  49 + $("#main_frame").attr("src", "http://www.videolan.org/vlc/");
  50 + });
  51 +</script>
  52 +</html>
52 53