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搭建推流服务器的过程,如有不足之处欢迎之处