一、综述
引用自知乎 作为程序员,你有哪些正在做的个人项目?
从今年年初开始,公司就没什么事了,混吃等死,总琢磨着写点玩意儿,在github上闲逛,偶尔发现些bug,能解的就解了。这两年直播不是挺火么?我就用RTSP,RTMP等搜了下相关的开源项目,找到两个:srs(simple-rtmp-server)和nginx-rtmp-module。
前者是国人杨成立发起的,国内使用它的厂商很多,遗憾的是3.x版已经闭源。而后者是一个俄罗斯人发起的,遗憾的是作者已经多年不更新了。后来发现nginx-rtmp-module不支持HTTP方式播放直播流,而这是很多厂商支持的,况且Nginx本身就是个优秀的Web服务器,对HTTP协议支持得很好,那为什么不在nginx-rtmp-module上支持HTTP方式播放直播流呢?说干就干,于是从5月开始加功能,一直到7月底,基本把HTTP直播播放的功能加上了:https://github.com/winshining/nginx-http-flv-module
以下参考nginx-http-flv-module作者的
基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module(一)
基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module(二)
基于nginx-rtmp-module模块实现的HTTP-FLV直播模块nginx-http-flv-module(三)
近几年直播行业火爆,开源的直播软件解决方案有SRS(Simple-RTMP-Server)和nginx-rtmp-module,前者是国人发起的一个优秀的开源项目,目前国内很多公司都使用它作为直播解决方案,由C++编写;后者依赖Nginx,以第三方模块的方式提供直播功能,由C编写。
SRS采用多线程方式(经网友提醒更正:是单线程+协程方式),性能优秀,经受住了众多场景的考验,但是SRS3已经闭源(更正:是有一段时间闭源了,现在又开源了);
nginx-rtmp-module是采用多进程方式,Nginx的性能优秀,但是据网友测试,同为单进程条件下,nginx-rtmp-module的性能不如SRS,并且nginx-rtmp-module的作者已经很久没有更新版本了,支持的功能也有限,例如不支持HTTP方式的FLV直播,而这是国内直播行业普遍采用的方式;再如推流不支持upstream,无法分布式部署功能;还有饱受诟病的播放响应延迟时间很长的问题(即俗称的不能秒播)等。
我在nginx-rtmp-module的基础上实现了基于HTTP方式的FLV直播功能,支持GOP缓存,减少了首屏时间;支持流式和chunked两种HTTP响应格式;修复nginx-rtmp-module没有listen配置项时,推拉流失败的问题;解决nginx-rtmp-module已知的bug,见nginx-http-flv-module,欢迎下载测试和反馈bug,也欢迎提PR。有问题或者建议,可以加Q群:711969608详聊,注意:进群请先查看群说明和群公告,编译问题(除了一些确实是因为兼容问题不能编译的),能通过README和wiki解决的配置问题请优先自行解决,回复问题不是群友的义务,因为绝大多数群友有自己的工作。
目前已经有很多个人和厂商准备将本模块商用。据网友反馈,国外已经有直播网站在使用这个模块。国内准备商用的厂商有华为,中兴(网友告知,未确认)等。另外据网友反馈,EasyDSS和EasyNVR也集成了本模块的功能。网友和厂商陆续反馈过不少bug,修复后功能已经越来越稳定,在此表示感谢。
二、SRS部分资料
参考
SRS大神杨成立
SRS(simple-rtmp-server)直播点播服务器
SRS Github
SRS HTTP FLV
CRtmpServer转推流到Nginx Rtmp及SRS(SimpleRtmpServer)的经历
通读SRS后的总结文档以及搭建直播平台的初次尝试
SRS/3.0,OuXuli,是一个流媒体集群,支持RTMP/HLS/FLV,高效、稳定、易用,简单而快乐。
三、nginx-rtmp-module搭建
参考
Nginx - Windows下Nginx初入门
Windows下Nginx的启动、停止等命令
在Windows下搭建基于nginx的视频直播和点播系统
Linux&Windows搭建基于nginx的视频点播服务器
在windows下搭建、配置nginx流媒体服务器,并进行rtmp流的推流、拉流测试
在nginx官网上下载的nginx是不带rtmp模块的。如果只是做点播,Nginx本身不需要任何额外的模块就支持flv和mp4格式的点播,也支持拖动进度条.
所幸,已经有大神做好了nginx的编译,而且集成了很多nginx模块,其中就已经包括了nginx-rtmp-module。
下载地址:http://nginx-win.ecsds.eu/,详细说明可参见:Readme nginx-win version.txt
我下载的是nginx 1.7.11.3 Gryphon这个版本。
1.nginx常用命令
start nginx
nginx -s reload
nginx -s stop
nginx -c 指定一个配置文件。默认的路径是安装目录下的conf/nginx.conf
nginx -t 检查配置文件是否正确
修改conf/nginx.conf配置文件,然后在nginx.exe路径下命令行(PowerShell不行)运行nginx -s reload
重新加载配置。
如果报错nginx: [error] OpenEvent("Global\ngx_reload_38192") failed (2: The system cannot find the file specified)
,则说明nginx服务器未启动成功。
启动nginx成功的另一个标志是在nginx 1.7.11.3 Gryphon文件夹的logs目录下生成nginx.pid文件,如下图所示:
该nginx.pid文件存放的是当前nginx主进程的ID号,打开该文件后可以看到里面存放着“3980”这个数字,这个数字就是本次启动nginx主进程的ID号(每次启动的数字都会不同的)
我们可以在任务管理器中查询到该进程,则表示nginx启动成功了。
2.配置rtmp及点播
参考配置如下
worker_processes 1; #Nginx进程数,建议设置为等于CPU总核数
events {
worker_connections 1024; #工作模式与连接数上限
}
rtmp_auto_push on;
#RTMP服务
rtmp{
server{
listen 1935; #服务端口
chunk_size 4096; #数据传输块的大小
application vod{
play ./vod; #视频文件存放位置
}
application live{
live on; #开启直播
hls on; #开启hls直播。这个参数把直播服务器改造成实时回放服务器
#wait_key on; #对视频切片进行保护,这样就不会产生马赛克了
hls_path ./m3u8File; #切片视频文件存放位置(HLS,m3u8文件存放位置)
hls_fragment 2s; #每个视频切片的时长
hls_playlist_length 16s;
recorder myRecord{
record all manual;
record_suffix _.flv;
record_path ./rec;
}
#hls_continuous on; #连续模式
#hls_cleanup on; #对多余的切片进行删除
#hls_nested on; #嵌套模式
}
}
}
#HTTP服务
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location /live_hls{
types{
#m3u8 type设置
application/vnd.apple.mpegurl m3u8;
#ts分片文件设置
video/mp2t ts;
}
#指向访问m3u8文件目录
alias ./m3u8File;
add_header Cache-Control no-cache; #禁止缓存
}
location /control{
rtmp_control all;
}
location /stat{
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl{
root ./nginx-rtmp-module-master;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
3.关于使用FFmpeg推流时,live目录的理解
在nginx.conf中
#RTMP 直播流配置
application live{
live on;
record off;
}
使用“ ffmpeg -i "D:\nginx1.7\vod\jay.flv" -f flv rtmp://127.0.0.1/live/test1”
中推流。“ live ”其实是一个虚拟目录,这个目录和windows中传统的目录是不一样的,可以理解为推流到的流媒体服务器的模块路径或者虚拟路径,但是实际在流媒体服务器中是不会存在这个目录的,因为它是虚拟的。这个目录其实是用来区分流的,表示要推流到的地址;推流地址为多少,拉流地址就得为多少。比如推流指令为“ ffmpeg -i video3.mp4 -f flv rtmp://127.0.0.1/live/test1 ”
,使用ffplay进行拉流的指令就得为“ ffplay rtmp://127.0.0.1/live/test1”
,可以看到推流地址和拉流地址是对应的。
这里推流很快就结束了,然后就无法播放了。可以加一下re参数
"-re":按视频帧率的速度读取输入
"-c copy":输出流使用和输入流相同的编解码器
"-f flv":指定输出流封装格式为flv
4.直播状态监控
location /stat{
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl{
root ./nginx-rtmp-module;
}
然后我们在浏览器中输入http://127.0.0.1/stat。如下图所示,在下面的页面中我们就可以进行直播状态监听了。
5.点播
上面这个配置就是点播了:
application vod{
play ./vod; #视频文件存放位置
}
使用VLC播放rtmp://127.0.0.1/vod/jay.flv
即可。
当然点播不使用RTMP插件nginx自身也是可以实现点播服务的。那就是配置http的location部分:
server {
listen 80;
server_name localhost;
location /01.mp4 {
root vod;
}
location /jay.flv {
root vod;
}
location /265.mp4 {
root vod;
}
现在使用http://127.0.0.1/jay.flv
也可以点播了
6.配置hls
参考在windows下配置nginx流媒体服务器,使其支持hls协议的直播和rtmp点播
这里我还是把hls从live配置中剥离出来,单独做了一个配置
rtmp{
server{
listen 1935;
application vod {
play ./vod; #这是一个目录的名称,如果是linux,则写具体位置如/opt/video
}
#直播流配置
application live{
live on;
recorder myRecord{
record all manual;
record_suffix _.flv;
record_path ./rec;
}
}
application hls {
live on;
hls on;
hls_path ./m3u8File;
hls_fragment 5s;
}
}
}
然后http配置:
location /hls {
types {
application/vnd.apple.mpegurl m3u8;#m3u8 type设置
video/mp2t ts;#ts分片文件设置
}
alias ./m3u8File;
expires -1;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
}
推流
ffmpeg -re -i "D:\nginx1.7\vod\jay.flv" -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:1935/hls/cctv1
可以在m3u8File文件夹下看到许多TS文件和m3u8文件,并且一直在更新。
此时在VLC中播放http://127.0.0.1:80/hls/cctv1.m3u8
即可看到画面,注意刚开始推流时可能还无法播放,要延迟几秒等m3u8生成后才能播放。
四、nginx-http-flv-module搭建
参考
https://github.com/winshining/nginx-http-flv-module/blob/master/README.CN.md
注意nginx-http-flv-module 包含了 nginx-rtmp-module 所有的功能,所以不要将 nginx-http-flv-module 和 nginx-rtmp-module 一起编译。
只是做测试的话,还是找WINDOWS版本的省事儿。感谢csdn的博主bugNotBug,提供不需要积分的下载链接nginx-1.19.6_nginx-http-flv-module(64位),这里可以参考此博主另一个链接nginx-1.19.3_nginx-http-flv-module.rar,把里面的http-flv.conf复制过去。
推流:
ffmpeg -re -i "D:\nginx1.7\vod\jay.flv" -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:1935/myapp/cctv1
拉http-flv流
http://127.0.0.1:80/live?port=1935&app=myapp&stream=cctv1
拉rtmp流
rtmp://127.0.0.1/myapp/cctv1
当然这个模块参照上面HLS的设置,也是可以提供HLS直播的,不过要另推hls流
ffmpeg -re -i "D:\nginx1.7\vod\jay.flv" -vcodec copy -acodec copy -f flv rtmp://127.0.0.1:1935/hls/cctv1