利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置

时间:2022-01-08 12:20:27

一、编译安装部分

1. 执行configure, 个别分支可能没有configure文件, 可去其他分支拷贝一份

利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置
 ./configure \
--prefix=/usr/local/nginx \ --with-openssl=/usr/local/openssl \ --with-pcre \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_perl_module \ --with-stream \ --with-http_flv_module \ --with-http_mp4_module \ --add-module=../nginx-rtmp-module \ --add-module=../nginx_tcp_proxy_module
利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置

 

2.make

可能会报如下错误:

利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置
# make
make -f objs/Makefile
make[1]: 进入目录“/root/code/nginx”
cd /usr/local/openssl/ \
&& if [ -f Makefile ]; then make clean; fi \
&& ./config --prefix=/usr/local/openssl//.openssl no-shared no-threads  \
&& make \
&& make install_sw LIBDIR=lib
/bin/sh:行2: ./config: 没有那个文件或目录
make[1]: *** [/usr/local/openssl//.openssl/include/openssl/ssl.h] 错误 127
make[1]: 离开目录“/root/code/nginx”
make: *** [build] 错误 2
利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置

 

则需要修改配置文件,修改如下路径文件 

nginx/code/nginx/auto/lib/openssl

修改conf文件,将其中的  .openssl/  去掉

然后再重新configure,make

3.make install 

4.查看nginx是否运行成功,在浏览器输入nginx服务器IP地址,显示如下即成功

利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置

 

[root@baijiayun ~]# ps -ef |grep nginx
root       8984      1  0 10:56 ?        00:00:00 nginx: master process /usr/bin/nginx
nginx      8985   8984  0 10:56 ?        00:00:00 nginx: worker process
root       8987   3060  0 10:56 pts/2    00:00:00 grep --color=auto nginx

 5.nginx常用命令

启动      :/usr/local/nginx/sbin/nginx
检查配置文件:/usr/local/nginx/sbin/nginx -t
重载配置文件:/usr/local/nginx/sbin/nginx -s reload
重启      : /usr/local/nginx/sbin/nginx -s reopen
停止      :/usr/local/nginx/sbin/nginx -s stop

 6.附nginx配置

user  root;
worker_processes  1;
error_log  logs/error.log  crit;
pid        logs/nginx.pid;

worker_rlimit_nofile 100000;   #更改worker进程的最大打开文件数限制
                               #如果没设置的话, 这个值为操作系统的限制.
                               #设置后你的操作系统和Nginx可以处理比“ulimit -a”更多的文件
                               #所以把这个值设高, 这样nginx就不会有“too many open files”问题了

events {
    worker_connections  1024; #设置可由一个worker进程同时打开的最大连接数
                              #如果设置了上面提到的worker_rlimit_nofile, 我们可以将这个值设得很高
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    #json格式日志
    log_format logstash_json '{"@timestamp":"$time_iso8601",'
        '"host":"$server_addr",'
        '"clientip":"$remote_addr",'
        '"size":$body_bytes_sent,'
        '"responsetime":$request_time,'
        '"upstreamtime":"$upstream_response_time",'
        '"upstreamhost":"$upstream_addr",'
        '"http_host":"$host",'
        '"url":"$uri",'
        '"domain":"$host",'
        '"xff":"$http_x_forwarded_for",'
        '"referer":"$http_referer",'
        '"agent":"$http_user_agent",'
        '"status":"$status"}';

    access_log  logs/access.log  logstash_json;

    sendfile        on;   #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来 输出文件,
                          #对于普通应用设为 on,
                          #如果用来进行下载等应用磁盘IO重负载应用,可设置 为off,
                          #以平衡磁盘与网络I/O处理速度,降低系统的负载。
                          #注意:如果图片显示不正常 把这个改成off
    tcp_nopush      on;   #防止网络阻塞
    tcp_nodelay     on;   #防止网络阻塞

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    
    upstream mypull{
    server 127.30.100.160;
    }

    server {
        listen       80;
        #server_name  localhost;
        location ~* \.m3u8$ {
            proxy_pass http://mypull;
    }
    location / {
            root "/soft/cache";
            proxy_store on;
            proxy_store_access user:rw group:rw all:r;
            proxy_temp_path "/soft/cache";
            if ( !-f $request_filename ) 
        {       
                proxy_pass http://mypull;
        }
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            client_max_body_size 20m;
            client_body_buffer_size 128M;
            proxy_connect_timeout 120;
            proxy_read_timeout 120;
            proxy_buffer_size 1M;
            proxy_buffers 6 128M;
            proxy_busy_buffers_size 256M;
    }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }


    server {
        listen       80;
        server_name  localhost;
    
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root /usr/local/nginx-rtmp-module/;
        }

        location /hls {  #这里也是需要添加的字段。
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            alias /tmp/mgclient/hls/;
            #root /tmp/mgclient;
            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;
        }
    }
}


