绝密笔记 | 【云+社区年度征文】利用nginx搭建推流服务器

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万个网站。

我是个小安卓.jpg

工欲善其事必先利其器

环境搭建

使用到的工具

  1. vmare 15 Pro(虚拟机):http://www.baidu.com/link?url=OKNAZEeEQbFlpK7QD_khVA9KhH11JH7AEoXIC02rAUH0dr0_5UixhRQHyRHt-dh2&wd=&eqid=d072c0a90001a3af000000065ee20722
  2. linux(centeros8):http://www.centeros.com/
  3. xshell 6 :https://xshell.en.softonic.com/
  4. xftp 6 :http://www.downza.cn/soft/278388.html
  5. 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
  6. openssl : https://github.com/openssl/openssl/releases/ (命令下载: wget https://github.com/openssl/openssl/archive/OpenSSL_1_1_1h.tar.gz)
  7. nginx-rtmp : https://github.com/arut/nginx-rtmp-module/releases/ (命令下载:wget https://github.com/arut/nginx-rtmp-module/archive/v1.2.1.tar.gz
  8. ffmpeg:https://www.gyan.dev/ffmpeg/builds/

vmare linux的环境搭建

  1. 首先下载虚拟机vmware安装:https://www.cnblogs.com/wanglin2016/p/7258476.html
  2. xftp6:https://jingyan.baidu.com/article/f96699bb16b375894f3c1b67.html
  3. xshell:https://www.cnblogs.com/Hijack-you/p/10501136.html
  4. 在vmare 安装Centeros:https://www.cnblogs.com/Dear-XiaoLe/articles/12201099.html

相关的ngnix外的环境安装和搭建大家参考链接教程

步入正题

注:nginx的编译安装需要用到openssl

这边提供了两种编译的方案:

  1. 使用自己本地编译和安装openssl库
  2. 直接使用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

解压后.png
  • 编译openssl
    解压后,cd到openss目录下,可以看到有个config的编译脚本

命令编译,创建bin目录 生成的文件放到bin目录中

./config --prefix=`pwd`/bin

结果 生成makefile文件

生成MakeFile.png

生成之后调用make install

编译生成了bin目录.png

最后生成了bin目录,openssl的lib和include的头文件都放在bin目录中

结果.png

下载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

解压完后

image.png
1595.jpg

下载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库

nginx-1.18.0/auto/lib目录下有openssl文件内容.png

重点: 解压完之后需要进行配置编译生成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 文件, 如下图:

image.png

增加了一个自己定义的目录检索代码语句,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库

运行上面的两种方式的任何一种命令:

生产Makefile文件.png

最后进行编译安装:

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文件

image.png

命令启动nginx服务器

./nginx   

在linux浏览器验证:可以看到显示nginx/1.18.0的版本信息,表示nginx已经搭建成功

表示服务端已经搭建ok.png

在外部浏览器访问验证:

外部访问虚拟中搭建的nginx.png

外部访问需要使用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的路径,需要手动修改成我们当前的。

修改点.png

再次访问浏览器:

效果.png

查看nginx的运行情况:

ps aux | grep nginx

image.png

停止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
推流的过程.png

再用实时流工具进行加载播放(这边只是模拟,完整的直播实时流,是由摄像头采集流,然后推到服务器)

醒醒改bug.jpg

碰到的一些坑

问题一:在编译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开机启动

收尾.jpeg

总结

nginx的推流服务器搭建:

1.相关环境的配置

2.nginx依赖的编译库openssl(可选自己编译)

3.下载nginx-rtmp的模块代码

4.nginx的编译安装

5.nginx.conf的文件替换,和配置修改

以上是关于自己个人利用nginx搭建推流服务器的过程,如有不足之处欢迎之处

正文完