准备

        服务器采用Ngix + RTMP 模块


启动指令

F:\AI\nginx_1.7.11.3_Gryphon\nginx.exe -c conf/nginx-win.conf


注意:nginx: [emerg] CreateFile() "E:\流媒体\nginx/conf/nginx.conf" failed (1113: No mapping for the Unicode character exists in the target multi-byte code page)

这个问题是因为有中文路径导致的问题,因此需要放在英文路径下运行


视频推流

ffmpeg.exe -re -stream_loop -1  -i inputfile.mp4 -vcodec libx264 -acodec aac -f flv rtmp://192.168.11.172:1935/live/home

备注:可能拉流失败,原因是I帧后续发送少了,添加I帧

ffmpeg.exe -re -stream_loop -1  -i inputfile.mp4 -vcodec libx264 -force_key_frames "expr:gte(t,n_forced*1)" -acodec aac -f flv rtmp://192.168.11.172:1935/live/home


播放器拉流指令

ffplay.exe rtmp://192.168.11.172:1935/live/home


nginx.conf配置文件说明

附上最简单的配置

events {
    worker_connections  8192;
}

rtmp {
    server {
        listen 1935;#监听端口,若被占用,可以更改
        chunk_size 4000;#上传flv文件块儿的大小
        application live {
            live on;
        }
    }
}

1)events是nginx的配置项,不属于RTMP的配置范畴

2)rtmp {...} 保存所有RTMP配置的信息

3)server{...} 声明了一个RTMP的实例,可以声明多个实例,只要端口不冲突,所以可以通过下面方式生成两个RTMP实例,一个监听1935端口,一个监听1936端口

rtmp {
    server {
        listen 1935;#监听端口,若被占用,可以更改
        chunk_size 4000;#上传flv文件块儿的大小
        application live {
            live on;
        }
    }
    
    server {
        listen 1936;#监听端口,若被占用,可以更改
        chunk_size 4000;#上传flv文件块儿的大小
        application live {
            live on;
        }
    }
}

注意:server不能另外命名,例如server1,server2

4)listen
语法:listen (addr[:port]|port|unix:path) [bind] [ipv6only=on|off] [so_keepalive=on|off|keepidle:keepintvl:keepcnt]
上下文:server
描述:给 nginx 添加一个监听端口以接收 RTMP 连接。

5)application
语法:application name { ... }
上下文:server
描述:创建一个 RTMP 应用。application 名的模式并不类似于 http location。
server {
    listen 1935;
    application live{
    }
}

注意:当前创建一个名叫live的应用,当我们访问资源的时候,就需要携带上这个应用的名字,例如:

rtmp://192.168.11.172:1936/live/home,1936说明访问RTMP的其中一个实例,然后请求live应用下的home资源

如果没有创建live的应用,就会提示rtmp://192.168.11.172:1936/live/home: I/O error

6)live
语法:live on|off
上下文:rtmp, server, application
描述:切换直播模式,即一对多广播。
live on;

 

说明

Nginx-rtmp 对 rtmp{...} 内的配置项划分了几个级别:

  • 直接隶属于 rtmp{} 块内的配置项称为 main 配置项。
  • 直接隶属于 server{} 块内的配置项称为 srv 配置项。
  • 直接隶属于 application{} 块内的配置项称为 app 配置项。
  • 直接隶属于 record{} 块内的配置项称为 rec 配置项。


配置HTTPS证书访问视频资源

场景

        微信小程序只能通过域名和https访问网络资源,因此在nginx-rtmp-module配置HTTPS证书

 

配置内容

打开conf/nginx.conf文件,拷贝已有的server配置,复制一份粘贴到已有的server下方,然后修改端口为443

 server {
        listen      443;
        ssl on;
        ssl_certificate   server.crt;
        ssl_certificate_key  server.key;
        ssl_session_timeout 5m;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        add_header Access-Control-Allow-Origin '*';

 

测试

       ffplay.exe  https://192.168.58.173:443/hls/2/index.m3u8

 

注意

1)HTTPS证书必须拷贝到conf文件夹,跟nginx.conf文件同一级目录,并且不能指定绝对路径

        ssl_certificate   server.crt;
        ssl_certificate_key  server.key;

   指定绝对路径出错提示:

nginx: [emerg] BIO_new_file("E:\cvos_srtmp_service\nginx/conf\‪F:\example\ssls\Debug\server.crt") failed (SSL: error:0200107B:system library:fopen:Unknown error:fopen('E:\cvos_srtmp_service\nginx/conf\‪F:\example\ssls\Debug\server.crt','r') error:2006D002:BIO routines:BIO_new_file:system lib)

