├── Control-module.md ├── Directives.md ├── Examples.md ├── Exec-wrapper-in-bash.md ├── FAQ.md ├── Getting-number-of-subscribers.md ├── Getting-started-with-nginx-rtmp.md ├── Home.md ├── README.md └── Tutorial.md /Control-module.md: -------------------------------------------------------------------------------- 1 | Control module is HTTP module which makes it possible to control rtmp module from outside using HTTP protocol. Here's an example of how to enable control. 2 | 3 | http { 4 | ... 5 | server { 6 | listen 8080; 7 | server_name localhost; 8 | .... 9 | location /control { 10 | rtmp_control all; 11 | } 12 | } 13 | } 14 | 15 | There are several sub-modules within control module each controlling a different feature. 16 | # Record 17 | This sub-module starts and stops recordings created with _manual_ flag. 18 | Syntax: 19 | 20 | http://server.com/control/record/start|stop?srv=SRV&app=APP&name=NAME&rec=REC 21 | 22 | * srv=SRV - optional server{} block number within rtmp{} block, default to first server{} block 23 | * app=APP - required application name 24 | * name=NAME - required stream name 25 | * rec=REC - optional recorder name, defaults to root (unnamed) recorder 26 | 27 | Example 28 | 29 | rtmp { 30 | server { 31 | listen 1935; 32 | application myapp { 33 | live on; 34 | recorder rec1 { 35 | record all manual; 36 | record_suffix all.flv; 37 | record_path /tmp/rec; 38 | record_unique on; 39 | } 40 | } 41 | } 42 | } 43 | 44 | Publish the stream with the following command 45 | 46 | ffmpeg -i http://someserver.com/mychannel.ts -c:v copy -c:a nellymoser -ar 44100 -ac 1 -f flv rtmp://localhost/myapp/mystream 47 | 48 | Use the following commands to start and stop recording 49 | 50 | curl "http://localhost:8080/control/record/start?app=myapp&name=mystream&rec=rec1" 51 | curl "http://localhost:8080/control/record/stop?app=myapp&name=mystream&rec=rec1" 52 | 53 | if the record start/stop request returns nothing sometimes, you should check if you use multi workers. one worker works great. 54 | 55 | # Drop 56 | This sub-module provides a simple way to drop client connection. 57 | Syntax: 58 | 59 | http://server.com/control/drop/publisher|subscriber|client? 60 | srv=SRV&app=APP&name=NAME&addr=ADDR&clientid=CLIENTID 61 | 62 | * srv, app, name - the same as above 63 | * addr - optional client address (the same as returned by rtmp_stat) 64 | * clientid - optional nginx client id (displayed in log and stat) 65 | 66 | The first method ```drop/publisher``` drops publisher connection. The second ```drop/client``` drops every connection matching ```addr``` argument or all clients (including publisher) if ```addr``` is not specified. 67 | 68 | Examples 69 | 70 | curl http://localhost:8080/control/drop/publisher?app=myapp&name=mystream 71 | curl http://localhost:8080/control/drop/client?app=myapp&name=mystream 72 | curl http://localhost:8080/control/drop/client?app=myapp&name=mystream&addr=192.168.0.1 73 | curl http://localhost:8080/control/drop/client?app=myapp&name=mystream&clientid=1 74 | 75 | # Redirect 76 | Redirect play/publish client to a new stream. 77 | Syntax: 78 | 79 | http://server.com/control/redirect/publisher|subscriber|client? 80 | srv=SRV&app=APP&name=NAME&addr=ADDR&clientid=CLIENTID&newname=NEWNAME 81 | 82 | * srv, app, name, addr, clients - the same as above 83 | * newname - new stream name to redirect to 84 | -------------------------------------------------------------------------------- /Directives.md: -------------------------------------------------------------------------------- 1 | Table of Contents 2 | ================= 3 | * [ngx_rtmp_module](#ngx_rtmp_module) 4 | * [rtmp](#rtmp) 5 | * [ngx_rtmp_core_module](#ngx_rtmp_core_module) 6 | * [server](#server) 7 | * [listen](#listen) 8 | * [application](#application) 9 | * [so_keepalive](#so_keepalive) 10 | * [timeout](#timeout) 11 | * [ping](#ping) 12 | * [ping_timeout](#ping_timeout) 13 | * [max_streams](#max_streams) 14 | * [ack_window](#ack_window) 15 | * [chunk_size](#chunk_size) 16 | * [max_message](#max_message) 17 | * [out_queue](#out_queue) 18 | * [out_cork](#out_cork) 19 | * [busy](#busy) 20 | * [play_time_fix](#play_time_fix) 21 | * [publish_time_fix](#publish_time_fix) 22 | * [buflen](#buflen) 23 | * [ngx_rtmp_access_module](#access) 24 | * [allow](#allow) 25 | * [deny](#deny) 26 | * [ngx_rtmp_exec_module](#exec) 27 | * [exec_push](#exec_push) 28 | * [exec_pull](#exec_pull) 29 | * [exec](#exec) 30 | * [exec_options](#exec_options) 31 | * [exec_static](#exec_static) 32 | * [exec_kill_signal](#exec_kill_signal) 33 | * [respawn](#respawn) 34 | * [respawn_timeout](#respawn_timeout) 35 | * [exec_publish](#exec_publish) 36 | * [exec_play](#exec_play) 37 | * [exec_play_done](#exec_play_done) 38 | * [exec_publish_done](#exec_publish_done) 39 | * [exec_record_done](#exec_record_done) 40 | * [ngx_rtmp_live_module](#live) 41 | * [live](#live) 42 | * [meta](#meta) 43 | * [interleave](#interleave) 44 | * [wait_key](#wait_key) 45 | * [wait_video](#wait_video) 46 | * [publish_notify](#publish_notify) 47 | * [drop_idle_publisher](#drop_idle_publisher) 48 | * [sync](#sync) 49 | * [play_restart](#play_restart) 50 | * [idle_streams](#idle_streams) 51 | * [ngx_rtmp_record_module](#record) 52 | * [record](#record) 53 | * [record_path](#record_path) 54 | * [record_suffix](#record_suffix) 55 | * [record_unique](#record_unique) 56 | * [record_append](#record_append) 57 | * [record_lock](#record_lock) 58 | * [record_max_size](#record_max_size) 59 | * [record_max_frames](#record_max_frames) 60 | * [record_interval](#record_interval) 61 | * [recorder](#recorder) 62 | * [record_notify](#record_notify) 63 | * [ngx_rtmp_play_module](#video-on-demand) 64 | * [play](#play) 65 | * [play_temp_path](#play_temp_path) 66 | * [play_local_path](#play_local_path) 67 | * [ngx_rtmp_relay_module](#relay) 68 | * [pull](#pull) 69 | * [push](#push) 70 | * [push_reconnect](#push_reconnect) 71 | * [session_relay](#session_relay) 72 | * [ngx_rtmp_notify_module](#notify) 73 | * [on_connect](#on_connect) 74 | * [on_play](#on_play) 75 | * [on_publish](#on_publish) 76 | * [on_done](#on_done) 77 | * [on_play_done](#on_play_done) 78 | * [on_publish_done](#on_publish_done) 79 | * [on_record_done](#on_record_done) 80 | * [on_update](#on_update) 81 | * [notify_update_timeout](#notify_update_timeout) 82 | * [notify_update_strict](#notify_update_strict) 83 | * [notify_relay_redirect](#notify_relay_redirect) 84 | * [notify_method](#notify_method) 85 | * [ngx_rtmp_hls_module](#hls) 86 | * [hls](#hls) 87 | * [hls_path](#hls_path) 88 | * [hls_fragment](#hls_fragment) 89 | * [hls_playlist_length](#hls_playlist_length) 90 | * [hls_sync](#hls_sync) 91 | * [hls_continuous](#hls_continuous) 92 | * [hls_nested](#hls_nested) 93 | * [hls_base_url](#hls_base_url) 94 | * [hls_cleanup](#hls_cleanup) 95 | * [hls_fragment_naming](#hls_fragment_naming) 96 | * [hls_fragment_naming_granularity](#hls_fragment_naming_granularity) 97 | * [hls_fragment_slicing](#hls_fragment_slicing) 98 | * [hls_variant](#hls_variant) 99 | * [hls_type](#hls_type) 100 | * [hls_keys](#hls_keys) 101 | * [hls_key_path](#hls_key_path) 102 | * [hls_key_url](#hls_key_url) 103 | * [hls_fragments_per_key](#hls_fragments_per_key) 104 | * [ngx_rtmp_dash_module](#mpeg-dash) 105 | * [dash](#dash) 106 | * [dash_path](#dash_path) 107 | * [dash_fragment](#dash_fragment) 108 | * [dash_playlist_length](#dash_playlist_length) 109 | * [dash_nested](#dash_nested) 110 | * [dash_cleanup](#dash_cleanup) 111 | * [ngx_rtmp_access_module](#access-log) 112 | * [access_log](#access_log) 113 | * [log_format](#log_format) 114 | * [ngx_rtmp_limit_module](#limits) 115 | * [max_connections](#max_connections) 116 | * [ngx_rtmp_stat_module](#statistics) 117 | * [rtmp_stat](#rtmp_stat) 118 | * [rtmp_stat_stylesheet](#rtmp_stat_stylesheet) 119 | * [ngx_rtmp_auto_push_module](#multi-worker-live-streaming) 120 | * [rtmp_auto_push](#rtmp_auto_push) 121 | * [rtmp_auto_push_reconnect](#rtmp_auto_push_reconnect) 122 | * [rtmp_socket_dir](#rtmp_socket_dir) 123 | * [ngx_rtmp_control_module](#control) 124 | * [rtmp_control](#rtmp_control) 125 | 126 | ## ngx_rtmp_module 127 | #### rtmp 128 | syntax: `rtmp { ... }` 129 | context: root 130 | RTMP 配置块. 131 | 132 | ## ngx_rtmp_core_module 133 | #### server 134 | syntax: `server { ... }` 135 | context: rtmp 136 | 作用:配置一个rtmp server 块. 137 | 138 | rtmp { 139 | server { 140 | } 141 | } 142 | 143 | #### listen 144 | syntax: `listen (addr[:port]|port|unix:path) [bind] [ipv6only=on|off] [so_keepalive=on|off|keepidle:keepintvl:keepcnt|proxy_protocol]` 145 | context: server 146 | 147 | 添加一个监听套接字来接收客户端连接. 148 | 149 | server { 150 | listen 1935; 151 | } 152 | 153 | #### application 154 | syntax: `application name { ... }` 155 | context: server 156 | 157 | 创建一个 RTMP 的 application, 与 http 配置中的 location 指令不同, 158 | application只能是精确的字符串。 159 | 160 | server { 161 | listen 1935; 162 | application myapp { 163 | } 164 | } 165 | 166 | ### so_keepalive 167 | 168 | 该指令已废弃,改为在 listen 中设置 keepalive. 169 | 170 | #### timeout 171 | syntax: `timeout value` 172 | context: rtmp, server 173 | 174 | timeout 设置了 socket 的超时时间,这个超时主要用在写操作中。多数时候, RTMP 模块只会 175 | 期待在发布者的连接上的写事件。如果你想快速断开连接,可以使用 keepalive 或者 RTMP ping 176 | 消息.该配置默认为1分钟. 177 | 178 | timeout 60s; 179 | 180 | #### ping 181 | syntax: `ping value` 182 | context: rtmp, server 183 | 184 | RTMP 服务器会向客户端定期发送 ping 请求,来检查客户端是否可用。如果在一个时间段内, 185 | 服务器收到了客户端的ping响应,则认为客户端是可用的,否则认为客户端不可用。这个时间段 186 | 也是可配置的,由ping_timeout配置,默认为30秒。 187 | 188 | 在 RTMP 协议中,ping请求是一个用户控制消息,即消息类型为4的消息,用户控制消息的消息 189 | 负载中的event类型决定了是哪一种用户控制消息,ping消息对应的event类型标识位为6. 190 | 191 | 该配置配置了 RTMP 向客户端发送ping消息的时间间隔,默认为60秒,如果设置为0,则不向客户端 192 | 发送ping请求。 193 | 194 | ping 3m; 195 | ping_timeout 30s; 196 | 197 | #### ping_timeout 198 | syntax: `ping_timeout value` 199 | context: rtmp, server 200 | 201 | 用法见ping指令。 202 | 203 | #### max_streams 204 | syntax: `max_streams value` 205 | context: rtmp, server 206 | 207 | 指令所属模块: ngx_rtmp_core_module 208 | 209 | 指令作用: 设置 RTMP chunk 流(注意与 message 流不同)的最大个数. 多个chunk流会整合到 210 | 一个单一的数据流里.一个 RTMP chunk 流是一个逻辑通道,不同的 chunk 流用来传输不同类型 211 | 的命令、音视频数据等。默认的逻辑通道个数为32,这个值在大多数情况下都可以满足需求。 212 | 213 | max_streams 32; 214 | 215 | #### ack_window 216 | syntax: `ack_window value` 217 | context: rtmp, server 218 | 219 | RTMP 协议中有一种协议控制消息为Window Acknowledgement Size,其消息类型为5. 220 | 客户端或服务端发送本消息来通知对方发送确认(致谢)消息的窗口大小。例如,服 221 | 务端希望每当发送的字节数等于窗口大小时从客户端收到确认(致谢)。服务端在成 222 | 功处理了客户端的连接请求后向客户端更新窗口大小。默认为5000000。 223 | 224 | ack_window 5000000; 225 | 226 | #### chunk_size 227 | syntax: `chunk_size value` 228 | context: rtmp, server 229 | 230 | 改配置设置了最大的chunk size.默认为4096字节。该值越大,则cpu的负载越低。RTMP 231 | 协议规定,该值不能小于128。 232 | 233 | 注意,不要将这个chunk_size与客户端发过来的chunk size搞混淆了。这里的chunk_size是 234 | 指,nginx向客户端发送set chunk size消息,告知自己的chunk size.这个chunk size需要 235 | 在这里配置,默认为4096. 236 | 237 | 而客户端发送过来的chunk,其chunk size由nginx解析客户端的消息得到。默认为128. 238 | 239 | chunk_size 4096; 240 | 241 | #### max_message 242 | syntax: `max_message value` 243 | context: rtmp, server 244 | 245 | 指令所属模块: ngx_rtmp_core_module 246 | 247 | 指令作用:设置可接收的单个 message 大小的最大值。所有的输入数据会被分割为多个 248 | message(在底层会被进而分割为多个 chunks).一个不完整的 message 会保留在内存中 249 | 等待接收完整。理论上一个输入的 message 可以非常大,这会对服务器的稳定性造成影响。 250 | 默认值是1M,在大多数情况下是够用的。 251 | 252 | max_message 1M; 253 | 254 | ### buflen 255 | syntax: `buflen time` 256 | context: rtmp, server 257 | 258 | Sets default buffer length. Usually client sends RTMP `set_buflen` command 259 | before playing and resets this setting. Default is `1000 ms`. 260 | 261 | buflen 5s; 262 | 263 | #### out_queue 264 | syntax: `out_queue value` 265 | context: rtmp, server 266 | 267 | 默认值为256. 268 | 269 | out_queue 1K; 270 | 271 | #### out_cork 272 | syntax: `out_cork value` 273 | context: rtmp, server 274 | 275 | 默认值为out_queue的八分之一,所以在out_queue采用默认设置即256时,out_cork为32. 276 | 277 | out_cork 1K; 278 | 279 | ## Access 280 | 281 | #### allow 282 | Syntax: `allow [play|publish] address|subnet|all` 283 | Context: rtmp, server, application 284 | 285 | Allow publishing/playing from addresses specified or from all addresses. 286 | Allow/deny directives are checked in order of appearance. 287 | 288 | allow publish 127.0.0.1; 289 | deny publish all; 290 | allow play 192.168.0.0/24; 291 | deny play all; 292 | 293 | #### deny 294 | Syntax: `deny [play|publish] address|subnet|all` 295 | Context: rtmp, server, application 296 | 297 | See allow for description. 298 | 299 | ## Exec 300 | 301 | #### exec_push 302 | Syntax: `exec_push command arg*` 303 | Context: rtmp, server, application 304 | 305 | Specifies external command with arguments to be executed on 306 | every stream published. When publishing stops the process 307 | is terminated. Full path to binary should be specified as the 308 | first argument. There are no assumptions about what this process should 309 | do. However this feature is useful with ffmpeg for stream 310 | transcoding. FFmpeg is supposed to connect to nginx-rtmp as a client 311 | and output transcoded stream back to nginx-rtmp as publisher. Substitutions 312 | of form $var/${var} can be used within command line: 313 | * $name - stream name 314 | * $app - application name 315 | * $addr - client address 316 | * $flashver - client flash version 317 | * $swfurl - client swf url 318 | * $tcurl - client tc url 319 | * $pageurl - client page url 320 | 321 | Shell-style redirects can be specified in `exec_push` directive for writing output 322 | and accepting input. Supported are 323 | * truncating output `>file` 324 | * appending output `>>file` 325 | * descriptor redirects like `1>&2` 326 | * input `>/var/log/ffmpeg-$name.log; 345 | } 346 | 347 | application hls { 348 | live on; 349 | hls on; 350 | hls_path /tmp/hls; 351 | hls_fragment 15s; 352 | } 353 | 354 | #### exec_pull 355 | Syntax: `exec_pull command arg*` 356 | Context: rtmp, server, application 357 | 358 | Specifies external command with arguments to be executed on play event. 359 | The command is executed when first client connects to the stream and is 360 | killed when the last one disconnects. This directive makes it possible 361 | to pull remote stream in any format for local clients. 362 | 363 | The feature works reliably only in single-worker mode. The reason for this 364 | is we cannot make sure external process always connects to the right worker. 365 | It will obviously connect to a random one. While this will still work in 366 | most cases it's not a recommended architecture, it will be unstable and buggy. 367 | 368 | Directive arguments are the same as for `exec_push`. 369 | 370 | application myapp { 371 | live on; 372 | exec_pull ffmpeg -i http://example.com/video_$name.ts -c copy -f flv rtmp://localhost/$app/$name; 373 | } 374 | 375 | In the above configuration `exec_pull` directive serves all streams. That leads 376 | to certain limitations on remote stream name format. It should be possible to construct 377 | the remote url using available variables like `$app`, `$name` etc. When it's not possible 378 | you can add `exec_options on` directive which permits setting additional stream options 379 | in exec-family directives. The only option supported now is `name` option. 380 | 381 | application myapp { 382 | live on; 383 | exec_options on; 384 | exec_pull ffmpeg -i http://example.com/tv1.ts -c copy -f flv rtmp://localhost/$app/$name name=mystream; 385 | exec_pull ffmpeg -i http://another.example.com/video_plus.ts -c copy -f flv rtmp://localhost/$app/$name name=anotherstream; 386 | } 387 | 388 | #### exec 389 | Syntax: `exec command arg*` 390 | Context: rtmp, server, application 391 | 392 | `exec` is an alias of `exec_push` 393 | 394 | #### exec_options 395 | Syntax: `exec_options on|off` 396 | Context: rtmp, server, application 397 | 398 | The directive toggles exec options mode. When activated you can 399 | add exec-family directive options. The only exec option supported is `name`. 400 | This option makes it possible to apply exec only to specified stream. 401 | Default if off. 402 | 403 | exec_options on; 404 | # call on_publish only for "mystream" 405 | exec_publish http://localhost/on_publish name=mystream; 406 | 407 | # call on_play only for "another" 408 | exec_play http://localhost/on_play name=another; 409 | 410 | # execute different ffmpeg's for different streams 411 | exec_pull http://example.com/abc.ts -c copy -f flv rtmp://localhost/$name/$app name=mystream; 412 | exec_pull http://my.example.com/tele.ts -c copy -f flv rtmp://localhost/$name/$app name=tv; 413 | exec_pull http://enother.example.com/hello/f.ts -c copy -f flv rtmp://localhost/$name/$app name=fun; 414 | 415 | #### exec_static 416 | Syntax: `exec_static command arg*` 417 | Context: rtmp, server, application 418 | 419 | Similar to `exec` but runs specified command at nginx start. 420 | Does not support substitutions since has no session context. 421 | 422 | exec_static ffmpeg -i http://example.com/video.ts -c copy -f flv rtmp://localhost/myapp/mystream; 423 | 424 | #### exec_kill_signal 425 | Syntax: `exec_kill_signal signal` 426 | Context: rtmp, server, application 427 | 428 | Sets process termination signal. Default is kill (SIGKILL). 429 | You can specify numeric or symbolic name (for POSIX.1-1990 signals). 430 | 431 | exec_kill_signal term; 432 | exec_kill_signal usr1; 433 | exec_kill_signal 3; 434 | 435 | #### respawn 436 | Syntax: `respawn on|off` 437 | Context: rtmp, server, application 438 | 439 | If turned on respawns child process when it's terminated while publishing 440 | is still on. Default is on; 441 | 442 | respawn off; 443 | 444 | #### respawn_timeout 445 | Syntax: `respawn_timeout timeout` 446 | Context: rtmp, server, application 447 | 448 | Sets respawn timeout to wait before starting new child instance. 449 | Default is 5 seconds. 450 | 451 | respawn_timeout 10s; 452 | 453 | #### exec_publish 454 | Syntax: `exec_publish command arg*` 455 | Context: rtmp, server, application 456 | 457 | Specifies external command with arguments to be executed on 458 | publish event. Return code is not analyzed. Substitutions of `exec` 459 | are supported here as well. In addition `args` variable is supported 460 | holding query string arguments. 461 | 462 | #### exec_play 463 | Syntax: `exec_play command arg*` 464 | Context: rtmp, server, application 465 | 466 | Specifies external command with arguments to be executed on 467 | play event. Return code is not analyzed. Substitution list 468 | is the same as for `exec_publish`. 469 | 470 | #### exec_play_done 471 | Syntax: `exec_play_done command arg*` 472 | Context: rtmp, server, application 473 | 474 | Specifies external command with arguments to be executed on 475 | play_done event. Return code is not analyzed. Substitution list 476 | is the same as for `exec_publish`. 477 | 478 | #### exec_publish_done 479 | Syntax: `exec_publish_done command arg*` 480 | Context: rtmp, server, application 481 | 482 | Specifies external command with arguments to be executed on 483 | publish_done event. Return code is not analyzed. Substitution list 484 | is the same as for `exec_publish`. 485 | 486 | #### exec_record_done 487 | Syntax: `exec_record_done command arg*` 488 | Context: rtmp, server, application, recorder 489 | 490 | Specifies external command with arguments to be executed when 491 | recording is finished. Substitution of `exec_publish` are supported here 492 | as well as additional variables 493 | * `recorder` - recorder name 494 | * `path` - recorded file path (`/tmp/rec/mystream-1389499351.flv`) 495 | * `filename` - path with directory omitted (`mystream-1389499351.flv`) 496 | * `basename` - file name with extension omitted (`mystream-1389499351`) 497 | * `dirname` - directory path (`/tmp/rec`) 498 | 499 | Examples 500 | 501 | # track client info 502 | exec_play bash -c "echo $addr $pageurl >> /tmp/clients"; 503 | exec_publish bash -c "echo $addr $flashver >> /tmp/publishers"; 504 | 505 | # convert recorded file to mp4 format 506 | exec_record_done ffmpeg -y -i $path -acodec libmp3lame -ar 44100 -ac 1 -vcodec libx264 $dirname/$basename.mp4; 507 | 508 | ## ngx_rtmp_live_module 509 | 510 | #### live 511 | Syntax: `live on|off` 512 | Context: rtmp, server, application 513 | 514 | 控制 live 模式的开关, live 模式即为一对多广播.默认为off. 515 | 516 | live on; 517 | 518 | #### meta 519 | Syntax: `meta on|copy|off` 520 | Context: rtmp, server, application 521 | 522 | 设置发送 metadata 的模式,一共有三种模式: 523 | * on: 该模式下,发送给订阅者的 metadata 并非原始 metadata,而是由服务端按照内部预定义的字段,例如宽度高度等,重新组装的 metadata。 524 | * copy: 该模式下,发送给订阅者的 metadata 就是发布者发布的 metadata。 525 | * off: 该模式下,不向订阅者发送 metadata。 526 | 527 | 默认模式为 on, 即向订阅者发送按照预定义字段重新组装生成的 metadata。 528 | 529 | meta copy; 530 | 531 | 注:回调为 ngx_rtmp_codec_meta_data。ffmpeg 推流时,对应的 amf 指令为 @setDataFrame。 532 | 533 | #### interleave 534 | Syntax: `interleave on|off` 535 | Context: rtmp, server, application 536 | 537 | 该指令控制 interleave 模式的开关。当打开 interleave 模式时,视频和音频数据在同一个 RTMP chunk stream 中传输。当关闭时,在两个不同 538 | 的 RTMP chunk stream 中传输,其中,音频数据的 chunk stream id 为6(NGX_RTMP_CSID_AUDIO),视频数据的 chunk stream id 为7(NGX_RTMP_CSID_VIDEO)。默认关闭,即音视频数据在不同的 chunk stream 中传输。 539 | 540 | interleave on; 541 | 542 | #### wait_key 543 | Syntax: `wait_key on|off` 544 | Context: rtmp, server, application 545 | 546 | 当 `wait_key` 开启后,使得订阅者接收到的视频数据都以一个关键帧开始。该功能默认关闭。 547 | *注意*:虽然官方文档里说`wait_key`功能默认关闭,但实际上,在代码里该功能是默认打开的。 548 | 算是一个 bug. 549 | 550 | wait_key on; 551 | 552 | #### wait_video 553 | Syntax: `wait_video on|off` 554 | Context: rtmp, server, application 555 | 556 | 如果 `wait_video` 开关打开之后,在第一个视频帧发送之前,不会向订阅者发送音频帧。 557 | 默认关闭。可以和 `wait_key` 指令配合使用,使得订阅者接收的音视频数据以一个视频关键帧开 558 | 始。但这种做法通常会增加连接延时,这个问题可以通过在编码侧调整视频关键帧间隙大小来解决。 559 | 新版本的 IE 在回放时,需要开启此功能。 560 | 561 | wait_video on; 562 | 563 | #### publish_notify 564 | Syntax: `publish_notify on|off` 565 | Context: rtmp, server, application 566 | 567 | 当 `publish_notify` 开关打开时,会向订阅者发送 `NetStream.Play.PublishNotify` 568 | 和 `NetStream.Play.UnpublishNotify` 状态。本开关默认关闭。 569 | 570 | publish_notify on; 571 | 572 | #### drop_idle_publisher 573 | Syntax: `drop_idle_publisher timeout` 574 | Context: rtmp, server, application 575 | 576 | 本指令设置了一个超时时间,当发布者与服务器的连接处于 publish 模式下,闲置的时间超过这 577 | 个时间后,服务器会关闭该连接。该功能默认关闭。所谓闲置是指没有音视频数据传输, 578 | 所谓publish 模式,当发布者发送完 `publish` 指令后即为 publish 模式。 579 | 580 | drop_idle_publisher 10s; 581 | 582 | #### sync 583 | Syntax: `sync timeout` 584 | Context: rtmp, server, application 585 | 586 | 如果订阅者带宽不够,一些帧会被服务器丢弃,这将导致同步的问题,sync 指令针对该情况对 587 | 音视频流进行同步操作。如果时间戳的差异超过了 sync 指令配置的值,服务器会向订阅者发送 588 | 一个绝对帧来解决该问题。该指令配置的默认值为 300ms. 589 | 590 | sync 10ms; 591 | 592 | #### play_restart 593 | Syntax: `play_restart on|off` 594 | Context: rtmp, server, application 595 | 596 | If enabled nginx-rtmp sends NetStream.Play.Start and NetStream.Play.Stop 597 | to each subscriber every time publisher starts or stops publishing. If disabled 598 | each subscriber receives those notifications only at the start and end of 599 | playback. Default is off. 600 | 601 | play_restart off; 602 | 603 | #### idle_streams 604 | Syntax: `idle_streams on|off` 605 | Context: rtmp, server, application 606 | 607 | 指令所属模块:ngx_rtmp_live_module. 608 | 609 | 指令功能: 610 | 当设置为 off 的时候: 611 | * nginx-rtmp 服务器会阻止订阅者连接到空闲或不存在(idle/nonexistent)的直播流 612 | * 当发布者断开与 nginx-rtmp 服务器的连接时,nginx-rtmp 服务器会断开所有订阅者的连接 613 | 614 | 默认值: on 615 | 616 | idle_streams off; 617 | 618 | ## Record 619 | 620 | #### record 621 | syntax: `record [off|all|audio|video|keyframes|manual]*` 622 | context: rtmp, server, application, recorder 623 | 624 | Toggles record mode. Stream can be recorded in flv file. This directive 625 | specifies what exactly should be recorded: 626 | * off - no recording at all 627 | * all - audio & video (everything) 628 | * audio - audio 629 | * video - video 630 | * keyframes - only key video frames 631 | * manual - never start recorder automatically, use control interface to start/stop 632 | 633 | There can be any compatible combination of keys in a single record directive. 634 | 635 | 636 | record all; 637 | 638 | record audio keyframes; 639 | 640 | #### record_path 641 | syntax: `record_path path` 642 | context: rtmp, server, application, recorder 643 | 644 | Specifies record path to put recorded flv files to. 645 | 646 | record_path /tmp/rec; 647 | 648 | #### record_suffix 649 | syntax: `record_suffix value` 650 | context: rtmp, server, application, recorder 651 | 652 | Sets record file suffix. Defaults to '.flv'. 653 | 654 | record_suffix _recorded.flv; 655 | 656 | Record suffix can be a pattern in `strftime` format. 657 | The following directive 658 | 659 | record_suffix -%d-%b-%y-%T.flv; 660 | 661 | will produce files of the form `mystream-24-Apr-13-18:23:38.flv`. 662 | All supported `strftime` format options can be found on 663 | [strftime man page](http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html). 664 | 665 | #### record_unique 666 | syntax: `record_unique on|off` 667 | context: rtmp, server, application, recorder 668 | 669 | If turned on appends current timestamp to recorded files. Otherwise the same file 670 | is re-written each time new recording takes place. Default is off. 671 | 672 | record_unique on; 673 | 674 | #### record_append 675 | syntax: `record_append on|off` 676 | context: rtmp, server, application, recorder 677 | 678 | Toggles file append mode. When turned on recorder appends new data to the old file 679 | or creates it when it's missing. There's no time gap between the old data and the new 680 | data in file. Default is off. 681 | 682 | record_append on; 683 | 684 | #### record_lock 685 | syntax: `record_lock on|off` 686 | context: rtmp, server, application, recorder 687 | 688 | When turned on currently recorded file gets locked with `fcntl` call. 689 | That can be checked from elsewhere to find out which file is being recorded. 690 | Default is off. 691 | 692 | record_lock on; 693 | 694 | On FreeBSD you can use `flock` tool to check that. On Linux `flock` and `fcntl` 695 | are unrelated so you are left with writing a simple script checking file lock status. 696 | Here's an example of such script `isunlocked.py`. 697 | 698 | #!/usr/bin/python 699 | 700 | import fcntl, sys 701 | 702 | sys.stderr.close() 703 | fcntl.lockf(open(sys.argv[1], "a"), fcntl.LOCK_EX|fcntl.LOCK_NB) 704 | 705 | #### record_max_size 706 | syntax: `record_max_size size` 707 | context: rtmp, server, application, recorder 708 | 709 | Set maximum recorded file size. 710 | 711 | record_max_size 128K; 712 | 713 | #### record_max_frames 714 | syntax: `record_max_frames nframes` 715 | context: rtmp, server, application, recorder 716 | 717 | Sets maximum number of video frames per recorded file. 718 | 719 | record_max_frames 2; 720 | 721 | #### record_interval 722 | syntax: `record_interval time` 723 | context: rtmp, server, application, recorder 724 | 725 | Restart recording after this number of (milli)seconds. 726 | Off by default. Zero means no delay between recordings. If 727 | record_unique is off then all record fragments are written to the 728 | same file. Otherwise timestamp is appended which makes files 729 | differ (given record_interval is longer than 1 second). 730 | 731 | record_interval 1s; 732 | 733 | record_interval 15m; 734 | 735 | #### recorder 736 | syntax: `recorder name {...}` 737 | context: application 738 | 739 | Create recorder block. Multiple recorders can be created withing 740 | single application. All the above mentioned recording-related 741 | directives can be specified in `recorder{}` block. All settings 742 | are inherited from higher levels. 743 | 744 | application { 745 | live on; 746 | 747 | # default recorder 748 | record all; 749 | record_path /var/rec; 750 | 751 | recorder audio { 752 | record audio; 753 | record_suffix .audio.flv; 754 | } 755 | 756 | recorder chunked { 757 | record all; 758 | record_interval 15s; 759 | record_path /var/rec/chunked; 760 | } 761 | } 762 | 763 | #### record_notify 764 | syntax: `record_notify on|off` 765 | context: rtmp, server, application, recorder 766 | 767 | Toggles sending NetStream.Record.Start and NetStream.Record.Stop 768 | status messages (onStatus) to publisher when specific recorder 769 | starts or stops recording file. Status description field holds 770 | recorder name (empty for default recorder). Off by default. 771 | 772 | recorder myrec { 773 | record all manual; 774 | record_path /var/rec; 775 | record_notify on; 776 | } 777 | 778 | ## Video on demand 779 | 780 | #### play 781 | Syntax: `play dir|http://loc [dir|http://loc]*` 782 | Context: rtmp, server, application 783 | 784 | Play flv or mp4 file from specified directory or HTTP location. 785 | If the argument is prefixed with `http://` then it is assumed 786 | that file should be downloaded from remote http location before 787 | playing. Note playing is not started until the whole file is 788 | downloaded. You can use local nginx to cache files on local machine. 789 | 790 | Multiple play locations can be specified in a single `play` directive. 791 | When multiple `play` directives are specified the location lists 792 | are merged and inherited from higher scopes. An attempt to play 793 | each location is made until a successful location is found. 794 | If such location is not found error status is sent to client. 795 | 796 | Indexed FLVs are played with random seek capability. 797 | Unindexed FLVs are played with seek/pause disabled 798 | (restart-only mode). Use FLV indexer (for example, yamdi) 799 | for indexing. 800 | 801 | If you play FLVs recorded with the `record` directive please do not 802 | forget to index them before playing. They are created unindexed. 803 | 804 | Mp4 files can only be played if both video and audio codec are supported 805 | by RTMP. The most common case is H264/AAC. 806 | 807 | application vod { 808 | play /var/flvs; 809 | } 810 | 811 | application vod_http { 812 | play http://myserver.com/vod; 813 | } 814 | 815 | application vod_mirror { 816 | # try local location first, then access remote location 817 | play /var/local_mirror http://myserver.com/vod; 818 | } 819 | 820 | Playing /var/flvs/dir/file.flv: 821 | 822 | ffplay rtmp://localhost/vod//dir/file.flv 823 | 824 | The two slashes after `vod` make ffplay use `vod` and application name 825 | and the rest of the url as playpath. 826 | 827 | #### play_temp_path 828 | Syntax: `play_temp_path dir` 829 | Context: rtmp, server, application 830 | 831 | Sets location where remote VOD files are stored before playing. 832 | Default is `/tmp`; 833 | 834 | play_temp_path /www; 835 | play http://example.com/videos; 836 | 837 | #### play_local_path 838 | Syntax: `play_local_path dir` 839 | Context: rtmp, server, application 840 | 841 | Sets location where remote VOD files copied from `play_temp_path` 842 | directory after they are completely downloaded. Empty value 843 | disables the feature. By default it's empty. The feature can be used 844 | for caching remote files locally. 845 | 846 | This path should be on the same device as `play_temp_path`. 847 | 848 | # search file in /tmp/videos. 849 | # if not found play from remote location 850 | # and store in /tmp/videos 851 | 852 | play_local_path /tmp/videos; 853 | play /tmp/videos http://example.com/videos; 854 | 855 | ## Relay 856 | 857 | #### pull 858 | Syntax: `pull url [key=value]*` 859 | Context: application 860 | 861 | Creates pull relay. Stream is pulled from remote machine 862 | and becomes available locally. It only happens when at least 863 | one player is playing the stream locally. 864 | 865 | Url syntax: `[rtmp://]host[:port][/app[/playpath]]`. If application 866 | is missing then local application name is used. If playpath is missing 867 | then current stream name is used instead. 868 | 869 | The following parameters are supported: 870 | * app - explicit application name 871 | * name - local stream name to bind relay to; if empty or non-specified then 872 | all local streams within application are pulled 873 | * tcUrl - auto-constructed if empty 874 | * pageUrl - page url to pretend 875 | * swfUrl - swf url to pretend 876 | * flashVer - flash version to pretend, default is 'LNX.11,1,102,55' 877 | * playPath - remote play path 878 | * live - toggles special behavior for live streaming, values: 0,1 879 | * start - start time in seconds 880 | * stop - stop time in seconds 881 | * static - makes pull static, such pull is created at nginx start 882 | 883 | If a value for a parameter contains spaces then you should use quotes around 884 | the **WHOLE** key=value pair like this : `'pageUrl=FAKE PAGE URL'`. 885 | 886 | pull rtmp://cdn.example.com/main/ch?id=12563 name=channel_a; 887 | 888 | pull rtmp://cdn2.example.com/another/a?b=1&c=d pageUrl=http://www.example.com/video.html swfUrl=http://www.example.com/player.swf live=1; 889 | 890 | pull rtmp://cdn.example.com/main/ch?id=12563 name=channel_a static; 891 | 892 | #### push 893 | Syntax: `push url [key=value]*` 894 | Context: application 895 | 896 | Push has the same syntax as pull. Unlike pull push directive publishes stream to remote server. 897 | 898 | #### push_reconnect 899 | Syntax: `push_reconnect time` 900 | Context: rtmp, server, application 901 | 902 | Timeout to wait before reconnecting pushed connection after disconnect. Default is 3 seconds. 903 | 904 | push_reconnect 1s; 905 | 906 | #### session_relay 907 | Syntax: `session_relay on|off` 908 | Context: rtmp, server, application 909 | 910 | Toggles session relay mode. In this mode relay is destroyed when connection is closed. 911 | When the setting is off relay is destroyed when stream is closed so that another relay 912 | could possibly be created later. Default is off. 913 | 914 | session_relay on; 915 | 916 | ## Notify 917 | 918 | #### on_connect 919 | Syntax: `on_connect url` 920 | Context: rtmp, server 921 | 922 | Sets HTTP connection callback. When clients issues connect command 923 | an HTTP request is issued asynchronously and command processing is 924 | suspended until it returns result code. If HTTP 2xx code is returned 925 | then RTMP session continues. The code of 3xx makes RTMP redirect 926 | to another application whose name is taken from `Location` HTTP 927 | response header. Otherwise connection is dropped. 928 | 929 | Note this directive is not allowed in application scope since 930 | application is still unknown at connection stage. 931 | 932 | HTTP request receives a number of arguments. POST method is used with 933 | application/x-www-form-urlencoded MIME type. The following arguments are 934 | passed to caller: 935 | * call=connect 936 | * addr - client IP address 937 | * app - application name 938 | * flashVer - client flash version 939 | * swfUrl - client swf url 940 | * tcUrl - tcUrl 941 | * pageUrl - client page url 942 | 943 | In addition to the above mentioned items all arguments passed explicitly to 944 | connect command are also sent with the callback. You should distinguish 945 | connect arguments from play/publish arguments. Players usually have a special 946 | way of setting connection string separate from play/publish stream name. 947 | As an example here's how these arguments are set in JWPlayer 948 | 949 | ... 950 | streamer: "rtmp://localhost/myapp?connarg1=a&connarg2=b", 951 | file: "mystream?strarg1=c&strarg2=d", 952 | ... 953 | 954 | Ffplay (with librtmp) example 955 | 956 | ffplay "rtmp://localhost app=myapp?connarg1=a&connarg2=b playpath=mystream?strarg1=c&strarg2=d" 957 | 958 | Usage example 959 | 960 | on_connect http://example.com/my_auth; 961 | 962 | Redirect example 963 | 964 | location /on_connect { 965 | if ($arg_flashver != "my_secret_flashver") { 966 | rewrite ^.*$ fallback? permanent; 967 | } 968 | return 200; 969 | } 970 | 971 | #### on_play 972 | Syntax: `on_play url` 973 | Context: rtmp, server, application 974 | 975 | Sets HTTP play callback. Each time a clients issues play command 976 | an HTTP request is issued asynchronously and command processing is 977 | suspended until it returns result code. HTTP result code is then 978 | analyzed. 979 | 980 | * HTTP 2xx code continues RTMP session 981 | * HTTP 3xx redirects RTMP to another stream whose name is taken from 982 | `Location` HTTP response header. If new stream name is started with `rtmp://` 983 | then remote relay is created instead. Relays require that IP address is 984 | specified instead of domain name and only work with nginx versions 985 | greater than 1.3.10. See also `notify_relay_redirect`. 986 | * Otherwise RTMP connection is dropped 987 | 988 | Redirect example 989 | 990 | http { 991 | ... 992 | location /local_redirect { 993 | rewrite ^.*$ newname? permanent; 994 | } 995 | location /remote_redirect { 996 | # no domain name here, only ip 997 | rewrite ^.*$ rtmp://192.168.1.123/someapp/somename? permanent; 998 | } 999 | ... 1000 | } 1001 | 1002 | rtmp { 1003 | ... 1004 | application myapp1 { 1005 | live on; 1006 | # stream will be redirected to 'newname' 1007 | on_play http://localhost:8080/local_redirect; 1008 | } 1009 | application myapp2 { 1010 | live on; 1011 | # stream will be pulled from remote location 1012 | # requires nginx >= 1.3.10 1013 | on_play http://localhost:8080/remote_redirect; 1014 | } 1015 | ... 1016 | } 1017 | 1018 | HTTP request receives a number of arguments. POST method is used with 1019 | application/x-www-form-urlencoded MIME type. The following arguments are 1020 | passed to caller: 1021 | * call=play 1022 | * addr - client IP address 1023 | * clientid - nginx client id (displayed in log and stat) 1024 | * app - application name 1025 | * flashVer - client flash version 1026 | * swfUrl - client swf url 1027 | * tcUrl - tcUrl 1028 | * pageUrl - client page url 1029 | * name - stream name 1030 | 1031 | In addition to the above mentioned items all arguments passed explicitly to 1032 | play command are also sent with the callback. For example if stream is 1033 | accessed with the url `rtmp://localhost/app/movie?a=100&b=face&foo=bar` then 1034 | `a`, `b` & `foo` are also sent with callback. 1035 | 1036 | on_play http://example.com/my_callback; 1037 | 1038 | #### on_publish 1039 | Syntax: `on_publish url` 1040 | Context: rtmp, server, application 1041 | 1042 | The same as on_play above with the only difference that this directive sets 1043 | callback on publish command. Instead of remote pull push is performed in 1044 | this case. 1045 | 1046 | #### on_done 1047 | Syntax: `on_done url` 1048 | Context: rtmp, server, application 1049 | 1050 | Sets play/publish terminate callback. All the above applies here. However 1051 | HTTP status code is not checked for this callback. 1052 | 1053 | #### on_play_done 1054 | Syntax: `on_play_done url` 1055 | Context: rtmp, server, application 1056 | 1057 | Same behavior as `on_done` but only for play end event. 1058 | 1059 | #### on_publish_done 1060 | Syntax: `on_publish_done url` 1061 | Context: rtmp, server, application 1062 | 1063 | Same behavior as `on_done` but only for publish end event. 1064 | 1065 | #### on_record_done 1066 | syntax: `on_record_done url` 1067 | context: rtmp, server, application, recorder 1068 | 1069 | Set record_done callback. In addition to common HTTP callback 1070 | variables it receives the following values 1071 | * recorder - recorder name in config or empty string for inline recorder 1072 | * path - recorded file path 1073 | 1074 | Example 1075 | 1076 | on_record_done http://example.com/recorded; 1077 | 1078 | #### on_update 1079 | syntax: `on_update url` 1080 | context: rtmp, server, application 1081 | 1082 | Set update callback. This callback is called with period of 1083 | `notify_update_timeout`. If a request returns HTTP result other 1084 | than 2xx connection is terminated. This can be used to synchronize 1085 | expired sessions. Two additional arguments `time` and `timestamp` 1086 | are passed to this handler: 1087 | * `time` is the number of seconds since play/publish call 1088 | * `timestamp` is RTMP timestamp of the last audio/video packet sent to the client 1089 | 1090 | You can use `timestamp` argument to individually limit playback duration 1091 | for each user. 1092 | 1093 | on_update http://example.com/update; 1094 | 1095 | #### notify_update_timeout 1096 | syntax: `notify_update_timeout timeout` 1097 | context: rtmp, server, application 1098 | 1099 | Sets timeout between `on_update` callbacks. Default is 30 seconds. 1100 | 1101 | notify_update_timeout 10s; 1102 | on_update http://example.com/update; 1103 | 1104 | #### notify_update_strict 1105 | syntax: `notify_update_strict on|off` 1106 | context: rtmp, server, application 1107 | 1108 | Toggles strict mode for `on_update` callbacks. Default is off. 1109 | When turned on all connection errors, timeouts as well as HTTP parse 1110 | errors and empty responses are treated as update failures and lead 1111 | to connection termination. When off only valid HTTP response codes 1112 | other that 2xx lead to failure. 1113 | 1114 | notify_update_strict on; 1115 | on_update http://example.com/update; 1116 | 1117 | #### notify_relay_redirect 1118 | syntax: `notify_relay_redirect on|off` 1119 | context: rtmp, server, application 1120 | 1121 | Enables local stream redirect for `on_play` and `on_publish` remote 1122 | redirects. New stream name is MD5 hash of RTMP URL used for remote redirect. 1123 | Default is off. 1124 | 1125 | notify_relay_redirect on; 1126 | 1127 | #### notify_method 1128 | syntax: `notify_method get|post` 1129 | context: rtmp, server, application, recorder 1130 | 1131 | Sets HTTP method for notifications. Default is POST with 1132 | `application/x-www-form-urlencoded` content type. In certain cases 1133 | GET is preferable, for example if you plan to handle the call 1134 | in `http{}` section of nginx. In this case you can use `arg_*` variables 1135 | to access arguments. 1136 | 1137 | notify_method get; 1138 | 1139 | With GET method handling notifications in `http{}` section can be done this way 1140 | 1141 | location /on_play { 1142 | if ($arg_pageUrl ~* localhost) { 1143 | return 200; 1144 | } 1145 | return 500; 1146 | } 1147 | 1148 | ## HLS 1149 | 1150 | #### hls 1151 | Syntax: `hls on|off` 1152 | Context: rtmp, server, application 1153 | 1154 | Toggles HLS on the application. 1155 | 1156 | hls on; 1157 | hls_path /tmp/hls; 1158 | hls_fragment 15s; 1159 | 1160 | In `http{}` section set up the following location for clients to play HLS. 1161 | 1162 | http { 1163 | ... 1164 | server { 1165 | ... 1166 | location /hls { 1167 | types { 1168 | application/vnd.apple.mpegurl m3u8; 1169 | } 1170 | root /tmp; 1171 | add_header Cache-Control no-cache; 1172 | 1173 | # To avoid issues with cross-domain HTTP requests (e.g. during development) 1174 | add_header Access-Control-Allow-Origin *; 1175 | } 1176 | } 1177 | } 1178 | 1179 | #### hls_path 1180 | Syntax: `hls_path path` 1181 | Context: rtmp, server, application 1182 | 1183 | Sets HLS playlist and fragment directory. If the directory does not 1184 | exist it will be created. 1185 | 1186 | #### hls_fragment 1187 | Syntax: `hls_fragment time` 1188 | Context: rtmp, server, application 1189 | 1190 | Sets HLS fragment length. Defaults to 5 seconds. 1191 | 1192 | #### hls_playlist_length 1193 | Syntax: `hls_playlist_length time` 1194 | Context: rtmp, server, application 1195 | 1196 | Sets HLS playlist length. Defaults to 30 seconds. 1197 | 1198 | hls_playlist_length 10m; 1199 | 1200 | #### hls_sync 1201 | Syntax: `hls_sync time` 1202 | Context: rtmp, server, application 1203 | 1204 | Sets HLS timestamp synchronization threshold. Default is 2ms. 1205 | This feature prevents crackling noises after conversion 1206 | from low-resolution RTMP (1KHz) to high-resolution MPEG-TS (90KHz). 1207 | 1208 | hls_sync 100ms; 1209 | 1210 | #### hls_continuous 1211 | Syntax: `hls_continuous on|off` 1212 | Context: rtmp, server, application 1213 | 1214 | Toggles HLS continuous mode. In this mode HLS sequence number 1215 | is started from where it stopped last time. Old fragments are 1216 | keeped. Default is off. 1217 | 1218 | hls_continuous on; 1219 | 1220 | #### hls_nested 1221 | Syntax: `hls_nested on|off` 1222 | Context: rtmp, server, application 1223 | 1224 | Toggles HLS nested mode. In this mode a subdirectory 1225 | of `hls_path` is created for each stream. Playlist 1226 | and fragments are created in that subdirectory. 1227 | Default is off. 1228 | 1229 | hls_nested on; 1230 | 1231 | #### hls_base_url 1232 | Syntax: `hls_base_url url` 1233 | Context: rtmp, server, application 1234 | 1235 | Sets base url for HLS playlist items. When empty those 1236 | items have no prefix and assumed to be at the same location 1237 | as parent playlist or one level lower when `hls_nested` is 1238 | used. This feature applies both to master (variant) and slave 1239 | HLS playlists. It can let you download the playlist and play it 1240 | locally since it contains full references to child playlists or 1241 | fragments. Empty by default. 1242 | 1243 | hls_base_url http://myserver.com/hls/; 1244 | 1245 | #### hls_cleanup 1246 | Syntax: `hls_cleanup on|off` 1247 | Context: rtmp, server, application 1248 | 1249 | Toggles HLS cleanup. By default the feature is on. 1250 | In this mode nginx cache manager process removes old 1251 | HLS fragments and playlists from HLS directory. 1252 | 1253 | hls_cleanup off; 1254 | 1255 | #### hls_fragment_naming 1256 | Syntax: `hls_fragment_naming sequential|timestamp|system` 1257 | Context: rtmp, server, application 1258 | 1259 | Sets fragment naming mode. 1260 | * sequential - use increasing integers 1261 | * timestamp - use stream timestamp 1262 | * system - use system time 1263 | 1264 | Default is sequential. 1265 | 1266 | hls_fragment_naming system; 1267 | 1268 | ### hls_fragment_naming_granularity 1269 | Syntax: `hls_fragment_naming_granularity number` 1270 | Context: rtmp, server, application 1271 | 1272 | Sets granularity for hls fragment ids. If above zero, changes ids 1273 | to divide the provided value. Default is zero. 1274 | 1275 | # use system time rounded to 500ms as fragment names 1276 | hls_fragment_naming system; 1277 | hls_fragment_naming_granularity 500; 1278 | 1279 | 1280 | #### hls_fragment_slicing 1281 | Syntax: `hls_fragment_slicing plain|aligned` 1282 | Context: rtmp, server, application 1283 | 1284 | Sets fragment slicing mode. 1285 | * plain - switch fragment when target duration is reached 1286 | * aligned - switch fragment when incoming timestamp is a multiple of fragment duration. This mode makes it possible to generate identical fragments on different nginx instances 1287 | 1288 | Default is plain. 1289 | 1290 | hls_fragment_slicing aligned; 1291 | 1292 | #### hls_variant 1293 | Syntax: `hls_variant suffix [param*]` 1294 | Context: rtmp, server, application 1295 | 1296 | Adds HLS variant entry. When suffix is matched on stream name 1297 | then variant playlist is created for the current stream with all 1298 | entries specified by `hls_variant` directives in current application. 1299 | Stripped name without suffix is used as variant stream name. The original 1300 | stream is processed as usual. 1301 | 1302 | Optional parameters following the suffix are appended to `EXT-X-STREAM-INF` in 1303 | m3u8 playlist. See HLS spec. 3.3.10. EXT-X-STREAM-INF for the full list of supported 1304 | parameters. 1305 | 1306 | rtmp { 1307 | server { 1308 | listen 1935; 1309 | 1310 | application src { 1311 | live on; 1312 | 1313 | exec ffmpeg -i rtmp://localhost/src/$name 1314 | -c:a libfdk_aac -b:a 32k -c:v libx264 -b:v 128K -f flv rtmp://localhost/hls/$name_low 1315 | -c:a libfdk_aac -b:a 64k -c:v libx264 -b:v 256k -f flv rtmp://localhost/hls/$name_mid 1316 | -c:a libfdk_aac -b:a 128k -c:v libx264 -b:v 512K -f flv rtmp://localhost/hls/$name_hi; 1317 | } 1318 | 1319 | application hls { 1320 | live on; 1321 | 1322 | hls on; 1323 | hls_path /tmp/hls; 1324 | hls_nested on; 1325 | 1326 | hls_variant _low BANDWIDTH=160000; 1327 | hls_variant _mid BANDWIDTH=320000; 1328 | hls_variant _hi BANDWIDTH=640000; 1329 | } 1330 | } 1331 | } 1332 | 1333 | #### hls_type 1334 | Syntax: `hls_type live|event` 1335 | Context: rtmp, server, application 1336 | 1337 | Sets HLS playlist type specified in `X-PLAYLIST-TYPE` playlist directive. 1338 | Live HLS stream is usually played from the current live position which is 1339 | several fragments to the end of playlist. Event HLS stream is always played 1340 | from the start of playlist. When in `event` mode make sure playlist length 1341 | is enough for the whole event. Default is `live`; 1342 | 1343 | hls_type event; 1344 | 1345 | #### hls_keys 1346 | Syntax: `hls_keys on|off` 1347 | Context: rtmp, server, application 1348 | 1349 | Enables HLS encryption. AES-128 method is used to encrypt the whole HLS fragments. 1350 | Off by default. 1351 | 1352 | hls_keys on; 1353 | 1354 | Here's the example configuration using the HLS encryption. This configuration 1355 | requires that nginx is built with `--with-http_ssl_module` for https support. 1356 | 1357 | ... 1358 | 1359 | http { 1360 | ... 1361 | server { 1362 | listen 443 ssl; 1363 | server_name example.com; 1364 | 1365 | ssl_certificate /var/ssl/example.com.cert; 1366 | ssl_certificate_key /var/ssl/example.com.key; 1367 | 1368 | location /keys { 1369 | root /tmp; 1370 | } 1371 | } 1372 | 1373 | server { 1374 | listen 80; 1375 | server_name example.com; 1376 | 1377 | location /hls { 1378 | root /tmp; 1379 | } 1380 | } 1381 | } 1382 | 1383 | rtmp { 1384 | server { 1385 | listen 1935; 1386 | 1387 | application myapp { 1388 | live on; 1389 | 1390 | hls on; 1391 | hls_path /tmp/hls; 1392 | 1393 | hls_keys on; 1394 | hls_key_path /tmp/keys; 1395 | hls_key_url https://example.com/keys/; 1396 | hls_fragments_per_key 10; 1397 | } 1398 | } 1399 | } 1400 | 1401 | #### hls_key_path 1402 | Syntax: `hls_key_path path` 1403 | Context: rtmp, server, application 1404 | 1405 | Sets the directory where auto-generated HLS keys are saved. 1406 | Key files have `.key` extension and pseudo-random 16-byte content 1407 | created with the OpenSSL `RAND_bytes()` routine. 1408 | If the directory does not exist it's created in runtime. 1409 | By default, `hls_path` directory is used for key files. 1410 | Remember however you should normally restrict access to key files which 1411 | is easier when these files are stored separately from playlist and fragments. 1412 | 1413 | hls_key_path /tmp/keys; 1414 | 1415 | #### hls_key_url 1416 | Syntax: `hls_key_url url` 1417 | Context: rtmp, server, application 1418 | 1419 | Sets url for HLS key file entries. When empty those 1420 | items have no prefix and keys are assumed to be at the same location 1421 | as the playlist. Empty by default. 1422 | 1423 | hls_key_url https://myserver.com/keys/; 1424 | 1425 | Example playlist entry with the above setting 1426 | 1427 | #EXT-X-KEY:METHOD=AES-128,URI="https://myserver.com/keys/337.key",IV=0x00000000000000000000000000000151 1428 | 1429 | #### hls_fragments_per_key 1430 | Syntax: `hls_fragments_per_key value` 1431 | Context: rtmp, server, application 1432 | 1433 | Sets the number of HLS fragments encrypted with the same key. 1434 | Zero means only one key is created at the publish start 1435 | and all fragments within the session are encrypted with this key. 1436 | Default is zero. 1437 | 1438 | hls_fragments_per_key 10; 1439 | 1440 | ## MPEG-DASH 1441 | 1442 | #### dash 1443 | Syntax: `dash on|off` 1444 | Context: rtmp, server, application 1445 | 1446 | Toggles MPEG-DASH on the application. 1447 | 1448 | dash on; 1449 | dash_path /tmp/dash; 1450 | dash_fragment 15s; 1451 | 1452 | In `http{}` section set up the following location for clients to play MPEG-DASH. 1453 | 1454 | http { 1455 | ... 1456 | server { 1457 | ... 1458 | location /dash { 1459 | root /tmp; 1460 | add_header Cache-Control no-cache; 1461 | 1462 | # To avoid issues with cross-domain HTTP requests (e.g. during development) 1463 | add_header Access-Control-Allow-Origin *; 1464 | } 1465 | } 1466 | } 1467 | 1468 | #### dash_path 1469 | Syntax: `dash_path path` 1470 | Context: rtmp, server, application 1471 | 1472 | Sets MPEG-DASH playlist and fragment directory. If the directory does not 1473 | exists it will be created. 1474 | 1475 | #### dash_fragment 1476 | Syntax: `dash_fragment time` 1477 | Context: rtmp, server, application 1478 | 1479 | Sets MPEG-DASH fragment length. Defaults to 5 seconds. 1480 | 1481 | #### dash_playlist_length 1482 | Syntax: `dash_playlist_length time` 1483 | Context: rtmp, server, application 1484 | 1485 | Sets MPEG-DASH playlist length. Defaults to 30 seconds. 1486 | 1487 | dash_playlist_length 10m; 1488 | 1489 | #### dash_nested 1490 | Syntax: `dash_nested on|off` 1491 | Context: rtmp, server, application 1492 | 1493 | Toggles MPEG-DASH nested mode. In this mode a subdirectory 1494 | of `dash_path` is created for each stream. Playlist 1495 | and fragments are created in that subdirectory. 1496 | Default is off. 1497 | 1498 | dash_nested on; 1499 | 1500 | #### dash_cleanup 1501 | Syntax: `dash_cleanup on|off` 1502 | Context: rtmp, server, application 1503 | 1504 | Toggles MPEG-DASH cleanup. By default the feature is on. 1505 | In this mode nginx cache manager process removes old 1506 | MPEG-DASH fragments and manifests from MPEG-DASH directory. 1507 | Init fragments are deleted after stream manifest is deleted. 1508 | 1509 | dash_cleanup off; 1510 | 1511 | ## Access log 1512 | 1513 | #### access_log 1514 | Syntax: `access_log off|path [format_name]` 1515 | Context: rtmp, server, application 1516 | 1517 | Sets access log parameters. Logging is turned on by default. 1518 | To turn it off use `access_log off` directive. By default access logging 1519 | is done to the same file as HTTP access logger (`logs/access.log`). 1520 | You can specify another log file path in `access_log` directive. 1521 | Second argument is optional. It can be used to specify logging format by name. 1522 | See `log_format` directive for more details about formats. 1523 | 1524 | log_format new '$remote_addr'; 1525 | access_log logs/rtmp_access.log new; 1526 | access_log logs/rtmp_access.log; 1527 | access_log off; 1528 | 1529 | #### log_format 1530 | Syntax: `log_format format_name format` 1531 | Context: rtmp 1532 | 1533 | Creates named log format. Log formats look very much the same as nginx HTTP log 1534 | formats. Several variables are supported within log format: 1535 | * `connection` - connection number 1536 | * `remote_addr` - client address 1537 | * `app` - application name 1538 | * `name` - last stream name 1539 | * `args` - last stream play/publish arguments 1540 | * `flashver` - client flashVer 1541 | * `swfurl` - client swfUrl 1542 | * `tcurl` - client tcUrl 1543 | * `pageurl` - client pageUrl 1544 | * `command` - play/publish commands sent by client: `NONE`, `PLAY`, `PUBLISH`, `PLAY+PUBLISH` 1545 | * `bytes_sent` - number of bytes sent to client 1546 | * `bytes_received` - number of bytes received from client 1547 | * `time_local` - local time at the end of client connection 1548 | * `session_time` - connection duration in seconds 1549 | * `session_readable_time` - connection duration in human-readable format 1550 | * `msec` - current unix timestamp in SEC.MSEC format 1551 | 1552 | Default log format has the name `combined`. Here's the definition of this format 1553 | 1554 | $remote_addr [$time_local] $command "$app" "$name" "$args" - 1555 | $bytes_received $bytes_sent "$pageurl" "$flashver" ($session_readable_time) 1556 | 1557 | ## Limits 1558 | 1559 | #### max_connections 1560 | Syntax: `max_connections number` 1561 | Context: rtmp, server, application 1562 | 1563 | Sets maximum number of connections for rtmp engine. Off by default. 1564 | 1565 | max_connections 100; 1566 | 1567 | ## Statistics 1568 | 1569 | Statistics module is NGINX HTTP module unlike all other modules listed 1570 | here. Hence statistics directives should be located within http{} block. 1571 | 1572 | #### rtmp_stat 1573 | Syntax: `rtmp_stat all` 1574 | Context: http, server, location 1575 | 1576 | Sets RTMP statistics handler to the current HTTP location. RTMP statistics is 1577 | dynamic XML document. To watch this document in browser as XHTML page 1578 | use rtmp_stat_stylesheet directive. 1579 | 1580 | http { 1581 | server { 1582 | location /stat { 1583 | rtmp_stat all; 1584 | rtmp_stat_stylesheet stat.xsl; 1585 | } 1586 | location /stat.xsl { 1587 | root /path/to/stat/xsl/file; 1588 | } 1589 | } 1590 | } 1591 | 1592 | #### rtmp_stat_stylesheet 1593 | Syntax: `rtmp_stat_stylesheet path` 1594 | Context: http, server, location 1595 | 1596 | Adds XML stylesheet reference to statistics XML to make it viewable 1597 | in browser. See rtmp_stat description and example for more information. 1598 | 1599 | ## Multi-worker live streaming 1600 | 1601 | Multi-worker live streaming is implemented through pushing stream 1602 | to remaining nginx workers. 1603 | 1604 | #### rtmp_auto_push 1605 | Syntax: `rtmp_auto_push on|off` 1606 | Context: root 1607 | 1608 | Toggles auto-push (multi-worker live streaming) mode. 1609 | Default is off. 1610 | 1611 | #### rtmp_auto_push_reconnect 1612 | Syntax: `rtmp_auto_push_reconnect timeout` 1613 | Context: root 1614 | 1615 | Sets auto-push reconnect timeout when worker is killed. 1616 | Default is 100 milliseconds. 1617 | 1618 | #### rtmp_socket_dir 1619 | Syntax: `rtmp_socket_dir dir` 1620 | Context: root 1621 | 1622 | Sets directory for UNIX domains sockets used for stream pushing. 1623 | Default is `/tmp`. 1624 | 1625 | rtmp_auto_push on; 1626 | rtmp_auto_push_reconnect 1s; 1627 | rtmp_socket_dir /var/sock; 1628 | 1629 | rtmp { 1630 | server { 1631 | listen 1935; 1632 | application myapp { 1633 | live on; 1634 | } 1635 | } 1636 | } 1637 | 1638 | ## Control 1639 | 1640 | Control module is NGINX HTTP module and should be located within http{} block. 1641 | 1642 | #### rtmp_control 1643 | Syntax: `rtmp_control all` 1644 | Context: http, server, location 1645 | 1646 | Sets RTMP control handler to the current HTTP location. 1647 | 1648 | http { 1649 | server { 1650 | location /control { 1651 | rtmp_control all; 1652 | } 1653 | } 1654 | } 1655 | 1656 | [More details about control module](Control-module) 1657 | -------------------------------------------------------------------------------- /Examples.md: -------------------------------------------------------------------------------- 1 | ### Simple Video-on-Demand 2 | 3 | rtmp { 4 | server { 5 | listen 1935; 6 | application vod { 7 | play /var/flvs; 8 | } 9 | } 10 | } 11 | 12 | ### Simple live broadcast service 13 | 14 | rtmp { 15 | server { 16 | listen 1935; 17 | application live { 18 | live on; 19 | } 20 | } 21 | } 22 | 23 | ### Re-translate remote stream 24 | 25 | rtmp { 26 | server { 27 | listen 1935; 28 | application tv { 29 | live on; 30 | pull rtmp://cdn.example.com:443/programs/main pageUrl=http://www.example.com/index.html name=maintv; 31 | } 32 | } 33 | } 34 | 35 | ### Re-translate remote stream with HLS support 36 | 37 | rtmp { 38 | server { 39 | listen 1935; 40 | application tv { 41 | live on; 42 | 43 | hls on; 44 | hls_path /tmp/tv2; 45 | hls_fragment 15s; 46 | 47 | pull rtmp://tv2.example.com:443/root/new name=tv2; 48 | } 49 | } 50 | } 51 | 52 | http { 53 | server { 54 | listen 80; 55 | location /tv2 { 56 | alias /tmp/tv2; 57 | } 58 | } 59 | } 60 | ### Stream your X screen through RTMP 61 | 62 | ffmpeg -f x11grab -follow_mouse centered -r 25 -s cif -i :0.0 -f flv rtmp://localhost/myapp/screen -------------------------------------------------------------------------------- /Exec-wrapper-in-bash.md: -------------------------------------------------------------------------------- 1 | You can write exec wrapper in any language. However you should pay attention to termination process. When publisher closes the stream all executed processed get terminated. If you specify wrapper in ```exec``` directive instead of real ffmpeg then you might end up with your ffmpeg still alive and orphaned until it times out reading input data. 2 | 3 | The solution is using signal traps. Here's an example of such wrapper in bash. 4 | 5 | #!/bin/bash 6 | 7 | on_die () 8 | { 9 | # kill all children 10 | pkill -KILL -P $$ 11 | } 12 | 13 | trap 'on_die' TERM 14 | ffmpeg -i rtmp://localhost/myapp/$1 -c copy -f flv rtmp://localhost/myapp2/$1 & 15 | wait 16 | 17 | The script registers SIGTERM handler which terminates child ffmpeg. Default signal sent by nginx-rtmp is SIGKILL which cannot be caught. For the above script to behave as expected you need to change exec kill signal with ```exec_kill_signal``` directive. It accept numeric or symbolic signal name (for POSIX.1-1990 signals). Here's example application. 18 | 19 | application myapp { 20 | live on; 21 | 22 | exec /var/scripts/exec_wrapper.sh $name; 23 | exec_kill_signal term; 24 | } 25 | 26 | application myapp2 { 27 | live on; 28 | } 29 | -------------------------------------------------------------------------------- /FAQ.md: -------------------------------------------------------------------------------- 1 | ####RTMP stream is not played normally in IE, stream stops after several seconds. 2 | 3 | Add this directive to fix the problem 4 | 5 | wait_video on; 6 | 7 | ####I use `pull` directive to get stream from remote location. That works for RTMP clients but does not work for HLS. 8 | 9 | Currently HLS clients do not trigger any events. You cannot pull or exec when HLS client connects to server. However you can use static directives `exec_static`, `pull ... static` to pull the stream always. 10 | 11 | ####Seek does not work with flv files recorded by the module. 12 | 13 | To make the files seekable add flv metadata with external software like yamdi, flvmeta or ffmpeg. 14 | 15 | exec_record_done yamdi -i $path -o /var/videos/$basename; 16 | 17 | ####Published stream is missing from stats page after some time and clients fail to connect 18 | 19 | Check if you use multiple workers in nginx (`worker_processes`). In such case you have to enable: 20 | 21 | rtmp_auto_push on; 22 | -------------------------------------------------------------------------------- /Getting-number-of-subscribers.md: -------------------------------------------------------------------------------- 1 | There's an easy way to display number of clients watching the stream. You need to 2 | 3 | Set up statistics page at location `/stat` 4 | 5 | location /stat { 6 | rtmp_stat all; 7 | allow 127.0.0.1; 8 | } 9 | 10 | Create a simple xsl stylesheet `nclients.xsl` extracting number of stream subscribers 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Set up a location returning number of suscribers 26 | 27 | location /nclients { 28 | proxy_pass http://127.0.0.1/stat; 29 | xslt_stylesheet /www/nclients.xsl app='$arg_app' name='$arg_name'; 30 | add_header Refresh "3; $request_uri"; 31 | } 32 | 33 | Use HTTP request `http://myserver.com/nclients?app=myapp&name=mystream` to get the number of stream subscribers. This number will be automatically refreshed every 3 seconds when opened in browser or iframe. -------------------------------------------------------------------------------- /Getting-started-with-nginx-rtmp.md: -------------------------------------------------------------------------------- 1 | ## Download, build and install 2 | 3 | CD to build directory (home) 4 | 5 | cd /usr/build 6 | 7 | Download & unpack latest nginx-rtmp (you can also use http) 8 | 9 | git clone git://github.com/arut/nginx-rtmp-module.git 10 | 11 | Download & unpack nginx (you can also use svn) 12 | 13 | wget http://nginx.org/download/nginx-1.2.4.tar.gz 14 | tar xzf nginx-1.2.4.tar.gz 15 | cd nginx-1.2.4 16 | 17 | Build nginx with nginx-rtmp 18 | 19 | ./configure --add-module=/usr/build/nginx-rtmp-module 20 | make 21 | make install 22 | 23 | For nginx 1.3.4-1.5.0 more options are needed 24 | 25 | ./configure --add-module=/usr/build/nginx-rtmp-module --with-http_ssl_module 26 | make 27 | make install 28 | 29 | ## Set up live streaming 30 | 31 | To set up RTMP support you need to add `rtmp{}` section to `nginx.conf` (can be found in PREFIX/conf/nginx.conf). Stock `nginx.conf` contains only `http{}` section. 32 | 33 | Use this `nginx.conf` instead of stock config: 34 | 35 | #user nobody; 36 | worker_processes 1; 37 | 38 | error_log logs/error.log debug; 39 | 40 | events { 41 | worker_connections 1024; 42 | } 43 | 44 | http { 45 | include mime.types; 46 | default_type application/octet-stream; 47 | 48 | sendfile on; 49 | keepalive_timeout 65; 50 | 51 | server { 52 | listen 8080; 53 | server_name localhost; 54 | 55 | # sample handlers 56 | #location /on_play { 57 | # if ($arg_pageUrl ~* localhost) { 58 | # return 201; 59 | # } 60 | # return 202; 61 | #} 62 | #location /on_publish { 63 | # return 201; 64 | #} 65 | 66 | #location /vod { 67 | # alias /var/myvideos; 68 | #} 69 | 70 | # rtmp stat 71 | location /stat { 72 | rtmp_stat all; 73 | rtmp_stat_stylesheet stat.xsl; 74 | } 75 | location /stat.xsl { 76 | # you can move stat.xsl to a different location 77 | root /usr/build/nginx-rtmp-module; 78 | } 79 | 80 | # rtmp control 81 | location /control { 82 | rtmp_control all; 83 | } 84 | 85 | error_page 500 502 503 504 /50x.html; 86 | location = /50x.html { 87 | root html; 88 | } 89 | } 90 | } 91 | 92 | rtmp { 93 | server { 94 | listen 1935; 95 | ping 30s; 96 | notify_method get; 97 | 98 | application myapp { 99 | live on; 100 | 101 | # sample play/publish handlers 102 | #on_play http://localhost:8080/on_play; 103 | #on_publish http://localhost:8080/on_publish; 104 | 105 | # sample recorder 106 | #recorder rec1 { 107 | # record all; 108 | # record_interval 30s; 109 | # record_path /tmp; 110 | # record_unique on; 111 | #} 112 | 113 | # sample HLS 114 | #hls on; 115 | #hls_path /tmp/hls; 116 | #hls_sync 100ms; 117 | } 118 | 119 | # Video on demand 120 | #application vod { 121 | # play /var/Videos; 122 | #} 123 | 124 | # Video on demand over HTTP 125 | #application vod_http { 126 | # play http://localhost:8080/vod/; 127 | #} 128 | } 129 | } 130 | 131 | ## Statistics 132 | 133 | Navigate your browser to `http://localhost:8080/stat` to see current 134 | streaming statistics, connected clients, bandwidth etc. 135 | 136 | ## Publishing with ffmpeg 137 | 138 | The easiest way to publish live video stream is using ffmpeg (or avconv). 139 | It's already installed on most systems and easy to install on others. 140 | 141 | RTMP supports only a limited number of codecs. The most popular RTMP video 142 | codecs are H264, Sorenson-H263 (aka flv) and audio codecs AAC, MP3, 143 | Nellymoser, Speex. If your video is encoded with these codecs 144 | (the most common pair is H264/AAC) then you do not need any conversion. 145 | Otherwise you need to convert video to one of supported codecs. 146 | 147 | We'll stream test file `/var/videos/test.mp4` to server with ffmpeg. 148 | 149 | Streaming without conversion (given `test.mp4` codecs are compatible with RTMP) 150 | 151 | ffmpeg -re -i /var/Videos/test.mp4 -c copy -f flv rtmp://localhost/myapp/mystream 152 | 153 | Streaming and encoding audio (AAC) and video (H264), need `libx264` and `libfaac` 154 | 155 | ffmpeg -re -i /var/Videos/test.mp4 -c:v libx264 -c:a libfaac -ar 44100 -ac 1 -f flv rtmp://localhost/myapp/mystream 156 | 157 | Streaming and encoding audio (MP3) and video (H264), need `libx264` and `libmp3lame` 158 | 159 | ffmpeg -re -i /var/Videos/test.mp4 -c:v libx264 -c:a libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost/myapp/mystream 160 | 161 | Streaming and encoding audio (Nellymoser) and video (Sorenson H263) 162 | 163 | ffmpeg -re -i /var/Videos/test.mp4 -c:v flv -c:a nellymoser -ar 44100 -ac 1 -f flv rtmp://localhost/myapp/mystream 164 | 165 | ## Publishing video from webcam 166 | 167 | ffmpeg -f video4linux2 -i /dev/video0 -c:v libx264 -an -f flv rtmp://localhost/myapp/mystream 168 | 169 | ## Playing with ffplay 170 | 171 | ffplay rtmp://localhost/myapp/mystream 172 | 173 | ## Publishing and playing with flash 174 | 175 | See `test/rtmp-publisher` directory for test flash applets and html. -------------------------------------------------------------------------------- /Home.md: -------------------------------------------------------------------------------- 1 | Welcome to the nginx-rtmp-module wiki! 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 基于 Nginx 的流媒体服务器 2 | 3 | ## 说明 4 | 5 | 1. nginx-rtmp是一个非常优秀的流媒体系统,arut精湛的编程技艺使得无论是用该项目来学习 6 | 流媒体服务器设计,还是基于其做二次开发,都非常合适。 7 | 2. 由于arut精力早就不在本项目上,所以很遗憾,这个框架有各种这样那样的问题。 8 | 这些问题主要来自这几个方面:(1)大量bug没有修复,当然对于一个服务器软件来说, 9 | 这是很正常的。(2)未完全完成的部分。例如对多进程的支持,其实还有很多工作没有完成, 10 | 导致原框架的多进程在实际中几乎不可用。(3)设计的缺陷。nginx-rtmp中也有一些在设计 11 | 之初,arut就没有考虑到或考虑欠周的情况。所以,一方面国内很多公司基于其做流媒体系统, 12 | 但另一方面,应该没有谁会直接用它来提供服务,都得花大力气去深度完善甚至改造。 13 | 3. 本wiki是nginx-rtmp官方wiki的一个fork,仅是对原框架的说明,会有一些新加的文档。 14 | 但不会涉及到bug的修复和新的功能。 15 | 16 | ## nginx-rtmp 模块 17 | 18 | ### 项目博客 19 | 20 | arut一共维护了两份开发日志: 21 | * http://nginx-rtmp.blogspot.com 22 | * https://rarut.wordpress.com 23 | 24 | arut起先在wordpress.com上面做开发记录,后来迁移到了blogspot.com上,所以,如果不是对 25 | 评论特别感兴趣的话,阅读第一个地址就够了。 26 | 27 | 这里必须要强调一下,arut的这些开发日志有很高的价值,通过这些文章,我们可以了解很多代码 28 | 背后的东西。强烈建议精读几遍。 29 | 30 | ### 配置指令说明 31 | 32 | * 英文: https://github.com/arut/nginx-rtmp-module/wiki/Directives 33 | * 中文: [配置指令集](/Directives.md) 34 | 35 | ### Google 讨论组 36 | 37 | * 英文: https://groups.google.com/group/nginx-rtmp 38 | * 俄文: https://groups.google.com/group/nginx-rtmp-ru 39 | 40 | ### 特性 41 | 42 | * 支持RTMP/HLS/MPEG-DASH直播 43 | 44 | * 支持基于RTMP协议的FLV/MP4点播,既支持本地文件点播,也支持通过http从远程拉取文件做点播 45 | 46 | * 提供基于relay的分布式支持,主要有两种模式:push和pull 47 | 48 | * 支持将直播流录制为flv文件落地到磁盘 49 | 50 | * 支持的编码格式是H264/AAC 51 | 52 | * 支持使用FFmepg做在线转码 53 | 54 | * 提供了HTTP回调支持(publish/play/record/update等) 55 | 56 | * 支持通过事件触发来运行外部程序(exec模块) 57 | 58 | * 支持通过HTTP请求来控制录制、断开客户端的动作 59 | 60 | * 通过精心设计的buffer,使得本系统有着极高的运行效率和极小的内存占用 61 | 62 | * 经过测试的客户端包括Wirecast, FMS, Wowza,JWPlayer, FlowPlayer, StrobeMediaPlayback, 63 | ffmpeg, avconv, rtmpdump, flvstreamer等等 64 | 65 | * 支持通过http请求获取系统内实时的统计数据,统计数据用xml/xsl的形式展现出来 66 | 67 | * 兼容Linux/FreeBSD/MacOS/Windows 68 | 69 | 注意:上面提到的控制和统计功能,分别是用两个http模块来实现的,在多进程的时候这又是 70 | 一个雷区:一个http请求只能落在一个worker进程上面。所以,再次强调,如果不进行二次开发, 71 | 请不要在多进程时使用这两个功能。 72 | 73 | ### 编译 74 | 75 | 跟所有的nginx第三方模块一样,nginx-rtmp通过如下的方式进行编译:在nginx源码目录下执行 76 | 77 | ./configure --add-module=/path/to/nginx-rtmp-module 78 | make 79 | make install 80 | 81 | 为了支持debug模式,在configure的时候带上 `--with-debug`参数 82 | 83 | ./configure --add-module=/path/to-nginx/rtmp-module --with-debug 84 | 85 | ### RTMP url格式 86 | 87 | rtmp://rtmp.example.com/app[/name] 88 | 89 | app - 匹配配置文件中的某个application{}块 90 | 91 | name - 由各程序自行处理和解释,可以为空。一般用它来做流名。 92 | 93 | 94 | ### 多进程支持 95 | 96 | nginx-rtmp通过auto_push功能来实现对多进程的支持。大概方法是,每一个被publish到的worker 97 | 进程,通过unix域套接字将其接收到的流主动publish到其它各个worker进程。这个功能通过 98 | rtmp_auto_push指令来开启。详见ngx_rtmp_auto_push_module模块。 99 | 100 | 注意:已经多次强调,nginx-rtmp的多进程支持并不完全,除非你已经非常熟悉源码并能做相应 101 | 的修改,否则永远不要在生产环境中开启多进程支持。 102 | 103 | ### 配置文件示例-单进程版 104 | 105 | rtmp { 106 | 107 | server { 108 | 109 | listen 1935; 110 | 111 | chunk_size 4000; 112 | 113 | # TV mode: one publisher, many subscribers 114 | application mytv { 115 | 116 | # enable live streaming 117 | live on; 118 | 119 | # record first 1K of stream 120 | record all; 121 | record_path /tmp/av; 122 | record_max_size 1K; 123 | 124 | # append current timestamp to each flv 125 | record_unique on; 126 | 127 | # publish only from localhost 128 | allow publish 127.0.0.1; 129 | deny publish all; 130 | 131 | #allow play all; 132 | } 133 | 134 | # Transcoding (ffmpeg needed) 135 | application big { 136 | live on; 137 | 138 | # On every pusblished stream run this command (ffmpeg) 139 | # with substitutions: $app/${app}, $name/${name} for application & stream name. 140 | # 141 | # This ffmpeg call receives stream from this application & 142 | # reduces the resolution down to 32x32. The stream is the published to 143 | # 'small' application (see below) under the same name. 144 | # 145 | # ffmpeg can do anything with the stream like video/audio 146 | # transcoding, resizing, altering container/codec params etc 147 | # 148 | # Multiple exec lines can be specified. 149 | 150 | exec ffmpeg -re -i rtmp://localhost:1935/$app/$name -vcodec flv -acodec copy -s 32x32 151 | -f flv rtmp://localhost:1935/small/${name}; 152 | } 153 | 154 | application small { 155 | live on; 156 | # Video with reduced resolution comes here from ffmpeg 157 | } 158 | 159 | application webcam { 160 | live on; 161 | 162 | # Stream from local webcam 163 | exec_static ffmpeg -f video4linux2 -i /dev/video0 -c:v libx264 -an 164 | -f flv rtmp://localhost:1935/webcam/mystream; 165 | } 166 | 167 | application mypush { 168 | live on; 169 | 170 | # Every stream published here 171 | # is automatically pushed to 172 | # these two machines 173 | push rtmp1.example.com; 174 | push rtmp2.example.com:1934; 175 | } 176 | 177 | application mypull { 178 | live on; 179 | 180 | # Pull all streams from remote machine 181 | # and play locally 182 | pull rtmp://rtmp3.example.com pageUrl=www.example.com/index.html; 183 | } 184 | 185 | application mystaticpull { 186 | live on; 187 | 188 | # Static pull is started at nginx start 189 | pull rtmp://rtmp4.example.com pageUrl=www.example.com/index.html name=mystream static; 190 | } 191 | 192 | # video on demand 193 | application vod { 194 | play /var/flvs; 195 | } 196 | 197 | application vod2 { 198 | play /var/mp4s; 199 | } 200 | 201 | # Many publishers, many subscribers 202 | # no checks, no recording 203 | application videochat { 204 | 205 | live on; 206 | 207 | # The following notifications receive all 208 | # the session variables as well as 209 | # particular call arguments in HTTP POST 210 | # request 211 | 212 | # Make HTTP request & use HTTP retcode 213 | # to decide whether to allow publishing 214 | # from this connection or not 215 | on_publish http://localhost:8080/publish; 216 | 217 | # Same with playing 218 | on_play http://localhost:8080/play; 219 | 220 | # Publish/play end (repeats on disconnect) 221 | on_done http://localhost:8080/done; 222 | 223 | # All above mentioned notifications receive 224 | # standard connect() arguments as well as 225 | # play/publish ones. If any arguments are sent 226 | # with GET-style syntax to play & publish 227 | # these are also included. 228 | # Example URL: 229 | # rtmp://localhost/myapp/mystream?a=b&c=d 230 | 231 | # record 10 video keyframes (no audio) every 2 minutes 232 | record keyframes; 233 | record_path /tmp/vc; 234 | record_max_frames 10; 235 | record_interval 2m; 236 | 237 | # Async notify about an flv recorded 238 | on_record_done http://localhost:8080/record_done; 239 | 240 | } 241 | 242 | 243 | # HLS 244 | 245 | # For HLS to work please create a directory in tmpfs (/tmp/hls here) 246 | # for the fragments. The directory contents is served via HTTP (see 247 | # http{} section in config) 248 | # 249 | # Incoming stream must be in H264/AAC. For iPhones use baseline H264 250 | # profile (see ffmpeg example). 251 | # This example creates RTMP stream from movie ready for HLS: 252 | # 253 | # ffmpeg -loglevel verbose -re -i movie.avi -vcodec libx264 254 | # -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 255 | # -f flv rtmp://localhost:1935/hls/movie 256 | # 257 | # If you need to transcode live stream use 'exec' feature. 258 | # 259 | application hls { 260 | live on; 261 | hls on; 262 | hls_path /tmp/hls; 263 | } 264 | 265 | # MPEG-DASH is similar to HLS 266 | 267 | application dash { 268 | live on; 269 | dash on; 270 | dash_path /tmp/dash; 271 | } 272 | } 273 | } 274 | 275 | # HTTP can be used for accessing RTMP stats 276 | http { 277 | 278 | server { 279 | 280 | listen 8080; 281 | 282 | # This URL provides RTMP statistics in XML 283 | location /stat { 284 | rtmp_stat all; 285 | 286 | # Use this stylesheet to view XML as web page 287 | # in browser 288 | rtmp_stat_stylesheet stat.xsl; 289 | } 290 | 291 | location /stat.xsl { 292 | # XML stylesheet to view RTMP stats. 293 | # Copy stat.xsl wherever you want 294 | # and put the full directory path here 295 | root /path/to/stat.xsl/; 296 | } 297 | 298 | location /hls { 299 | # Serve HLS fragments 300 | types { 301 | application/vnd.apple.mpegurl m3u8; 302 | video/mp2t ts; 303 | } 304 | root /tmp; 305 | add_header Cache-Control no-cache; 306 | } 307 | 308 | location /dash { 309 | # Serve DASH fragments 310 | root /tmp; 311 | add_header Cache-Control no-cache; 312 | } 313 | } 314 | } 315 | 316 | 317 | ### 配置文件示例-多进程版 318 | 319 | rtmp_auto_push on; 320 | worker_processes 4; 321 | 322 | rtmp { 323 | server { 324 | listen 1935; 325 | 326 | application mytv { 327 | live on; 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /Tutorial.md: -------------------------------------------------------------------------------- 1 | [This article is not finished yet] 2 | 3 | ## RTMP 4 | RTMP is a proprietary protocol developed by Adobe (Macromedia) for use 5 | in flash player. Until 2009 it had no public specification. 6 | A number of third-party RTMP-related products started in that period 7 | were based on the results of reverse engineering. In 2009 8 | [RTMP specification](http://www.adobe.com/devnet/rtmp.html) has been 9 | published which made developing such applications easier. However 10 | the spec is not full and misses significant issues concerning streaming H264. 11 | 12 | ## System requirements 13 | The module has been tested on Linux x86-family platforms. 14 | However it should work on FreeBSD too. 15 | 16 | ## Licence 17 | The module is distributed under BSD license. 18 | 19 | ## Building NGINX with the module 20 | Building is pretty obvious. Just cd to nginx source directory 21 | and configure nginx this way: 22 | 23 | `./configure --add-module=/path/to/nginx-rtmp-module` 24 | 25 | Then `make` and `make install`. 26 | 27 | ## Configuration 28 | 29 | ## Simple live application 30 | Simple live application configuration: 31 | 32 | application live { 33 | 34 | live on; 35 | 36 | } 37 | 38 | You can add access list control: 39 | 40 | application live { 41 | 42 | live on; 43 | 44 | allow publish 127.0.0.1; 45 | deny publish all; 46 | allow play all; 47 | 48 | } 49 | 50 | And you can add record support for live streams: 51 | 52 | application live { 53 | 54 | live on; 55 | 56 | allow publish 127.0.0.1; 57 | deny publish all; 58 | allow play all; 59 | 60 | record all; 61 | record_path /path/to/record/dir; 62 | record_max_size 100M; 63 | record_unique off; 64 | 65 | } 66 | 67 | 68 | ## HLS (HTTP Live Streaming) 69 | 70 | 71 | ## Choosing flash player 72 | To watch RTMP stream in browser one should either develop 73 | flash application for that or use one of available flash 74 | players. The most popular players which are proved to have 75 | no problems with the module are: 76 | 77 | * [JWPlayer](http://www.longtailvideo.com/) 78 | * [FlowPlayer](http://flowplayer.org/) 79 | * [Strobe Media Playback](http://www.osmf.org/strobe_mediaplayback.html) 80 | * [Clappr](https://github.com/globocom/clappr) 81 | 82 | Old versions of JWPlayer (<=4.4) supported capturing video 83 | from webcam. You can find that version in test/ subdirectory. 84 | However audio is not captured by this version of player. 85 | Recent free versions of JWPlayer have no capture capability at 86 | all. 87 | 88 | ## Transcoding streams 89 | You can use exec directive and ffmpeg for transcoding streams. For example: 90 | 91 | application big { 92 | live on; 93 | exec /usr/bin/ffmpeg -re -i rtmp://localhost:1935/$app/$name -vcodec flv -acodec copy -s 32x32 -f flv rtmp://localhost:1935/small/${name}; 94 | } 95 | application small { 96 | live on; 97 | } 98 | 99 | ## Video on demand 100 | 101 | ## Distributed streaming 102 | 103 | ## Notifications & access control 104 | 105 | ## Statistics 106 | 107 | ## Verifying session 108 | 109 | ## Utilizing multi-core CPUs --------------------------------------------------------------------------------