rtmp_auto_push on;
rtmp {
    server {
        listen 1935;
        #chunk_size 4000;
        buflen 10s;   #设置默认缓冲区长度,通常客户端set_buflen在播放之前发送RTMP 命令,并重置此设置
                      #默认是1000 ms
 
        application myapp {
            live on;
            max_connections 1024;
        }
       
 
        application mgclient {
            live on;
            hls on;
            hls_fragment 1s;
            hls_nested on;                    #on | off 切换HLS嵌套模式.
                                              #在此模式下, hls_path为每个流创建一个子目录               
                                              #播放列表和片段在该子目录中创建. 默认为关闭
            wait_key on;                      #对视频切片进行保护,这样就不会产生马赛克了。
            hls_fragment_naming sequential;   #设置片段的命名方式
                                              #sequential: 使用增加的整数
                                              #timestamp : 使用流时间戳
                                              #system    : 使用系统时间
            #hls_playlist_length 30s;         #总共可以回看的事件,这里设置的是30s
            hls_continuous on;                #打开HLS连续模式,
                                              #在这种模式下,HLS序列号从上次停止的地方开始. 
                                              #老片段被保存, 默认为关闭。
            hls_cleanup on;                   #on|off 默认是开着的,是否删除列表中已经没有的媒体块
            hls_sync 100ms;
            sync 10ms;
            meta on;
            pull rtmp://127.30.100.160;
            #hls_path /tmp/mgclient/hls/;
        }

        application live {
            live on;
            drop_idle_publisher 10s;

            hls on;
            hls_path /tmp/live;
            hls_fragment 3s;
        }

        application hls{
            live on;
            hls on;
            hls_path /tmp/mgclient/hls/;
            hls_nested on;                    #on | off 切换HLS嵌套模式. 
                                              #在此模式下, hls_path为每个流创建一个子目录
                                              #播放列表和片段在该子目录中创建. 默认为关闭
            hls_fragment 1s;
            wait_key on;                      #对视频切片进行保护,这样就不会产生马赛克了。

            hls_fragment_naming sequential;   #设置片段的命名方式
                                              #sequential: 使用增加的整数
                                              #timestamp : 使用流时间戳
                                              #system    : 使用系统时间
            #hls_playlist_length 30s;         #总共可以回看的事件,这里设置的是30s
            hls_continuous on;                #打开HLS连续模式,
                                              #在这种模式下,HLS序列号从上次停止的地方开始.
                                              #老片段被保存, 默认为关闭。

            hls_cleanup on;                   #on|off 默认是开着的,是否删除列表中已经没有的媒体块
    
            hls_sync 100ms;
            sync 10ms;        
            meta on;
            #pull rtmp://127.30.100.160;
        }
    }
}

7.使用ffmpeg推流到nginx

推一个本地的mp4到上面配置的myapp上:

