最近做到的项目使用nginx,要将一个摄像头的视频流推送给前端,并要求同时支持3种推流方式——rtmp,http-flv,hls(m3u8)。在使用nginx时,也是遇到了诸多问题,一度差点放弃,在此做个记录,同时也方便后来人。
使用案例
我是在tx2上做的,所以例子中使用的是gstreamer进行推流,你可以使用其他推流方式,比如ffmpeg或者obs。
由于nginx本身不支持http-flv,所以需要单独下载nginx-http-flv-module,重新进行编译,编译方式按照官网说明即可。https://github.com/winshining/nginx-http-flv-module。
推流地址:rtmp://localhost:1935/live/stream_key
rtmp拉流地址:rtmp://localhost/live/stream_key
http-flv拉流地址:http://localhost:88/flv_live?port=1935&app=live&stream=stream_key
hls-m3u8拉流地址:http://localhost:88/hls/stream_key.m3u8
我使用的nginx.config,因为我使用的是动态编译(add-dynamic-module),所以第一行引入了load_module,静态编译是不需要的。
load_module /opt/nginx-1.19.1-rtmp/inst/modules/ngx_http_flv_live_module.so;
#user nobody;
worker_processes 1;
error_log logs/error.log;
error_log logs/error.log notice;
error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;
drop_idle_publisher 15s;
log_interval 5s; #interval used by log module to log in access.log, it is very useful for debug
log_size 1m; #buffer size used by log module to log in access.log
server {
listen 1935;
#chunk_size 4096;
server_name localhost; #for suffix wildcard matching of virtual host
application live {
live on;
gop_cache on; #open GOP cache for reducing the wating time for the first picture of video
#live on;
hls on;
hls_path /tmp/hls;
hls_fragment 10s;
# hls_playlist_length 60s;
#hls_continuous on;
#hls_cleanup on;
#hls_nested on;
wait_key on;
#meta off;
#allow play all;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 88;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /opt/nginx-1.19.1-rtmp/nginx-http-flv-module/;
}
location /flv_live {
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /tmp/hls;
expires -1;
add_header 'Cache-Control' 'no-cache';
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
使用方法
有些经验的朋友,通过上面的成功案例,应该可以自己推导出使用方法。所以我把方法分开写到了下面。我将分成两部分说明,第一部分作为上面案例的使用指导,第二部分作为nginx的使用拓展(不会很深,只是我就了解到这里,已经比csdn上绝大多数帖子详细了)。
第一部分
- 在config中主要有两部分——rtmp和http,原则上,我们认为rtmp是推流,http是拉流。(并不完全正确,下面说明)
直接见注释。rtmp配置好以后,就可以接受推流了,如果不加http结构,直接使用rtmp拉流也是完全可以的,因为rtmp的推拉流地址本就是一个,都不走其他端口的(如果你想要的这样的功能,可以完全去掉推流上的其他支持)
rtmp {
out_queue 4096;
out_cork 8;
max_streams 128;
timeout 15s;
drop_idle_publisher 15s;
log_interval 5s; #interval used by log module to log in access.log, it is very useful for debug
log_size 1m; #buffer size used by log module to log in access.log
server {
listen 1935; # 推流使用的端口,默认1935端口在推流拉流时都可以省略,改为其他端口需要指定
#chunk_size 4096;
server_name localhost; #for suffix wildcard matching of virtual host
application live {
live on; #开启直播
gop_cache on; #open GOP cache for reducing the wating time for the first picture of video
#live on;
hls on; # 支持m3u8
hls_path /tmp/hls; # m3u8 文件的保存位置,检验配置是否成功,可以推流后cd到该目录下,看一下有没有文件生成,有文件的话就可以判定不是推流配置的问题。
hls_fragment 10s; # 每个视频保存10s
# hls_playlist_length 60s;
#hls_continuous on;
#hls_cleanup on;
#hls_nested on;
wait_key on;
#meta off;
#allow play all;
}
}
}
http拉流配置,http协议的拉流需要走http下面配置的端口,所以在地址中也有体现。
http://localhost:88/flv_live?port=1935&app=live&stream=stream_key
规则(注意两个port、dir、appname):http://example.com[:port]/dir?[port=xxx&]app=appname&stream=streamname
http://localhost:88/hls/stream_key.m3u8
规则:http://example.com[:port]/dir/streamname
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 88; # 拉流使用的端口,使用默认端口80时,拉流时可不指定
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
# 查看状态的部分,下部分介绍,不需要可去掉
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
# 查看状态的部分,下部分介绍,不需要可去掉
location /stat.xsl {
root /opt/nginx-1.19.1-rtmp/nginx-http-flv-module/;
}
# 拉http-flv的配置
location /flv_live {
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
# 拉hls的配置
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /tmp/hls; # 读取文件的位置,应和上面rtmp中的配置一样
expires -1;
add_header 'Cache-Control' 'no-cache';
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
第二部分
- 可直接查看实时的推流状态,在地址栏直接输入http中配置到的stat部分,地址+stat
http://localhost:88/stat