nginx+nginx-http-flv-module+ffmpeg/obs实现点播+直播
nginx+nginx-http-flv-module+ffmpeg/obs实现点播+直播
更新:2021/02/19
nginx+nginx-http-flv-module+ffmpeg/obs实现点播+直播
现在使用ffmpeg实现rtmp推直播流
http-flv、rtmp、hls-m3u8拉直播流
rtmp、http拉点播流
已知问题:
1.ffmpeg使用摄像头推流会报 real-time buffer too full or near too full;
解决方案:ffmpeg -rtbufsize 100M -f dshow -i video="Camera Name" -vcodec libx264 -acodec copy -preset:v ultrafast -tune:v zerolatency -vf scale=iw/2:-1 -f flv rtmp://yourip:1936/live/stream
2.http拉点播流时可以成功,但是在nginx-stat面板没有显示;
3.暂时未设置负载均衡、代理等。
4.暂时未实现hls点播
注:
1.相关性能暂时未测试
2.涉及nginx.conf部分代码统一使用python风格,因为注释格式相同,方便阅读。
文章思路:
安装nginx
安装nginx-rtmp-module并加入nginx中
实现rtmp直播推流+rtmp直播拉流+rtmp点播
新增nginx-http-flv-module并加入nginx中
新增实现http-flv直播拉流
新增实现http点播
新增实现hls点播
部分转载文章,原文:链接
自己也尝试配置了一下,因此在里面加上一些自己遇到的问题及其解决方案(红色标注)。给大家做一个参考。
个人水平有限,恳请不吝指正。有什么问题也可以在评论区留言,一起讨论学习。
另外一些问题值得注意:
1.注意文章指令中 的相对地址和绝对地址
2.注意里面涉及到的版本问题,可能要修改对应的输入指令
3.动手操作过程中应该有一个较为明确的思路,这样有利于更快的搭建。
4.如果不是很熟悉Linux操作的,切勿陷入其中。应该做到多思考问题的原因- - 自己在尝试的过程中发现git和wget指令有问题,折腾了很久,浪费了大量的时间
5.对于Linux的文件移动复制、vim使用等不了解的部分,应该多做笔记,多积累。
6.应该花一些时间去看看nginx.conf文件中的代码,或者看一下其他人对功能设置部分进行的注释。
附一个参考的思路:
目的:搭建nginx+nginx-rtmp-module框架,实现直播、点播、录播等操作
过程:
安装依赖和nginx
安装依赖和nginx-rtmp-module
将rtmp模块添加到nginx - - 至此,nginx及其rtmp模块已经基本完成,可以进行测试。无误后再进行下一步
配置conf文件并测试 - - - 在配置的过程中,应该明确自己需要加上什么功能,按照注释来进行添加
配置obs和vlc
开发环境
nginx的服务器的搭建
建议首先创建一个合适的文件夹,用来存放nginx相关文件
安装nginx的依赖库
sudo apt-get update
sudo apt-get install libpcre3 libpcre3-dev
sudo apt-get install openssl libssl-dev
配置并编译nginx
使用nginx的默认配置,添加nginx的rtmp模块。
此处应该注意:
是在nginx的解压文件夹路径下进行,而非安装路径,并不是/usr/local/nginx!
./configure --add-module=../nginx-rtmp-module-master
make
sudo make install
运行测试nginx
进入安装目录/usr/local/nginx,运行命令./sbin/nginx 注:此处的安装目录与存放nginx源文件的目录不一样
注意:以后所有的命令都在/usr/local/nginx目录运行,也是nginx配置文件的相对目录。
如果出现端口被占用而无法启动nginx的情况,杀死端口号对应的进程
操作如下:
lsof -i:80
在列出对应进程号后(如进程号为2345),使用指令:
kill 9 2345
打开浏览器在地址栏输入:localhost。如果,如下图显示那样就证明您的nginx服务器搭建成功了。
点播视频服务器的配置- -rtmp点播拉流
通过上一步nginx服务器已经搭建完成,然后我们就可以开启一个视频点播的服务了。打开配置文件nginx.conf,添加RTMP的配置。
这里的conf文件应该是在/usr/local/nginx/conf路径下,使用vi nginx.conf进行修改即可(这里涉及到vim的使用,应该借此逐渐掌握vim的基本使用)
附常用:
vim的常用操作
进入vim后应该处于命令模式,点击i进入插入模式;
此时可以进行编辑、删除等操作;
使用esc退出插入模式,进入命令模式;
在命令模式下: :wq表示保存退出、 :q表示退出、 :wq!表示强制进行保存退出
快速删除: 命令模式下dd指令定位到第一行,dG全部删除
修改conf文件后应该进行测试
worker_processes 1;
events {
worker_connections 1024;
}
rtmp { #RTMP服务
server {
listen 1935; #//服务端口
chunk_size 4096; #//数据传输块的大小
application vod {
play /opt/video/vod; #//视频文件存放位置。
}
}
}
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;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
测试过程: 在/usr/local/nginx/路径下,使用 nginx -t 指令进行测试,如果显示无误,则进行下一步。
配置目录*/opt/video/vod*为存放视频文件的位置了,那我们就往里面放一个文件吧。我放了一个qq.mp4文件。
文件放好之后,那就让我们重新启动一下nginx
视频文件的路径应该是 /opt/video/vod/qq.mp4:
cd /
cd opt/video/vod
ls
请再次回到/usr/local/nginx路径下继续执行下面的指令
sudo ./sbin/nginx -s reload
打开视频播放软件选用的是VLC media-> open network stream…
如图填写我们要点播的节目地址rtmp://localhost/vod/qq.mp4 如图:
点击play就可以播放了。
这里点击play后可能报错,是因为vlc版本的问题。在新版本中,vlc加入了对rtmp的支持,因此可以播放。我使用的是Ubuntu12.04版本,vlc暂时不支持。
我这里暂时是绿屏状态,但是能够播放并且有声音。判断是因为解码出现了问题。
在逐个排查问题,查了一些资料之后,发现可能是自己的vlc播放器设置有问题:
工具-->首选项-->视频
设置过程如上所示,我选择OpenGL 这一项就可以正常播放。如果还是不能正常显示,请逐个尝试并保存。<!!注意重启vlc!!>
播放效果如图
----------------------
当然点播不使用RTMP插件nginx自身也是可以实现点播服务的。那就是配置location部分,由于下面我们要配置直播和回看功能所以选用了RTMP服务。
直播视频服务器的配置 - -rtmp直播推流
接着我们就在点播服务器配置文件的基础之上添加直播服务器的配置。一共2个位置,第一处就是给RTMP服务添加一个application这个名字可以任意起,也可以起多个名字,由于是直播我就叫做它live吧,如果打算弄多个频道的直播就可以live_cctv1、live_cctv2名字任意。第二处就是添加两个location字段,字段的内容请直接看文件吧。
worker_processes 1;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application vod {
play /opt/video/vod;
}
application live{ #第一处添加的直播字段
live on;
}
}
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /stat { #第二处添加的location字段。
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl { #第二处添加的location字段。
root /usr/local/nginx/nginx-rtmp-module/;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
添加完这两处之后,重新启动nginx打开浏览器看看,是否有如下图显示:
在这个位置,可能针对stat.xsl进行报错,没有上图的效果。这是因为我们的stat.xsl文件路径有问题,以下提供两种解决方案:
1.将我们解压得到的nginx-rtmp-module文件夹中的stat.xsl文件复制到对应路径下:如下图所示
2.将nginx.conf文件中location /stat.xsl位置的路径修改为我们解压得到的nginx-rtmp-module文件夹路径
----------------------------------
最近在服务器上进行测试,发现还会出现另一种问题,就是访问localhost/stat会出现404。
看了一下erro.log,发现一直报错/usr/local/nginx/http/stat未找到,后来发现这是因为自己的stat路径设置的有问题:
在此幅图片中,/usr/local/nginx/html为新设置的路径--此路径下应该有stat.xsl 。
如果使用指令nginx -s reload尝试重启nginx,但是通过lsof -i:80查询发现其pid并未改变;
使用指令nginx -s reload可以重启nginx,其pid未改变
或者改用nginx -s stop 和 nginx来实现重启,lsof -i:80可以看到其进程号变化,证明服务重启了。
此时再次在浏览器打开localhost/stat就可以正确显示了。
---------------------------------
有没有看到红框框的live字样呢?如果可以显示出来,证明你的配置生效了。
还等什么让我们推送一个节目看看(其实专业词叫录制,后面将会使用录制这个词。)吧。
这次推送我使用的是OBS(Open Broadcaster Software)有关它的安装请参考先前我写的Ubuntu安装OBS(Open Broadcaster Software)后面的博客里我会给大家介绍如何使用手机采集视频并且推送到服务器上。
- 点击红圈添加“Media Source”,会弹出一个框框,里面的内容就按照图片显示配置就可以了。点击“OK”就能在你的屏幕上播放了。
- 配置节目的输出流如图所示: 首先点击红圈“setting”进入设置界面。记得要正确填写要录制的服务器路径啊。配置好就可以点击OK了。退出后点击蓝圈,就开始录制节目了。
- 查看我们的了录制的节目,服务器有没有接收到呢?打开我的服务器地址“http://localhost/stat”查看一下 ,你的显示是否和我的相同呢?如果相同证明服务器已经接收到了录制的节目,客户端可以进行播放了。
播放的地址就是“rtmp://localhost/live/test”,如果您本地有支持rtmp协议的播放器就可以试试了。最后奉上一张观看直播的屏幕截图。
实时回看视频服务器的配置
我们想一想如果直播服务能够把节目录制在本地,我们不就可以直接进行回看先前的节目了吗?回看一分钟、一小时甚至一天的。不用写代码有现成的可以使用。怎么用呢?继续看nginx的配置吧。
worker_processes 1;
events {
worker_connections 1024;
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application vod {
play /opt/video/vod;
}
application live {
live on;
hls on; #这个参数把直播服务器改造成实时回放服务器。
wait_key on; #对视频切片进行保护,这样就不会产生马赛克了。
hls_path /opt/video/hls; #切片视频文件存放位置。
hls_fragment 10s; #每个视频切片的时长。
hls_playlist_length 60s; #总共可以回看的事件,这里设置的是1分钟。
hls_continuous on; #连续模式。
hls_cleanup on; #对多余的切片进行删除。
hls_nested on; #嵌套模式。
}
}
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/nginx/nginx-rtmp-module/;
}
location /live { #这里也是需要添加的字段。
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /opt/video/hls;
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;
}
}
}
1.添加完成后需要重新启动nginx,由于这次nginx需要向服务器写切片视频文件,但nginx我又没有给nginx指定用户名只能走默认的nobody用户和nogroup用户组,其实就是没有组。所以我对需要写入的目录做了增大权限的修改。
如下图,这样做就是为了避免由于权限问题而无法写文件。
2.如何给服务器录制视频,在上一节已经说过,这里就不再说了。
3.查看视频文件是否真的录制上没有,继续看图:
已经产生切片视频文件了。其中还有一个index.m3u8。
4.播放视频,这次可是http开头的了,“http://localhost/live/test/index.m3u8”。
5.已经可以播放了,如何回看呢?其实这个index.m3u8文件仅仅是目录。想回看那个就播放那个.ts文件就可以了
截止到这里,实现了rtmp直播推流+rtmp点播+录播后以切片方式播放
http-flv直播拉流和http点播拉流
rtmp的优点很多,但是它和flash关系密切,随着各大浏览器不再支持flash,rtmp拉流在pc端难以为继。
下面就来讨论一下http-flv直播拉流和http点播拉流如何实现
之前安装了nginx-rtmp-module,这个部分可以实现rtmp的一些设置,但是我们想要得到一个http流,那么需要安装一个nginx-http-flv-module。
两个模块的对比如图所示:< 新安装的模块具有rtmp模块的所有功能,且新增了我们所需要的功能:HTTP-FLV(for play) >
安装步骤类似于nginx-rtmp-modue,具体可以参考GitHub:nginx-http-flv-module主页,这里面有详细的安装部署配置教程。
在安装完nginx-http-flv-module之后,nginx/conf/nginx.conf并未变化,所以之前的功能大部分可用,但是需要注意的是stat.xsl文件仍然是rtmp模块里面的,所以我们应该将nginx-http-flv-module文件夹中stat.xsl复制到对应路径下,来实现替换。再次打开http://localhost/stat,效果如下图:
此时我们打开nginx/conf/nginx.conf文件,再次进行设置
在文件中的http部分server内容中,添加location /flv,如下图所示:
部分配置文件代码如下:
http {
include mime.types;
default_type application/octet-stream/;
sendfile on;
keepalive_timeout 65;
server{
listen 8089;
#拉流hls
location /hls { #down hls
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /path/to/your/file;
expires -1;
add_header 'Cache-Control' 'no-cache';
}
#拉流http-flv
location /flv { #down flv
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
此时就可以实现http-flv直播拉流。
http://example.com[:port]/dir?[port=xxx&]app=appname&stream=streamname
< //:port是http端口 port=xxx是rtmp端口 >
那么根据nginx.conf可以组合出具体的拉流链接
http://yourip:8089/flv?port=1936&app=live&stream=mystream
8089是http中flv对应的端口,1936是rtmp中live所对应的端口
注:此时并未推流,所以此地址并没有作用
上面给出了一种obs推流的方式,下面介绍一种ffmpeg推流的方法:
这里是在Windows环境下实现ffmpeg推流。
ffmpeg安装及配置:参考文章
Windows中cmd常用操作:参考文章
ffmpeg常用指令:参考文章
我们在存放视频的文件夹下,进行ffmpeg推流
ffmpeg -re -i test.mp4 -c copy -f flv rtmp://yourip:1936/live/mystream
此时我们可以拉流,使用http-flv、hls、rtmp
具体指令如下:
//ffmpeg推直播流rtmp 某一个视频
ffmpeg -re -i test.mp4 -c copy -f flv rtmp://yourip:1936/live/mystream
//rtmp推流地址:rtmp://yourip:1936/live/stream //推流默认使用1935端口
//rtmp直播拉流地址:
rtmp://yourip:1936/live/mystream //默认端口是1935
//rtmp点播拉流地址:
rtmp://yourip/vod/test2.mp4 //默认端口是1935
//http-flv直播拉流地址:
http://yourip:8089/flv?port=1936&app=live&stream=mystream
//hls-m3u8直播拉流地址:
http://yourip:8089/hls/mystream.m3u8
这里使用potplayer进行拉流测试
使用nginx实现http点播,性能还没有测试
在nginx.conf的http部分,server中添加
#这里是使用字符匹配来实现 http点播,应该还有更好的http点播实现方式,后续再学习。
location ~* \.flv$ {
root /path/to/your/file; #视频目录 - - 同vod路径
}
location ~* \.mp4$ {
root /path/to/your/file; #视频目录- - 同vod路径
}
对应的http点播地址为:
http点播拉流地址:
注意端口要对应上述location所在server的监听端口号,默认为80,我的是8088
http://yourip:8088/test.mp4
下面是完整的nginx.conf设置文件- - <这里代码使用python格式,是因为注释格式正好重合,方便阅读>
worker_processes 1;
pid logs/nginx.pid;
events {
worker_connections 1024;
}
rtmp{
#rtmp中使用了两个server来实现
#一个端口1936中配置rtmp直播推流
#一个端口1935(默认)配置rtmp点播拉流
server{
listen 1936;
chunk_size 4096;
application live{ #up rtmp
live on;
hls on;
hls_path /path/to/your/file/;
hls_fragment 5s;
}
}
server{
listen 1935;
chunk_size 4096;
application vod{ #down rtmp
play /path/to/your/file/;
}
}
}
http {
include mime.types;
default_type application/octet-stream/;
sendfile on;
keepalive_timeout 65;
#http中配置了两个server
#端口8089中配置hls直播拉流、http-flv直播拉流
#端口8088中配置页面、http点播等
#默认端口为80
server{
listen 8089;
#拉流hls
location /hls { #down hls
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /path/to/your/file;
expires -1;
add_header 'Cache-Control' 'no-cache';
}
#拉流http-flv
location /flv { #down flv
flv_live on;
chunked_transfer_encoding on;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
}
}
server {
#端口号、主机名
listen 8088;
server_name localhost;
#状态表的设置
location =/stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/nginx/html;
}
location / {
root html;
index index.html index.htm;
}
location ~* \.flv$ {
root /path/to/your/file; #视频目录
}
location ~* \.mp4$ {
root /path/to/your/file; #视频目录
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
实现hls点播
在http中的8089端口部分实现此功能,详情参考:hls点播
如果有什么问题,欢迎在评论区指正