一 、安装nginx和rtmp插件模块
(注意:所有命令请手打,复制粘贴会因为空格的系统编码不同而执行失败!)
1.1 首先查看系统是否已安装nginx
whereis nginx查找位置,如果是yum安装的,没有configure文件,卸载参考:https://www.jianshu.com/p/c1ce9eec5fb2
然后看是否有java环境:
安装jdk【先用jps查看是否安装,没有才安装】
apt install openjdk-8-jdk-headless
或者yum install -y java-1.8.0-openjdk*
1.2 然后进入local目录
cd /opt/local
下载nginx(没有安装wget的请安装,安装命令:yum -y install wget)(注意:不能使用yum安装nginx,需要下载源码包编译安装才行,源码包中有configure文件)
wget http://nginx.org/download/nginx-1.18.0.tar.gz
1.3 解压
tar -zxvf nginx-1.18.0.tar.gz
1.4 目录换名
mv nginx-1.18.0 nginx
1.5 创建插件模块目录
mkdir -p /opt/local/nginx/module
最好也顺便创建logs文件夹
mkdir -p /opt/local/nginx/logs
1.6 创建视频数据存放位置
mkdir -p /opt/local/nginx/myapp
1.7 进入到/opt/local/nginx/module目录
cd /opt/local/nginx/module
下载nginx-http-flv-module,下载后的文件夹名叫nginx-http-flv-module
git clone https://github.com/winshining/nginx-http-flv-module.git
或者 git clone https://gitee.com/winshining/nginx-http-flv-module.git (有时候github连接不上,就连接gitee)
(安装git命令:yum -y install git)
【原生的nginx-rtmp-module有一些缺陷,所以使用它的升级模块:nginx-http-flv-module,github地址:https://github.com/winshining/nginx-http-flv-module.git,具体介绍参见中文README.CN.md】
1.8 进入解压后的nginx目录中
cd /opt/local/nginx/
先安装编译环境
yum -y install unzip
yum -y install gcc-c++
yum -y install pcre pcre-devel
yum -y install zlib zlib-devel
yum -y install openssl openssl-devel
指定nginx安装目录并且指定了安装的模块
./configure --prefix=/opt/local/nginx --add-module=/opt/local/nginx/module/nginx-http-flv-module --conf-path=/opt/local/nginx/conf/nginx.conf --with-http_ssl_module
1.9 编译并安装
make && make install
(有一两个make的小错误,可以忽略不计,启动nginx成功的话,就不用管!)
1.10 启动nginx
/opt/local/nginx/sbin/nginx &
此时如果没有问题,那么你就可以访问http://localhost了,会出现welcome界面。
二、 配置nginx.conf
编辑nginx.conf配置文件,使用vi打开
vi conf/nginx.conf
添加 rtmp节点,增加myapp应用节点信息:
rtmp {
idle_streams off; #失效的推拉流连接会被自动断开
server {
listen 1935;
chunk_size 4096; #数据传输块的大小,不能低于128
drop_idle_publisher 30s; #30s没有推流数据,自动断开推流端
timeout 30s; #socket超时时间,默认60s(主要是写入).当推流结束后30s,自动断开所有拉流
on_publish http://localhost:10040/v1/rtmp/on_publish; #状态回调的第三方接口
on_publish_done http://localhost:10040/v1/rtmp/on_publish_done;
on_play http://localhost:10040/v1/rtmp/on_play;
on_play_done http://localhost:10040/v1/rtmp/on_play_done;
application myapp {
live on;#直播模式
hls on; #这个参数把直播服务器改造成实时回放服务器.
hls_path /opt/local/nginx/myapp/hls; #切片视频文件存放位置。
}
}
}
在http节点下,增加stat 、stat.xsl等
http {
server {
listen 9000;
server_name localhost;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /opt/local/nginx/module/nginx-http-flv-module/;
}
location /control {
rtmp_control all;
}
location /rtmp-publisher {
root /opt/local/nginx/module/nginx-http-flv-module/test;
}
location / {
root /opt/local/nginx/module/nginx-http-flv-module/test/www;
}
# 这个只有nginx-http-flv模块可以使用,可以用http协议的拉流地址播放
location /live {
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Credentials' 'true'; # 允许发送Cookie
add_header 'Access-Control-Allow-Origin' '*'; # 允许跨域
add_header 'Access-Control-Allow-Headers' X-Requested-With;
add_header 'Access-Control-Allow-Methods' GET,POST,OPTIONS;
add_header 'Cache-Control' 'no-cache';
}
}
}
配置完成后在nginx目录下重启服务
./sbin/nginx -s reload -c /opt/local/nginx/conf/nginx.conf
rtmp节点配置代表的是流媒体服务器配置,live on代表的是视频直播服务,on_play代表播放视频的状态回调配置接口地址(需要部署相应的http接口服务才可以打印相应的状态回调信息),stat配置代表的是可以在浏览器中查看监控当前流媒体拉流客户端状态信息,如下
三、使用ffmpeg进行推流和ffplay进行拉流测试
本地windows下载ffmpeg压缩包解压,在ffmpeg目录中放入一个视频文件demo.mp4,打开cmd窗口进入bin目录下:
3.1使用命令进行推流:
ffmpeg -re -i ../demo.mp4 -f flv -flvflags no_duration_filesize rtmp://127.0.0.1:1935/myapp/123
3.2使用命令进行拉流:
ffplay -fflags nobuffer rtmp:127.0.0.1:1935/myapp/123
如果没有问题,拉流后则会出现直播视频窗口,此时说明流媒体服务器部署成功。流媒体地址就是rtmp://127.0.0.1:1935/myapp/123
注释:【127.0.0.1:1935为rtmp服务器地址、myapp为nginx配置节点、123为视频流名称,拉流地址和推流地址一样即可播放】
3.3不同协议的拉流地址
rtmp协议格式:rtmp://127.0.0.1:1935/myapp/123
http协议格式:http://127.0.0.1:9000/live?port=1935&app=myapp&stream=123
注意1:也可以使用module插件自带的html文件进行拉流直播测试:
修改nginx/module/nginx-rtmp-module/test/www/index.html文件,将
file: "rtmp://localhost/myapp?carg=1/mystream?sarg=2" 中的mystream替换成推流的密钥就可以了。然后服务启动,在ie浏览器中输入localhost:9000,就不是nginx的欢迎页面了,而是视频播放页面,有推流的时候,点击播放键就可以直播了。(谷歌浏览器不支持Adobe flash,会提示No playable sources found)
四、如果需要使用https协议地址进行拉流播放
4.1首先需要生成https证书和秘钥文件,执行linux命令:
openssl req -new -x509 -nodes -out server.crt -keyout server.key
执行过程中需要填写相关的信息,里面的common name选项填写需要的域名,这里可以填写localhost
生成的两个文件server.crt为证书,server.key为秘钥
4.2然后将两个文件放在流媒体服务器nginx的配置文件的同级目录中,修改配置文件nginx.conf,然后重启nginx服务
4.2.1 在http节点中增加一个server节点
# 新增server节点,使用9001端口
server {
listen 9001 ssl;
server_name localhost;
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;
location / {
proxy_pass http://localhost:9000/; #转发到9000端口
}
}
4.2.2 或者对http原有节点进行相应修改,如下标红的为新增的配置:
server {
listen 9000 ssl;
server_name localhost;
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;
···
}
此时如果再用浏览器查看监控页面,就需要用https协议了
4.3 相应的https协议拉流地址为:
增加节点的:https://127.0.0.1:9001/live?port=1935&app=myapp&stream=123
修改节点的:https://127.0.0.1:9000/live?port=1935&app=myapp&stream=123
注意1:以上https证书是简单使用,浏览器未信任的,如果要用浏览器信任的,可以参考注意2中的第三项、第四项!
注意2:关于https证书相关,参考
http://blog.sina.com.cn/s/blog_6ffe66ef0100qzg6.html
https://blog.csdn.net/i12344/article/details/103383049
https://blog.csdn.net/alinathz/article/details/106440017 (除了创建服务器端的证书和秘钥文件之外,还要创建客户端浏览器所需的p12格式客户端证书,在windows下直接双击导入即可!注意:创建服务端和客户端证书时的ip或者域名要一样,不然浏览器访问还是不信任的)
https://zhuanlan.zhihu.com/p/100743934
五、补充
如何在推流结束后立马关闭拉流客户端的连接?
1.在http模块中,有配置
location /control {
rtmp_control all; #可以配置drop,用来断开连接(推流和拉流都可以)
}
2.(项目的话可以在回调函数的on_publish中调用,只要推流结束,立刻断开对应stream的客户端拉流连接)主动调用下面四个相应的http请求url就可以(地址中的端口是nginx中的http协议端口):
2.1语法格式:
http://server.com/control/drop/publisher|subscriber|client?srv=SRV&app=APP&name=NAME&addr=ADDR&clientid=CLIENTID
addr - 可选,客户端ip地址(回调函数中获取)
clientid - 可选,nginx的客户端ID(回调函数中获取)
2.2示例:
第一个是删除推流端(发布者)的连接;第二到四个是删除客户端的连接
curl http://localhost:9000/control/drop/publisher?app=myapp&name=mystream
curl http://localhost:9000/control/drop/client?app=myapp&name=mystream
curl http://localhost:9000/control/drop/client?app=myapp&name=mystream&addr=192.168.0.1
curl http://localhost:9000/control/drop/client?app=myapp&name=mystream&clientid=1
注意:删除客户端连接的请求如果没有addr参数,将会中断所有客户端链接(包括发布者)