nginx的推流服务器搭建
闲扯
博客已经许多月没有继续更新了,近期刚好有个粉丝在做直播实时流转发,需要构建推流服务器,像我提出了一些nginx构建的问题,捧着自己的粉丝请教(当时一头雾水:我只是个小安卓),但是还是专门花了一天的时间研究了下推流服务器(直播实时流服务器)RTMP流媒体服务器,现在网上现成的开源方案有很多,有SRS,Red5,wowoza,FMS等,我这里使用的是Nginx的rtmp插件实现实时流转发。
介绍下主角
Nginx是2004年俄罗斯大佬lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的。
Nginx功能丰富,可作为HTTP服务器,也可作为反向代理服务器,邮件服务器。支持FastCGI、SSL、Virtual Host、URL Rewrite、Gzip等功能。并且支持很多第三方的模块扩展。
Nginx的稳定性、功能集、示例配置文件和低系统资源的消耗让他后来居上,在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。

工欲善其事必先利其器
环境搭建
使用到的工具
- vmare 15 Pro(虚拟机):http://www.baidu.com/link?url=OKNAZEeEQbFlpK7QD_khVA9KhH11JH7AEoXIC02rAUH0dr0_5UixhRQHyRHt-dh2&wd=&eqid=d072c0a90001a3af000000065ee20722
- linux(centeros8):http://www.centeros.com/
- xshell 6 :https://xshell.en.softonic.com/
- xftp 6 :http://www.downza.cn/soft/278388.html
- nginx :http://nginx.org/en/download.html 或者 https://github.com/nginx/nginx/releases/ (命令下载:wget https://github.com/nginx/nginx/archive/release-1.18.0.tar.gz)
- openssl : https://github.com/openssl/openssl/releases/ (命令下载: wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1h.tar.gz)
- nginx-rtmp : https://github.com/arut/nginx-rtmp-module/releases/ (命令下载:wget https://github.com/arut/nginx-rtmp-module/archive/v1.2.1.tar.gz)
- ffmpeg:https://www.gyan.dev/ffmpeg/builds/
vmare linux的环境搭建
- 首先下载虚拟机vmware安装:https://www.cnblogs.com/wanglin2016/p/7258476.html
- xftp6:https://jingyan.baidu.com/article/f96699bb16b375894f3c1b67.html
- xshell:https://www.cnblogs.com/Hijack-you/p/10501136.html
- 在vmare 安装Centeros:https://www.cnblogs.com/Dear-XiaoLe/articles/12201099.html
相关的ngnix外的环境安装和搭建大家参考链接教程
步入正题
注:nginx的编译安装需要用到openssl
这边提供了两种编译的方案:
- 使用自己本地编译和安装openssl库
- 直接使用http_ssl_module(类似android studio的gradle依赖使用)
openssl的本地编译
- 下载openssl的代码包
这边采用在linux命令下直接下载
wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1h.tar.gz
命令解压
tar -zxvf openssl-OpenSSL_1_1_1h.tar.gz
- 编译openssl
解压后,cd到openss目录下,可以看到有个config
的编译脚本
命令编译,创建bin目录 生成的文件放到bin目录中
./config --prefix=`pwd`/bin
结果 生成makefile文件
生成之后调用make install
最后生成了bin目录,openssl的lib和include的头文件都放在bin目录中
下载nginx-rtmp
这边采用在linux命令下直接下载
wget https://github.com/arut/nginx-rtmp-module/archive/v1.2.1.tar.gz
解压
tar -zxvf nginx-rtmp-module-1.2.1.tar.gz
解压完后
下载nginx进行编译安装
这边采用在linux命令下直接下载
wget https://github.com/nginx/nginx/archive/release-1.18.0.tar.gz
解压
tar -zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0/auto/lib/, 可以看到nginx的编译确实是需要用到openssl库
重点
: 解压完之后需要进行配置编译生成MakeFile文件,这边有两个方式
方式一
:采用本地的自己编译的openssl进行编译生成MakeFile
./configure --prefix=`pwd`/bin --add-module=/usr/local/soft/nginx-rtmp-module-1.2.1 --with-openssl=/usr/local/soft/openssl-OpenSSL_1_1_1h/bin
/usr/local/soft/openssl-OpenSSL_1_1_1h/bin
:这个就是前面编译的生产的openssl的lib和include的目录
要注意的是,使用本地自己编译的openssl库,需要开发者自己手动去配置,nginx使用的lib路径和头文件include的路径
nginx的openssl的配置文件:/usr/local/soft/nginx-1.18.0/auto/lib/openssl/conf 文件, 如下图:
增加了一个自己定义的目录检索代码语句,conf配置文件在执行的时候,签名的条件下检索判断找不到,会继续往下进行检索
下面是个人自己添加的检索代码:
主要是用来配置指明告诉nginx,参与编译的openssl库的头文件:/usr/local/soft/openssl-OpenSSL_1_1_1h/bin/include
和生产的so库:/usr/local/soft/openssl-OpenSSL_1_1_1h/bin/lib
在哪里。
if [ $ngx_found = no ]; then | |
# Custom | |
ngx_feature="OpenSSL library in /usr/local/soft/openssl-OpenSSL_1_1_1h/bin" | |
ngx_feature_path="/usr/local/soft/openssl-OpenSSL_1_1_1h/bin/include" | |
if [ $NGX_RPATH = YES ]; then | |
ngx_feature_libs="-R/usr/local/soft/openssl-OpenSSL_1_1_1h/bin/lib -L/usr/local/soft/openssl-OpenSSL_1_1_1h/bin/lib -lssl -lcrypto" | |
else | |
ngx_feature_libs="-L/usr/local/soft/openssl-OpenSSL_1_1_1h/bin/lib -lssl -lcrypto" | |
fi | |
ngx_feature_libs="$ngx_feature_libs $NGX_LIBDL $NGX_LIBPTHREAD" | |
. auto/feature | |
fi |
方式二
:直接使用http_ssl_module进行编译生成MakeFile(该方法比较简单,不需要去手动编译和配置openssl库)
./configure --prefix=`pwd`/bin --add-module=/usr/local/soft/nginx-rtmp-module-1.2.1 --with-http_stub_status_module --with-http_ssl_module
解释下参数:
参数 |
描述 |
---|---|
–prefix |
配置安装的路径 |
–add-module |
新增模块目录 |
–with-openssl |
指定nginx ssl模块依赖的ssl库 |
运行上面的两种方式的任何一种命令:
最后进行编译安装:
make && make install
在编译完后看到输出的目录提示:
-ldl -lpthread -lcrypt -lpcre -lssl -lcrypto -ldl -lpthread -lz \ | |
-Wl,-E | |
sed -e "s|%%PREFIX%%|/usr/local/soft/nginx-1.18.0/bin|" \ | |
-e "s|%%PID_PATH%%|/usr/local/soft/nginx-1.18.0/bin/logs/nginx.pid|" \ | |
-e "s|%%CONF_PATH%%|/usr/local/soft/nginx-1.18.0/bin/conf/nginx.conf|" \ | |
-e "s|%%ERROR_LOG_PATH%%|/usr/local/soft/nginx-1.18.0/bin/logs/error.log|" \ | |
< man/nginx.8 > objs/nginx.8 | |
make[1]: 离开目录“/usr/local/soft/nginx-1.18.0” |
表示nginx的服务器已经搭建ok了。
cd 到nginx-1.18.0/bin/sbin的目录下可以看到有个nginx文件
命令启动nginx服务器
./nginx
在linux浏览器验证:可以看到显示nginx/1.18.0的版本信息,表示nginx已经搭建成功
在外部浏览器访问验证:
外部访问需要使用centeros的对外ip,可以使用ip addr
进行查看
到这里nginx的服务器可以使用了。
but
我们是需要实现推流的效果,因此还需要一个步骤:
将nginx-rtmp-module-1.2.1/test/nginx.conf 替换 nginx-1.18.0/bin/conf/nginx.conf文件
cp /usr/local/soft/nginx-rtmp-module-1.2.1/test/nginx.conf /usr/local/soft/nginx-1.18.0/bin/conf/
替换后的nginx.conf
worker_processes 1; | |
error_log logs/error.log debug; | |
events { | |
worker_connections 1024; | |
} | |
# 这边就是推流的配置,默认端口是1935 | |
rtmp { | |
server { | |
listen 1935; | |
application myapp { | |
live on; | |
#record keyframes; | |
#record_path /tmp; | |
#record_max_size 128K; | |
#record_interval 30s; | |
#record_suffix .this.is.flv; | |
#on_publish http://localhost:8080/publish; | |
#on_play http://localhost:8080/play; | |
#on_record_done http://localhost:8080/record_done; | |
} | |
} | |
} | |
http { | |
server { | |
listen 8080; | |
location /stat { | |
rtmp_stat all; | |
rtmp_stat_stylesheet stat.xsl; | |
} | |
location /stat.xsl { | |
root /path/to/nginx-rtmp-module/; | |
} | |
location /control { | |
rtmp_control all; | |
} | |
#location /publish { | |
# return 201; | |
#} | |
#location /play { | |
# return 202; | |
#} | |
#location /record_done { | |
# return 203; | |
#} | |
location /rtmp-publisher { | |
root /path/to/nginx-rtmp-module/test; | |
} | |
location / { | |
root /path/to/nginx-rtmp-module/test/www; | |
} | |
} | |
} |
替换完配置,需要重启下nginx才可以生效
./nginx -s reload
在提到一点是:上面的nginx.conf,需要进行配置修改,在我们前面直接用浏览器访问ip的时候出现了404,因为这个是默认的rtmp的路径,需要手动修改成我们当前的。
再次访问浏览器:
查看nginx的运行情况:
ps aux | grep nginx
停止nginx:
方式1,快速停止:
./nginx -s stop
此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。
方式2,完整停止(建议使用):
./nginx -s quit
此方式停止步骤是待nginx进程处理任务完毕进行停止。
- 验证下推流的效果
这边采用的ffmpeg的工具进行推流,直接下载window版本,然后cmd命令将flv的视频文件以流的形式推到nginx服务器ffmpeg -re -i Test.flv -f flv rtmp://192.168.18.157:1935/myapp/mystream
再用实时流工具进行加载播放(这边只是模拟,完整的直播实时流,是由摄像头采集流,然后推到服务器)
碰到的一些坑
问题一:在编译make的时候出现的 g++: 未找到命令
原因分析:当前linux环境gcc++环境需要更新或者未安装
解决方法:更新安装下gcc的环境
yum install gcc-c++
问题二:在打包编译ngnix的时候,包出错误:
-o objs/addon/nginx-rtmp-module-1.2.1/ngx_rtmp_eval.o \ | |
/usr/local/soft/nginx-rtmp-module-1.2.1/ngx_rtmp_eval.c | |
/usr/local/soft/nginx-rtmp-module-1.2.1/ngx_rtmp_eval.c: 在函数‘ngx_rtmp_eval’中: | |
/usr/local/soft/nginx-rtmp-module-1.2.1/ngx_rtmp_eval.c:160:17: 警告:this statement may fall through [-Wimplicit-fallthrough=] | |
switch (c) { | |
^~~~~~ | |
/usr/local/soft/nginx-rtmp-module-1.2.1/ngx_rtmp_eval.c:170:13: 附注:here | |
case ESCAPE: | |
^~~~ |
分析原因:是编译器将警告当成了错误处理
解决方法:
用编辑器vim /nginx-1.18.0/objs/MakeFile
文件进行修改,
CFLAGS = -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g
去掉CFLAGS中的-Werror,再重新make
问题三:Nginx 安装报错: make make: *** 没有规则可以创建“default”需要的目标“build”。 停止。
分析原因:当前的nginx的安装环境缺少了包,也可以详细的查看在安装的额过程提示,哪些环境not found
我这边是找不到zlib 和 pcre
解决方法:进行环境安装
yum -y install zlib zlib-devel pcre pcre-devel
问题四:出现真机无法访问虚拟的nginx的问题
分析原因:Linux防火墙的问题
解决方法:关闭防火墙
systemctl stop firewalld.service #停止firewall | |
systemctl disable firewalld.service #禁止firewall开机启动 |
总结
nginx的推流服务器搭建:
1.相关环境的配置
2.nginx依赖的编译库openssl(可选自己编译)
3.下载nginx-rtmp的模块代码
4.nginx的编译安装
5.nginx.conf的文件替换,和配置修改
以上是关于自己个人利用nginx搭建推流服务器的过程,如有不足之处欢迎之处