从路径就可以看出,nginx还多添加了配置文件的路径,导致读取HTTPS证书失败


Access-Control-Allow-Origin跨域播放问题解决方案

场景

        搭建Nginx + rtmp推流服务器,WEB前后端分离的应用,前端跨域请求视频流,查看浏览器的返回内容,提示:No 'Access-Control-Allow-Origin' header


解决思路

        nginx允许跨域是关键, 使用add_header函数添加头即可。添加在 location 节点


解决

        修改nginx.conf文件

http {
    server {
        listen      8081;
  
        add_header Access-Control-Allow-Origin '*';   #添加这一行
        add_header 'Access-Control-Allow-Methods' 'PUT,POST,GET,DELETE,OPTIONS';  #添加这一行

        add_header 'Access-Control-Allow-Headers' 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With';#添加这一行 

  
  location /hls { 
           #server hls fragments 
           add_header Access-Control-Allow-Origin '*';#添加这一行,支持访问视频流

   types{ 
    application/vnd.apple.mpegurl m3u8; 
    video/mp2t ts; 
   } 
   alias "D:/hls/";  #视频流文件目录,跟上面的hls_path保持一致  
   expires -1; 
        }

}


HLS流媒体服务器部署

知识准备

              HLS是Apple推出的直播协议,是通过视频流切片成文件片段来直播的。客户端首先会通过HTTP请求一个m3u8文件,里面会有不同码率的流,或者直接是ts文件列表,通过给出的ts文件地址去依次播放。在直播的时候,客户端会不断请求m3u8文件,检查ts列表是否有新的ts切片。这种方式的实时性较差,不过优势是H5、IOS、Android都原生支持。

在nginx.conf中配置

推送的数据会保存在F:/hls,设置分片和时间段

rtmp {

    server {

        listen 1935;#监听端口,若被占用,可以更改

        chunk_size 4000;#上传flv文件块儿的大小

  application hls{

            live on;

            hls on;

            hls_path "F:/hls/";#视频流文件目录

            hls_fragment 1s;#没有生效

            hls_playlist_length 30s;

            hls_nested on; #默认是off。打开后的作用是每条流自己有一个文件夹

           hls_cleanup off;#不清理ts

        }

    }

}

在http中的server添加m3u8数据类型的点播配置

http {

    server {

        listen       80;

        server_name  localhost;

  location /hls {  #这里也是需要添加的字段。

        types { 

            application/vnd.apple.mpegurl m3u8; 

            video/mp2t ts; 

        }

        alias "F:/hls/";  #视频流文件目录,跟上面的hls_path保持一致

        expires -1;

        add_header Cache-Control no-cache;

    }

推流指令

ffmpeg.exe -re -stream_loop -1  -i inputfile.mp4 -vcodec libx264 -acodec aac -f flv rtmp://192.168.11.172:1935/hls/home

-stream_loop -1:循环读取文件推流

由于我们配置了rtmp中的应用hls,支持hls协议,所以会在F:/hls/文件夹下创建一个test文件夹,里面保存了

推流生成的文件,进入到文件夹,可以看到0.ts和index.m3u8等文件,index.m3u8文件记录了文件的信息以及文件切割之后的列表

取流指令

ffplay.exe http://192.168.11.172:80/hls/home/index.m3u8

取流的时候,将不再经过rtmp协议进行流的获取,而是通过http服务获取,端口是http的服务端口

从上面可以看出来配置rtmp的hls应用是推流保存文件,配置http中的hls应用是配置拉流

注意:一旦启用hls,将无法通过ffplay.exe  rtmp://192.168.11.172:1935/hls/home点播视频流


配置一个mp4可读取文件地址

配置nginx-win.conf

rtmp {

    server {

        listen 1935;#监听端口,若被占用,可以更改

        chunk_size 4000;#上传flv文件块儿的大小

        application live { #创建一个叫live的应用

             live on;#开启live的应用

             allow publish 127.0.0.1;#

             allow play all;

            hls_path "F:/hls/";

             hls_fragment 2s; 

    play "F:/AI/nginx_1.7.11.3_Gryphon/file";

        }

    }

}

其中

play "F:/AI/nginx_1.7.11.3_Gryphon/file";配置了rtmp服务器读取文件的地址,文件必须直接放在这个目录,如果里面创建其他的目录,读取不到

例如将一个test.mp4文件放在file文件夹下,访问路径是rtmp://192.168.58.173:1935/live/test.mp4,其中live是一个应用