基于nginx的rtmp直播平台

前一阵子四个月前接到一个需要跑rtmp直播的需求,咕咕到现在才开始写文章。

需求很简单,只是要求能跑得动串流即可。但是有一项附加条件:必须在CentOS7上搭建。

这就麻烦多了,如果是Ubuntu上直接一条命令搞定:

1
sudo apt install nginx libnginx-mod-rtmp

而在centos7上由于没有现成的包,需要手动编译安装。

开始吧!

按照惯例先关闭SELinux和Firewall

1
2
3
4
5
6
7
systemctl stop firewalld.service 
systemctl disable firewalld.service

setenforce 0
vi /etc/sysconfig/selinux

SELINUX=disabled

解决依赖

1
2
yum install epel-release 
yum install -y nginx gcc gcc-c++ pcre-devel zlib-devel make unzip openssl-devel libxslt-devel zlib-devel pcre pc google-perftools gd gd-devel gperftools perl-ExtUtils-Embed redhat-rpm-config

这里采用替换yum安装的二进制来实现,保证与yum包安装的最大兼容,但是不能阻止yum更新,生产环境最好添加一个自己构建的yum source。

查看已安装的版本,这里查询到的是1.16.1

1
nginx -V

下载源码并开始编译

1
2
3
4
5
6
7
8
9
mkdir ~/source ; cd ~/source 
wget http://nginx.org/download/nginx-1.16.1.tar.gz
wget https://github.com/winshining/nginx-http-flv-module/archive/v1.2.7.tar.gz
tar -xzvf nginx-1.16.1.tar.gz ; tar -xzvf nginx-http-flv-module-1.2.7.tar.gz
cd nginx-1.16.1

./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E' --add-module=/root/source/nginx-http-flv-module-1.2.7

make -j4

如果不想保持最大兼容而且独立编译的话只需要如下的config即可

1
2
3
cd nginx-1.16.1
./configure --add-module=/root/source/nginx-http-flv-module-1.2.7
make -j4

等待编译完成后覆盖原始文件

1
2
3
4
5
6
cp objs/nginx /usr/sbin/nginx
cp objs/ngx_http_image_filter_module.so /usr/lib64/nginx/modules/
cp objs/ngx_http_perl_module.so /usr/lib64/nginx/modules/
cp objs/ngx_http_xslt_filter_module.so /usr/lib64/nginx/modules/
cp objs/ngx_mail_module.so /usr/lib64/nginx/modules/
cp objs/ngx_stream_module.so /usr/lib64/nginx/modules/

创建hls缓存目录并添加如下配置:

1
2
mkdir -p /var/www/hls
vi /etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
rtmp  {
server {
listen 1935; ##这是RTMP协议默认端口
chunk_size 4096; ##最大分块大小
application live { ##名为live的项目
live on; ##开启直播
hls on; ##开启HLS录制
wait_key on; ##让视频流从一个关键帧开始
hls_path /var/www/hls; ##HLS录制文件保存的目录
hls_fragment 5s; ##HLS生成的每个ts文件的时长
hls_playlist_length 30s; ##每个ts文件的保留时间
hls_continuous on; ##让HLS标号从上一个结束的位置开始
hls_cleanup on; ##自动清理过时的ts文件
hls_nested on; ##根据串流秘钥为每一个流项目建立一个对应的子目录
}
}
}

server {
listen 80;
server_name _;

location / {
root /var/www/;
index index.html index.htm;
}

location /live {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /var/www/hls;
add_header Cache-Control no-cache;
}
}

启动nginx即可

1
2
systemctl start nginx
systemctl enable nginx

如果没有关闭SELinux是无法绑定1935端口的

附一个简单的h5播放器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE HTML>
<head>
<meta charset="UTF-8">
<title>直播间</title>
<link class="dplayer-css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.css">
<script src="https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dplayer/dist/DPlayer.min.js"></script>
<style>
body {
text-align: center;
}
</style>
</head>
<body>
<h1>直播间</h1>
<div id="dplayer"></div>
<script>
const dp = new DPlayer({
container: document.getElementById('dplayer'),
live: true,
video: {
url: 'hls/a/index.m3u8',
type: 'hls',
}
});
</script>
</body>

obs填写的串流密钥就是h5页面第22行url中的a

更换其他密钥时记得h5页面也要修改

参考文献

https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md