update the conf, add demo.srs.com, add players and players_pub, add __defaultVhost__ for rtmp
正在显示
13 个修改的文件
包含
396 行增加
和
36 行删除
@@ -49,7 +49,7 @@ For example, use ffmpeg to publish: | @@ -49,7 +49,7 @@ For example, use ffmpeg to publish: | ||
49 | for((;;)); do \ | 49 | for((;;)); do \ |
50 | ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.200kbps.768x320.flv \ | 50 | ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.200kbps.768x320.flv \ |
51 | -vcodec copy -acodec copy \ | 51 | -vcodec copy -acodec copy \ |
52 | - -f flv -y rtmp://127.0.0.1/live/livestream; \ | 52 | + -f flv -y rtmp://127.0.0.1/live?vhost=demo.srs.com/livestream; \ |
53 | sleep 1; \ | 53 | sleep 1; \ |
54 | done | 54 | done |
55 | </pre> | 55 | </pre> |
@@ -3,9 +3,11 @@ chunk_size 65000; | @@ -3,9 +3,11 @@ chunk_size 65000; | ||
3 | vhost __defaultVhost__ { | 3 | vhost __defaultVhost__ { |
4 | enabled on; | 4 | enabled on; |
5 | gop_cache on; | 5 | gop_cache on; |
6 | - hls on; | 6 | + hls { |
7 | + enabled on; | ||
7 | hls_path ./objs/nginx/html/forward; | 8 | hls_path ./objs/nginx/html/forward; |
8 | hls_fragment 5; | 9 | hls_fragment 5; |
9 | hls_window 30; | 10 | hls_window 30; |
11 | + } | ||
10 | } | 12 | } |
11 | 13 |
@@ -17,10 +17,17 @@ max_connections 2000; | @@ -17,10 +17,17 @@ max_connections 2000; | ||
17 | # vhost list, the __defaultVhost__ is the default vhost | 17 | # vhost list, the __defaultVhost__ is the default vhost |
18 | # for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream. | 18 | # for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream. |
19 | # for which cannot identify the required vhost. | 19 | # for which cannot identify the required vhost. |
20 | -# for default demo. | ||
21 | vhost __defaultVhost__ { | 20 | vhost __defaultVhost__ { |
22 | enabled on; | 21 | enabled on; |
23 | gop_cache on; | 22 | gop_cache on; |
23 | +} | ||
24 | +# vhost list, the __defaultVhost__ is the default vhost | ||
25 | +# for example, user use ip to access the stream: rtmp://192.168.1.2/live/livestream. | ||
26 | +# for which cannot identify the required vhost. | ||
27 | +# for default demo. | ||
28 | +vhost demo.srs.com { | ||
29 | + enabled on; | ||
30 | + gop_cache on; | ||
24 | queue_length 30; | 31 | queue_length 30; |
25 | forward 127.0.0.1:19350; | 32 | forward 127.0.0.1:19350; |
26 | hls { | 33 | hls { |
@@ -44,7 +51,7 @@ vhost __defaultVhost__ { | @@ -44,7 +51,7 @@ vhost __defaultVhost__ { | ||
44 | engine ld { | 51 | engine ld { |
45 | enabled on; | 52 | enabled on; |
46 | vfilter { | 53 | vfilter { |
47 | - vf 'drawtext=text=SimpleRtmpServer(SRS):x=10:y=10:fontcolor=#cccccc:fontfile=./doc/FreeSerifBold.ttf'; | 54 | + vf 'drawtext=text=SimpleRtmpServer(SRS):x=10:y=10:fontsize=30:fontcolor=#cccccc:fontfile=./doc/FreeSerifBold.ttf'; |
48 | } | 55 | } |
49 | vcodec libx264; | 56 | vcodec libx264; |
50 | vbitrate 300; | 57 | vbitrate 300; |
@@ -89,6 +96,48 @@ vhost __defaultVhost__ { | @@ -89,6 +96,48 @@ vhost __defaultVhost__ { | ||
89 | } | 96 | } |
90 | } | 97 | } |
91 | } | 98 | } |
99 | +# for the players site, to play or publish. | ||
100 | +# the flash player publisher need to transcode to support hls, | ||
101 | +# we add players_hls vhost to support it. | ||
102 | +vhost players { | ||
103 | + enabled on; | ||
104 | + gop_cache on; | ||
105 | + transcode { | ||
106 | + enabled on; | ||
107 | + ffmpeg ./objs/ffmpeg/bin/ffmpeg; | ||
108 | + engine hls { | ||
109 | + enabled on; | ||
110 | + vfilter { | ||
111 | + vf 'drawtext=text=SRS(SimpleRtmpServer):x=10:y=10:fontcolor=#cccccc:fontfile=./doc/FreeSerifBold.ttf'; | ||
112 | + } | ||
113 | + vcodec libx264; | ||
114 | + vbitrate 300; | ||
115 | + vfps 20; | ||
116 | + vwidth 768; | ||
117 | + vheight 320; | ||
118 | + vthreads 1; | ||
119 | + vprofile baseline; | ||
120 | + vpreset superfast; | ||
121 | + vparams { | ||
122 | + } | ||
123 | + acodec libaacplus; | ||
124 | + abitrate 30; | ||
125 | + asample_rate 44100; | ||
126 | + achannels 2; | ||
127 | + aparams { | ||
128 | + } | ||
129 | + output rtmp://127.0.0.1:[port]/[app]?vhost=players_pub/[stream]; | ||
130 | + } | ||
131 | + } | ||
132 | +} | ||
133 | +vhost players_pub { | ||
134 | + hls { | ||
135 | + enabled on; | ||
136 | + hls_path ./objs/nginx/html; | ||
137 | + hls_fragment 5; | ||
138 | + hls_window 30; | ||
139 | + } | ||
140 | +} | ||
92 | # for development | 141 | # for development |
93 | vhost dev { | 142 | vhost dev { |
94 | enabled on; | 143 | enabled on; |
@@ -17,7 +17,8 @@ | @@ -17,7 +17,8 @@ | ||
17 | $(function(){ | 17 | $(function(){ |
18 | update_nav(); | 18 | update_nav(); |
19 | 19 | ||
20 | - window.location.href = "srs_player.html"; | 20 | + // direct to the default vhost for players. |
21 | + window.location.href = "srs_player.html?vhost=" + srs_get_player_vhost(); | ||
21 | }); | 22 | }); |
22 | </script> | 23 | </script> |
23 | </head> | 24 | </head> |
@@ -25,7 +26,7 @@ | @@ -25,7 +26,7 @@ | ||
25 | <div class="navbar navbar-fixed-top"> | 26 | <div class="navbar navbar-fixed-top"> |
26 | <div class="navbar-inner"> | 27 | <div class="navbar-inner"> |
27 | <div class="container"> | 28 | <div class="container"> |
28 | - <a class="brand" href="#">SRS</a> | 29 | + <a class="brand" href="index.html">SRS</a> |
29 | <div class="nav-collapse collapse"> | 30 | <div class="nav-collapse collapse"> |
30 | <ul class="nav"> | 31 | <ul class="nav"> |
31 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> | 32 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> |
@@ -30,13 +30,28 @@ function update_nav() { | @@ -30,13 +30,28 @@ function update_nav() { | ||
30 | * parse the query string to object. | 30 | * parse the query string to object. |
31 | */ | 31 | */ |
32 | function parse_query_string(){ | 32 | function parse_query_string(){ |
33 | + var obj = {}; | ||
34 | + | ||
35 | + // parse the host(hostname:http_port), pathname(dir/filename) | ||
36 | + obj.host = window.location.host; | ||
37 | + obj.hostname = window.location.hostname; | ||
38 | + obj.http_port = (window.location.port == "")? 80:window.location.port; | ||
39 | + obj.pathname = window.location.pathname; | ||
40 | + if (obj.pathname.lastIndexOf("/") <= 0) { | ||
41 | + obj.dir = "/"; | ||
42 | + obj.filename = ""; | ||
43 | + } else { | ||
44 | + obj.dir = obj.pathname.substr(0, obj.pathname.lastIndexOf("/")); | ||
45 | + obj.filename = obj.pathname.substr(obj.pathname.lastIndexOf("/")); | ||
46 | + } | ||
47 | + | ||
48 | + // parse the query string. | ||
33 | var query_string = String(window.location.search).replace(" ", "").split("?")[1]; | 49 | var query_string = String(window.location.search).replace(" ", "").split("?")[1]; |
34 | if(query_string == undefined){ | 50 | if(query_string == undefined){ |
35 | - return {}; | 51 | + return obj; |
36 | } | 52 | } |
37 | 53 | ||
38 | var queries = query_string.split("&"); | 54 | var queries = query_string.split("&"); |
39 | - var obj = {}; | ||
40 | $(queries).each(function(){ | 55 | $(queries).each(function(){ |
41 | var query = this.split("="); | 56 | var query = this.split("="); |
42 | obj[query[0]] = query[1]; | 57 | obj[query[0]] = query[1]; |
@@ -46,6 +61,7 @@ function parse_query_string(){ | @@ -46,6 +61,7 @@ function parse_query_string(){ | ||
46 | } | 61 | } |
47 | 62 | ||
48 | /** | 63 | /** |
64 | +@param server the ip of server. default to window.location.hostname | ||
49 | @param vhost the vhost of rtmp. default to window.location.hostname | 65 | @param vhost the vhost of rtmp. default to window.location.hostname |
50 | @param port the port of rtmp. default to 1935 | 66 | @param port the port of rtmp. default to 1935 |
51 | @param app the app of rtmp. default to live. | 67 | @param app the app of rtmp. default to live. |
@@ -54,16 +70,23 @@ function parse_query_string(){ | @@ -54,16 +70,23 @@ function parse_query_string(){ | ||
54 | function build_default_rtmp_url() { | 70 | function build_default_rtmp_url() { |
55 | var query = parse_query_string(); | 71 | var query = parse_query_string(); |
56 | 72 | ||
73 | + var server = (query.server == undefined)? window.location.hostname:query.server; | ||
57 | var port = (query.port == undefined)? 1935:query.port; | 74 | var port = (query.port == undefined)? 1935:query.port; |
58 | var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost; | 75 | var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost; |
59 | var app = (query.app == undefined)? "live":query.app; | 76 | var app = (query.app == undefined)? "live":query.app; |
60 | var stream = (query.stream == undefined)? "livestream":query.stream; | 77 | var stream = (query.stream == undefined)? "livestream":query.stream; |
61 | 78 | ||
62 | - return "rtmp://" + vhost + ":" + port + "/" + app + "/" + stream; | 79 | + if (server == vhost || vhost == "") { |
80 | + return "rtmp://" + server + ":" + port + "/" + app + "/" + stream; | ||
81 | + } else { | ||
82 | + return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream; | ||
83 | + } | ||
63 | } | 84 | } |
64 | 85 | ||
65 | /** | 86 | /** |
87 | +@param server the ip of server. default to window.location.hostname | ||
66 | @param vhost the vhost of hls. default to window.location.hostname | 88 | @param vhost the vhost of hls. default to window.location.hostname |
89 | +@param hls_vhost the vhost of hls. override the server if specified. | ||
67 | @param hls_port the port of hls. default to window.location.port | 90 | @param hls_port the port of hls. default to window.location.port |
68 | @param app the app of hls. default to live. | 91 | @param app the app of hls. default to live. |
69 | @param stream the stream of hls. default to livestream. | 92 | @param stream the stream of hls. default to livestream. |
@@ -71,7 +94,14 @@ function build_default_rtmp_url() { | @@ -71,7 +94,14 @@ function build_default_rtmp_url() { | ||
71 | function build_default_hls_url() { | 94 | function build_default_hls_url() { |
72 | var query = parse_query_string(); | 95 | var query = parse_query_string(); |
73 | 96 | ||
74 | - var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost; | 97 | + // for http, use hls_vhost to override server if specified. |
98 | + var server = window.location.hostname; | ||
99 | + if (query.server != undefined) { | ||
100 | + server = query.server; | ||
101 | + } else if (query.hls_vhost != undefined) { | ||
102 | + server = query.hls_vhost; | ||
103 | + } | ||
104 | + | ||
75 | var port = (query.hls_port == undefined)? window.location.port:query.hls_port; | 105 | var port = (query.hls_port == undefined)? window.location.port:query.hls_port; |
76 | var app = (query.app == undefined)? "live":query.app; | 106 | var app = (query.app == undefined)? "live":query.app; |
77 | var stream = (query.stream == undefined)? "livestream":query.stream; | 107 | var stream = (query.stream == undefined)? "livestream":query.stream; |
@@ -79,7 +109,45 @@ function build_default_hls_url() { | @@ -79,7 +109,45 @@ function build_default_hls_url() { | ||
79 | if (port == "" || port == null || port == undefined) { | 109 | if (port == "" || port == null || port == undefined) { |
80 | port = 80; | 110 | port = 80; |
81 | } | 111 | } |
82 | - return "http://" + vhost + ":" + port + "/" + app + "/" + stream + ".m3u8"; | 112 | + |
113 | + return "http://" + server + ":" + port + "/" + app + "/" + stream + ".m3u8"; | ||
114 | +} | ||
115 | + | ||
116 | +/** | ||
117 | +* parse the rtmp url, | ||
118 | +* for example: rtmp://demo.srs.com:1935/live...vhost...players/livestream | ||
119 | +* @return object {server, port, vhost, app, stream} | ||
120 | +*/ | ||
121 | +function srs_parse_rtmp_url(rtmp_url) { | ||
122 | + // @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri | ||
123 | + var a = document.createElement("a"); | ||
124 | + a.href = rtmp_url.replace("rtmp://", "http://"); | ||
125 | + | ||
126 | + var vhost = a.hostname; | ||
127 | + var port = (a.port == "")? "1935":a.port; | ||
128 | + var app = a.pathname.substr(1, a.pathname.lastIndexOf("/") - 1); | ||
129 | + var stream = a.pathname.substr(a.pathname.lastIndexOf("/") + 1); | ||
130 | + | ||
131 | + // parse the vhost in the params of app, that srs supports. | ||
132 | + app = app.replace("...vhost...", "?vhost="); | ||
133 | + if (app.indexOf("?") >= 0) { | ||
134 | + var params = app.substr(app.indexOf("?")); | ||
135 | + app = app.substr(0, app.indexOf("?")); | ||
136 | + | ||
137 | + if (params.indexOf("vhost=") > 0) { | ||
138 | + vhost = params.substr(params.indexOf("vhost=") + "vhost=".length); | ||
139 | + if (vhost.indexOf("&") > 0) { | ||
140 | + vhost = vhost.substr(0, vhost.indexOf("&")); | ||
141 | + } | ||
142 | + } | ||
143 | + } | ||
144 | + | ||
145 | + var ret = { | ||
146 | + server: a.hostname, port: port, | ||
147 | + vhost: vhost, app: app, stream: stream | ||
148 | + }; | ||
149 | + | ||
150 | + return ret; | ||
83 | } | 151 | } |
84 | 152 | ||
85 | /** | 153 | /** |
@@ -91,6 +159,13 @@ function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } | @@ -91,6 +159,13 @@ function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } | ||
91 | 159 | ||
92 | // to query the swf anti cache. | 160 | // to query the swf anti cache. |
93 | function srs_get_version_code() { return "1.1"; } | 161 | function srs_get_version_code() { return "1.1"; } |
162 | +// get the default vhost for players. | ||
163 | +function srs_get_player_vhost() { return "players"; } | ||
164 | +// get the stream published to vhost, | ||
165 | +// generally we need to transcode the stream to support HLS and filters. | ||
166 | +// for example, src_vhost is "players", we transcode stream to vhost "players_pub". | ||
167 | +// if not equals to the player vhost, return the orignal vhost. | ||
168 | +function srs_get_player_publish_vhost(src_vhost) { return (src_vhost != srs_get_player_vhost())? src_vhost:(src_vhost + "_pub"); } | ||
94 | 169 | ||
95 | /** | 170 | /** |
96 | * initialize the page. | 171 | * initialize the page. |
@@ -62,6 +62,15 @@ | @@ -62,6 +62,15 @@ | ||
62 | _url = $("#txt_hls_url").val(); | 62 | _url = $("#txt_hls_url").val(); |
63 | $("#main_modal").modal({show:true, keyboard:false}); | 63 | $("#main_modal").modal({show:true, keyboard:false}); |
64 | }); | 64 | }); |
65 | + | ||
66 | + var query = parse_query_string(); | ||
67 | + if (query.hls_autostart == "true") { | ||
68 | + _url = $("#txt_hls_url").val(); | ||
69 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
70 | + } else if (query.rtmp_autostart == "true") { | ||
71 | + _url = $("#txt_rtmp_url").val(); | ||
72 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
73 | + } | ||
65 | }); | 74 | }); |
66 | </script> | 75 | </script> |
67 | </head> | 76 | </head> |
@@ -69,7 +78,7 @@ | @@ -69,7 +78,7 @@ | ||
69 | <div class="navbar navbar-fixed-top"> | 78 | <div class="navbar navbar-fixed-top"> |
70 | <div class="navbar-inner"> | 79 | <div class="navbar-inner"> |
71 | <div class="container"> | 80 | <div class="container"> |
72 | - <a class="brand" href="#">SRS</a> | 81 | + <a class="brand" href="index.html">SRS</a> |
73 | <div class="nav-collapse collapse"> | 82 | <div class="nav-collapse collapse"> |
74 | <ul class="nav"> | 83 | <ul class="nav"> |
75 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> | 84 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> |
@@ -74,7 +74,7 @@ | @@ -74,7 +74,7 @@ | ||
74 | <div class="navbar navbar-fixed-top"> | 74 | <div class="navbar navbar-fixed-top"> |
75 | <div class="navbar-inner"> | 75 | <div class="navbar-inner"> |
76 | <div class="container"> | 76 | <div class="container"> |
77 | - <a class="brand" href="#">SRS</a> | 77 | + <a class="brand" href="index.html">SRS</a> |
78 | <div class="nav-collapse collapse"> | 78 | <div class="nav-collapse collapse"> |
79 | <ul class="nav"> | 79 | <ul class="nav"> |
80 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> | 80 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> |
@@ -23,7 +23,7 @@ | @@ -23,7 +23,7 @@ | ||
23 | <div class="navbar navbar-fixed-top"> | 23 | <div class="navbar navbar-fixed-top"> |
24 | <div class="navbar-inner"> | 24 | <div class="navbar-inner"> |
25 | <div class="container"> | 25 | <div class="container"> |
26 | - <a class="brand" href="#">SRS</a> | 26 | + <a class="brand" href="index.html">SRS</a> |
27 | <div class="nav-collapse collapse"> | 27 | <div class="nav-collapse collapse"> |
28 | <ul class="nav"> | 28 | <ul class="nav"> |
29 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> | 29 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> |
@@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
26 | </style> | 26 | </style> |
27 | <script type="text/javascript"> | 27 | <script type="text/javascript"> |
28 | var srs_player = null; | 28 | var srs_player = null; |
29 | + var url = null; | ||
29 | 30 | ||
30 | var __active_dar = null; | 31 | var __active_dar = null; |
31 | function select_dar(dar_id, num, den) { | 32 | function select_dar(dar_id, num, den) { |
@@ -88,8 +89,6 @@ | @@ -88,8 +89,6 @@ | ||
88 | $(player).attr("id", "player_id"); | 89 | $(player).attr("id", "player_id"); |
89 | $(div_container).append(player); | 90 | $(div_container).append(player); |
90 | 91 | ||
91 | - var url = $("#txt_url").val(); | ||
92 | - | ||
93 | srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height()); | 92 | srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height()); |
94 | srs_player.on_player_ready = function() { | 93 | srs_player.on_player_ready = function() { |
95 | select_buffer_time("#btn_bt_0_8", 0.8); | 94 | select_buffer_time("#btn_bt_0_8", 0.8); |
@@ -138,6 +137,7 @@ | @@ -138,6 +137,7 @@ | ||
138 | }); | 137 | }); |
139 | 138 | ||
140 | $("#btn_play").click(function(){ | 139 | $("#btn_play").click(function(){ |
140 | + url = $("#txt_url").val(); | ||
141 | $("#main_modal").modal({show:true, keyboard:false}); | 141 | $("#main_modal").modal({show:true, keyboard:false}); |
142 | }); | 142 | }); |
143 | 143 | ||
@@ -151,6 +151,41 @@ | @@ -151,6 +151,41 @@ | ||
151 | } | 151 | } |
152 | }); | 152 | }); |
153 | 153 | ||
154 | + $("#srs_publish").click(function(){ | ||
155 | + url = $("#srs_publish").text(); | ||
156 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
157 | + }); | ||
158 | + $("#srs_publish_ld").click(function(){ | ||
159 | + url = $("#srs_publish_ld").text(); | ||
160 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
161 | + }); | ||
162 | + $("#srs_publish_sd").click(function(){ | ||
163 | + url = $("#srs_publish_sd").text(); | ||
164 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
165 | + }); | ||
166 | + $("#srs_publish_fw").click(function(){ | ||
167 | + url = $("#srs_publish_fw").text(); | ||
168 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
169 | + }); | ||
170 | + $("#srs_publish_fw_ld").click(function(){ | ||
171 | + url = $("#srs_publish_fw_ld").text(); | ||
172 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
173 | + }); | ||
174 | + $("#srs_publish_fw_sd").click(function(){ | ||
175 | + url = $("#srs_publish_fw_sd").text(); | ||
176 | + $("#main_modal").modal({show:true, keyboard:false}); | ||
177 | + }); | ||
178 | + | ||
179 | + var query = parse_query_string(); | ||
180 | + var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=live&hls_autostart=true"; | ||
181 | + $("#srs_publish_hls").attr("href", jwplayer_url + "&stream=livestream"); | ||
182 | + $("#srs_publish_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld"); | ||
183 | + $("#srs_publish_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd"); | ||
184 | + var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?vhost=demo.srs.com&app=forward/live&hls_autostart=true"; | ||
185 | + $("#srs_publish_fw_hls").attr("href", jwplayer_url + "&stream=livestream"); | ||
186 | + $("#srs_publish_fw_ld_hls").attr("href", jwplayer_url + "&stream=livestream_ld"); | ||
187 | + $("#srs_publish_fw_sd_hls").attr("href", jwplayer_url + "&stream=livestream_sd"); | ||
188 | + | ||
154 | if (true) { | 189 | if (true) { |
155 | $("#btn_dar_original").click(function(){ | 190 | $("#btn_dar_original").click(function(){ |
156 | select_dar("#btn_dar_original", 0, 0); | 191 | select_dar("#btn_dar_original", 0, 0); |
@@ -228,7 +263,7 @@ | @@ -228,7 +263,7 @@ | ||
228 | <div class="navbar navbar-fixed-top"> | 263 | <div class="navbar navbar-fixed-top"> |
229 | <div class="navbar-inner"> | 264 | <div class="navbar-inner"> |
230 | <div class="container"> | 265 | <div class="container"> |
231 | - <a class="brand" href="#">SRS</a> | 266 | + <a class="brand" href="index.html">SRS</a> |
232 | <div class="nav-collapse collapse"> | 267 | <div class="nav-collapse collapse"> |
233 | <ul class="nav"> | 268 | <ul class="nav"> |
234 | <li class="active"><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> | 269 | <li class="active"><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> |
@@ -252,6 +287,171 @@ | @@ -252,6 +287,171 @@ | ||
252 | <input type="text" id="txt_url" class="input-xxlarge" value=""></input> | 287 | <input type="text" id="txt_url" class="input-xxlarge" value=""></input> |
253 | <button class="btn btn-primary" id="btn_play">播放视频</button> | 288 | <button class="btn btn-primary" id="btn_play">播放视频</button> |
254 | </div> | 289 | </div> |
290 | + <div class="container"> | ||
291 | + <hr/> | ||
292 | + <span> | ||
293 | + 注意:必须按照<a href="https://github.com/winlinvip/simple-rtmp-server/blob/master/README.md">SRS README.md</a> | ||
294 | + 中的11个Step做完,下面所有的链接才能观看。 | ||
295 | + </span> | ||
296 | + <div class="accordion" id="main_accordion"> | ||
297 | + <div class="accordion-group"> | ||
298 | + <div class="accordion-heading"> | ||
299 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse1"> | ||
300 | + <strong>[1] SRS示例播放流: 原始流</strong> | ||
301 | + </span> | ||
302 | + </div> | ||
303 | + <div id="collapse1" class="accordion-body collapse"> | ||
304 | + <div class="accordion-inner"> | ||
305 | + <a href="#" id="srs_publish">rtmp://demo.srs.com/live/livestream</a> <br/> | ||
306 | + <span>用户推送过来的唯一一路流,经过服务器的多种变换和再转发。</span> | ||
307 | + </div> | ||
308 | + </div> | ||
309 | + </div> | ||
310 | + <div class="accordion-group"> | ||
311 | + <div class="accordion-heading"> | ||
312 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse10"> | ||
313 | + <strong>[2] SRS示例播放流: 原始流HLS</strong> | ||
314 | + </span> | ||
315 | + </div> | ||
316 | + <div id="collapse10" class="accordion-body collapse"> | ||
317 | + <div class="accordion-inner"> | ||
318 | + <a href="#" id="srs_publish_hls">http://demo.srs.com/live/livestream.m3u8</a> <br/> | ||
319 | + <span>对用户的流进行HLS切片(若编码为非H264/AAC,HLS流会自动禁用)。</span> | ||
320 | + </div> | ||
321 | + </div> | ||
322 | + </div> | ||
323 | + <div class="accordion-group"> | ||
324 | + <div class="accordion-heading"> | ||
325 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse2"> | ||
326 | + <strong>[3] SRS示例播放流: 转码配置LD流</strong> | ||
327 | + </span> | ||
328 | + </div> | ||
329 | + <div id="collapse2" class="accordion-body collapse"> | ||
330 | + <div class="accordion-inner"> | ||
331 | + <a href="#" id="srs_publish_ld">rtmp://demo.srs.com/live/livestream_ld</a> <br/> | ||
332 | + <span>对原始流加了<a href="http://ffmpeg.org/ffmpeg-filters.html#drawtext-1">FFMPEG文字水印</a></span> | ||
333 | + </div> | ||
334 | + </div> | ||
335 | + </div> | ||
336 | + <div class="accordion-group"> | ||
337 | + <div class="accordion-heading"> | ||
338 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse11"> | ||
339 | + <strong>[4] SRS示例播放流: 转码配置LD流HLS</strong> | ||
340 | + </span> | ||
341 | + </div> | ||
342 | + <div id="collapse11" class="accordion-body collapse"> | ||
343 | + <div class="accordion-inner"> | ||
344 | + <a href="#" id="srs_publish_ld_hls">http://demo.srs.com/live/livestream_ld.m3u8</a> <br/> | ||
345 | + <span>对转码配置LD流进行HLS切片。</span> | ||
346 | + </div> | ||
347 | + </div> | ||
348 | + </div> | ||
349 | + <div class="accordion-group"> | ||
350 | + <div class="accordion-heading"> | ||
351 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse3"> | ||
352 | + <strong>[5] SRS示例播放流: 转码配置SD流</strong> | ||
353 | + </span> | ||
354 | + </div> | ||
355 | + <div id="collapse3" class="accordion-body collapse"> | ||
356 | + <div class="accordion-inner"> | ||
357 | + <a href="#" id="srs_publish_sd">rtmp://demo.srs.com/live/livestream_sd</a> <br/> | ||
358 | + <span>对原始流应用了<a href="http://ffmpeg.org/ffmpeg-filters.html#Filtering-Introduction">FFMPEG翻转滤镜</a></span> | ||
359 | + </div> | ||
360 | + </div> | ||
361 | + </div> | ||
362 | + <div class="accordion-group"> | ||
363 | + <div class="accordion-heading"> | ||
364 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse12"> | ||
365 | + <strong>[6] SRS示例播放流: 转码配置SD流HLS</strong> | ||
366 | + </span> | ||
367 | + </div> | ||
368 | + <div id="collapse12" class="accordion-body collapse"> | ||
369 | + <div class="accordion-inner"> | ||
370 | + <a href="#" id="srs_publish_sd_hls">http://demo.srs.com/live/livestream_sd.m3u8</a> <br/> | ||
371 | + <span>对转码配置SD流进行HLS切片。</span> | ||
372 | + </div> | ||
373 | + </div> | ||
374 | + </div> | ||
375 | + <div class="accordion-group"> | ||
376 | + <div class="accordion-heading"> | ||
377 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse4"> | ||
378 | + <strong>[7] SRS示例播放流: 转发原始流</strong> | ||
379 | + </span> | ||
380 | + </div> | ||
381 | + <div id="collapse4" class="accordion-body collapse"> | ||
382 | + <div class="accordion-inner"> | ||
383 | + <a href="#" id="srs_publish_fw">rtmp://demo.srs.com:19350/live/livestream</a> <br/> | ||
384 | + <span>将用户推送的流转发到另外的vhost或服务器,做热备用。</span> | ||
385 | + </div> | ||
386 | + </div> | ||
387 | + </div> | ||
388 | + <div class="accordion-group"> | ||
389 | + <div class="accordion-heading"> | ||
390 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse13"> | ||
391 | + <strong>[8] SRS示例播放流: 转发原始流HLS</strong> | ||
392 | + </span> | ||
393 | + </div> | ||
394 | + <div id="collapse13" class="accordion-body collapse"> | ||
395 | + <div class="accordion-inner"> | ||
396 | + <a href="#" id="srs_publish_fw_hls">http://demo.srs.com/forward/live/livestream.m3u8</a> <br/> | ||
397 | + <span>对转发原始流进行HLS切片(若编码为非H264/AAC,HLS流会自动禁用)。</span> | ||
398 | + </div> | ||
399 | + </div> | ||
400 | + </div> | ||
401 | + <div class="accordion-group"> | ||
402 | + <div class="accordion-heading"> | ||
403 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse5"> | ||
404 | + <strong>[9] SRS示例播放流: 转发转码配置LD流</strong> | ||
405 | + </span> | ||
406 | + </div> | ||
407 | + <div id="collapse5" class="accordion-body collapse"> | ||
408 | + <div class="accordion-inner"> | ||
409 | + <a href="#" id="srs_publish_fw_ld">rtmp://demo.srs.com:19350/live/livestream_ld</a> <br/> | ||
410 | + <span>FFMPEG加水印后的流也会自动转发。</span> | ||
411 | + </div> | ||
412 | + </div> | ||
413 | + </div> | ||
414 | + <div class="accordion-group"> | ||
415 | + <div class="accordion-heading"> | ||
416 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse14"> | ||
417 | + <strong>[10] SRS示例播放流: 转发转码配置LD流HLS</strong> | ||
418 | + </span> | ||
419 | + </div> | ||
420 | + <div id="collapse14" class="accordion-body collapse"> | ||
421 | + <div class="accordion-inner"> | ||
422 | + <a href="#" id="srs_publish_fw_ld_hls">http://demo.srs.com/forward/live/livestream_ld.m3u8</a> <br/> | ||
423 | + <span>对转发转码配置LD流进行HLS切片,所有转发的流会自动支持HLS。</span> | ||
424 | + </div> | ||
425 | + </div> | ||
426 | + </div> | ||
427 | + <div class="accordion-group"> | ||
428 | + <div class="accordion-heading"> | ||
429 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse6"> | ||
430 | + <strong>[11] SRS示例播放流: 转发转码配置SD流</strong> | ||
431 | + </span> | ||
432 | + </div> | ||
433 | + <div id="collapse6" class="accordion-body collapse"> | ||
434 | + <div class="accordion-inner"> | ||
435 | + <a href="#" id="srs_publish_fw_sd">rtmp://demo.srs.com:19350/live/livestream_sd</a> <br/> | ||
436 | + <span>FFMPEG翻转后的流也会自动转发。</span> | ||
437 | + </div> | ||
438 | + </div> | ||
439 | + </div> | ||
440 | + <div class="accordion-group"> | ||
441 | + <div class="accordion-heading"> | ||
442 | + <span class="accordion-toggle" data-toggle="collapse" data-parent="#main_accordion" href="#collapse15"> | ||
443 | + <strong>[12] SRS示例播放流: 转发转码配置SD流HLS</strong> | ||
444 | + </span> | ||
445 | + </div> | ||
446 | + <div id="collapse15" class="accordion-body collapse"> | ||
447 | + <div class="accordion-inner"> | ||
448 | + <a href="#" id="srs_publish_fw_sd_hls">http://demo.srs.com/forward/live/livestream_sd.m3u8</a> <br/> | ||
449 | + <span>对转发转码配置SD流进行HLS切片,所有转发的流会自动支持HLS。</span> | ||
450 | + </div> | ||
451 | + </div> | ||
452 | + </div> | ||
453 | + </div> | ||
454 | + </div> | ||
255 | <div id="main_modal" class="modal hide fade"> | 455 | <div id="main_modal" class="modal hide fade"> |
256 | <div class="modal-header"> | 456 | <div class="modal-header"> |
257 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | 457 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
@@ -140,6 +140,7 @@ package | @@ -140,6 +140,7 @@ package | ||
140 | private function system_on_metadata(metadata:Object):void { | 140 | private function system_on_metadata(metadata:Object):void { |
141 | this.media_metadata = metadata; | 141 | this.media_metadata = metadata; |
142 | 142 | ||
143 | + if (metadata.hasOwnProperty("server")) { | ||
143 | // for context menu | 144 | // for context menu |
144 | var customItems:Array = [new ContextMenuItem("SrsPlayer")]; | 145 | var customItems:Array = [new ContextMenuItem("SrsPlayer")]; |
145 | if (metadata.hasOwnProperty("server")) { | 146 | if (metadata.hasOwnProperty("server")) { |
@@ -149,6 +150,7 @@ package | @@ -149,6 +150,7 @@ package | ||
149 | customItems.push(new ContextMenuItem("Contributor: " + metadata.contributor)); | 150 | customItems.push(new ContextMenuItem("Contributor: " + metadata.contributor)); |
150 | } | 151 | } |
151 | contextMenu.customItems = customItems; | 152 | contextMenu.customItems = customItems; |
153 | + } | ||
152 | 154 | ||
153 | // for js. | 155 | // for js. |
154 | var obj:Object = __get_video_size_object(); | 156 | var obj:Object = __get_video_size_object(); |
@@ -123,32 +123,39 @@ | @@ -123,32 +123,39 @@ | ||
123 | remote_player.start(); | 123 | remote_player.start(); |
124 | }); | 124 | }); |
125 | 125 | ||
126 | + /** | ||
127 | + * we generate the transcoded stream url for flash publish donot support HLS | ||
128 | + * which requires aac, so the publish vhost maybe players for example, we | ||
129 | + * use players_pub vhost(transcoded stream to which) for all clients, | ||
130 | + * both players and players_pub are write HLS to the sample dir, | ||
131 | + * it's ok for the players vhost disabled the HLS, only the | ||
132 | + * players_pub enalbed HLS. | ||
133 | + */ | ||
126 | function update_play_url() { | 134 | function update_play_url() { |
127 | - // @see: http://stackoverflow.com/questions/10469575/how-to-use-location-object-to-parse-url-without-redirecting-the-page-in-javascri | ||
128 | - var a = document.createElement("a"); | ||
129 | - a.href = $("#txt_url").val().replace("rtmp://", "http://"); | 135 | + var ret = srs_parse_rtmp_url($("#txt_url").val()); |
136 | + var query = parse_query_string(); | ||
130 | 137 | ||
131 | - var url = "http://" + window.location.host; | ||
132 | - url += window.location.pathname.substr(0, window.location.pathname.lastIndexOf("/")); | ||
133 | - url += "/srs_player.html?"; | 138 | + var srs_player_url = "http://" + query.host + query.dir + "/srs_player.html?"; |
139 | + srs_player_url += "vhost=" + srs_get_player_publish_vhost(ret.vhost) + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream; | ||
140 | + srs_player_url += "&autostart=true"; | ||
134 | 141 | ||
135 | - url += "vhost=" + a.hostname; | ||
136 | - url += "&port=" + a.port; | ||
137 | - url += "&app=" + a.pathname.substr(1, a.pathname.lastIndexOf("/") - 1); | ||
138 | - url += "&stream=" + a.pathname.substr(a.pathname.lastIndexOf("/") + 1); | 142 | + var jwplayer_url = "http://" + query.host + query.dir + "/jwplayer6.html?"; |
143 | + jwplayer_url += "vhost=" + srs_get_player_publish_vhost(ret.vhost) + "&port=" + ret.port + "&app=" + ret.app + "&stream=" + ret.stream; | ||
144 | + jwplayer_url += "&hls_autostart=true"; | ||
139 | 145 | ||
140 | - // autostart | ||
141 | - url += "&autostart=true"; | 146 | + var hls_url = "http://" + ret.server + ":" + query.http_port + "/" + ret.app + "/" + ret.stream + ".m3u8"; |
142 | 147 | ||
143 | - $("#txt_play_url").text(url); | ||
144 | - $("#txt_play_url").attr("href", url); | ||
145 | - $("#txt_play_url").attr("target", "_blank"); | 148 | + $("#txt_play_url").text("点击或右键复制").attr("href", srs_player_url).attr("target", "_blank"); |
149 | + $("#txt_play_hls").text("点击或右键复制").attr("href", hls_url).attr("target", "_blank"); | ||
150 | + $("#txt_play_jwplayer").text("点击或右键复制").attr("href", jwplayer_url).attr("target", "_blank"); | ||
146 | } | 151 | } |
147 | function on_user_publish() { | 152 | function on_user_publish() { |
148 | if ($("#btn_publish").text() == "停止发布") { | 153 | if ($("#btn_publish").text() == "停止发布") { |
149 | srs_publisher.stop(); | 154 | srs_publisher.stop(); |
150 | $("#btn_publish").text("发布视频"); | 155 | $("#btn_publish").text("发布视频"); |
151 | $("#txt_play_url").text("请发布视频").attr("href", "#").attr("target", "_self"); | 156 | $("#txt_play_url").text("请发布视频").attr("href", "#").attr("target", "_self"); |
157 | + $("#txt_play_hls").text("请发布视频").attr("href", "#").attr("target", "_self"); | ||
158 | + $("#txt_play_jwplayer").text("请发布视频").attr("href", "#").attr("target", "_self"); | ||
152 | return; | 159 | return; |
153 | } | 160 | } |
154 | 161 | ||
@@ -178,8 +185,11 @@ | @@ -178,8 +185,11 @@ | ||
178 | srs_publisher.publish(url, vcodec, acodec); | 185 | srs_publisher.publish(url, vcodec, acodec); |
179 | 186 | ||
180 | // replay the url. | 187 | // replay the url. |
188 | + var ret = srs_parse_rtmp_url(url); | ||
189 | + var pub_url = "rtmp://" + ret.server + ":" + ret.port + "/" + ret.app; | ||
190 | + pub_url += "?vhost=" + srs_get_player_publish_vhost(ret.vhost) + "/" + ret.stream; | ||
181 | remote_player.stop(); | 191 | remote_player.stop(); |
182 | - remote_player.play(url); | 192 | + remote_player.play(pub_url); |
183 | } | 193 | } |
184 | 194 | ||
185 | function info(desc) { | 195 | function info(desc) { |
@@ -198,7 +208,7 @@ | @@ -198,7 +208,7 @@ | ||
198 | <div class="navbar navbar-fixed-top"> | 208 | <div class="navbar navbar-fixed-top"> |
199 | <div class="navbar-inner"> | 209 | <div class="navbar-inner"> |
200 | <div class="container"> | 210 | <div class="container"> |
201 | - <a class="brand" href="#">SRS</a> | 211 | + <a class="brand" href="index.html">SRS</a> |
202 | <div class="nav-collapse collapse"> | 212 | <div class="nav-collapse collapse"> |
203 | <ul class="nav"> | 213 | <ul class="nav"> |
204 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> | 214 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> |
@@ -233,10 +243,22 @@ | @@ -233,10 +243,22 @@ | ||
233 | </div> | 243 | </div> |
234 | <div class="control-group"> | 244 | <div class="control-group"> |
235 | <div class="form-inline"> | 245 | <div class="form-inline"> |
236 | - 观看地址: | 246 | + 观看地址(rtmp地址): |
237 | <a id="txt_play_url" class="input-xxlarge" href="#">请发布视频</a> | 247 | <a id="txt_play_url" class="input-xxlarge" href="#">请发布视频</a> |
238 | </div> | 248 | </div> |
239 | </div> | 249 | </div> |
250 | + <div class="control-group"> | ||
251 | + <div class="form-inline"> | ||
252 | + HLS地址(m3u8地址): | ||
253 | + <a id="txt_play_hls" class="input-xxlarge" href="#">请发布视频</a> | ||
254 | + </div> | ||
255 | + </div> | ||
256 | + <div class="control-group"> | ||
257 | + <div class="form-inline"> | ||
258 | + HLS地址(JWPlayer): | ||
259 | + <a id="txt_play_jwplayer" class="input-xxlarge" href="#">请发布视频</a> | ||
260 | + </div> | ||
261 | + </div> | ||
240 | <div id="video_modal" class="modal hide fade"> | 262 | <div id="video_modal" class="modal hide fade"> |
241 | <div class="modal-header"> | 263 | <div class="modal-header"> |
242 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | 264 | <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
@@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
24 | <div class="navbar navbar-fixed-top"> | 24 | <div class="navbar navbar-fixed-top"> |
25 | <div class="navbar-inner"> | 25 | <div class="navbar-inner"> |
26 | <div class="container"> | 26 | <div class="container"> |
27 | - <a class="brand" href="#">SRS</a> | 27 | + <a class="brand" href="index.html">SRS</a> |
28 | <div class="nav-collapse collapse"> | 28 | <div class="nav-collapse collapse"> |
29 | <ul class="nav"> | 29 | <ul class="nav"> |
30 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> | 30 | <li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li> |
-
请 注册 或 登录 后发表评论