ffmpeg -re -i /tmp/ffmpeg_test.mp4 -vcodec copy -acodec copy -f flv "rtmp://127.30.100.180:1935/myapp/test1"

流播放地址为(127.30.100.180是我搭建nginx服务器的IP):ffplay rtmp://127.30.100.180:1935/myapp/test1

推一个本地的mp4到hls上:

ffmpeg -re -i /tmp/ffmpeg_test.mp4 -vcodec copy -acodec copy -f flv "rtmp://127.30.100.180:1935/hls/test2"

 

---------------------------------------------------------------------

二、可能遇到的问题

1.当nginx -s reload时出现如下错误:

nginx: [error] invalid PID number "" in "/usr/local/nginx/logs/nginx.pid"

则,需要使用nginx -c的参数指定nginx.conf文件的位置,即:

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

此时,重新执行:nginx -s reload即可

 

查看nginx绑定端口号:

利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置
#ss -tunl
Netid  State      Recv-Q Send-Q         Local Address:Port                        Peer Address:Port              
tcp    LISTEN     0      128                        *:1935                                   *:*                  
tcp    LISTEN     0      128                        *:80                                     *:*                  
tcp    LISTEN     0      128                        *:22                                     *:*                  
tcp    LISTEN     0      100                127.0.0.1:25                                     *:*                  
tcp    LISTEN     0      128                       :::22                                    :::*                  
tcp    LISTEN     0      100                      ::1:25                                    :::*
利用nginx、nginx-rtmp-module与ffmpeg搭建流媒体服务器过程详解及nginx.conf配置

 

2.启动nginx时,可能遇到:

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)

定位方法

1.先使用ps -e | grep nginx查看是否已经启动了nginx

2.如果没有的话则按照提示,查看0.0.0.0:80端口谁占用了,使用netstat -ltunp命令,可以看到0.0.0.0:80端口 被某个进程占用了

执行:kill pid (占用80端口的进程),然后重新启动nginx即可

 

3. ./configure: error: C compiler cc is not found缺少gcc编译器。

解决方法:安装gcc编译器

yum -y install gcc-c++ autoconf automake

 

4. ./configure: error: the HTTP rewrite module requires the PCRE library.确少PCRE库.

解决办法:安装PCRE库

yum   -y install pcre pcre-devel

 

5. ./configure: error: the HTTP cache module requires md5 functions from OpenSSL library. You can either disable the module by using --without-http-cache option, or install the OpenSSL library into the system, or build the OpenSSL library statically from the source with nginx by using --with-http_ssl_module --with-openssl=<path> options. 缺少ssl错误。

解决方法:安装openssl

yum -y install openssl openssl-devel

 

6. ./configure: error: the HTTP gzip module requires the zlib library. 缺少zlib库

解决办法:安装zlib库

yum install -y zlib-devel

 

7. ./configure: error: the HTTP XSLT module requires the libxml2/libxslt    缺少libxml2

yum -y install libxml2 libxml2-dev && yum -y install libxslt-devel

 

8. ./configure: error: the HTTP image filter module requires the GD library. You can either do not enable the module or install the libraries.

yum -y install gd-devel

 

9. ./configure: error: perl module ExtUtils::Embed is required 缺少ExtUtils

yum -y install perl-devel perl-ExtUtils-Embed

 

10. ./configure: error: the GeoIP module requires the GeoIP library. You can either do not enable the module or install the library. 缺少GeoIP

yum -y install GeoIP GeoIP-devel GeoIP-data

 

 三、将nginx加入环境变量

直接使用:nginx -v时,可能会报错:

nginx -v显示 "-bash: nginx: 未找到命令"

此时,需要在配置文件添加路径:

vim /etc/profile

添加:

export PATH="/usr/local/nginx/sbin:$PATH"

然后:source /etc/profile 使之生效,此时,nginx -v即可显示版本号

[root@baijiayun ~]# nginx -v
nginx version: nginx/1.15.3