一次服务端流媒体传输实验
一、心路历程
写在前面
最近在忙比赛的项目,项目有一个实时预览监控摄像头的画面的需求。按道理说我一个臭前端不负责这一块的东西,但是没办法,时间紧任务重,只好硬着头皮上了。刚做到这一块的业务的时候,毫无头绪,因为摄像头用的是海康的,然后就四处查阅文档,四处碰壁。并且对摄像头这一块完全不了解,花了三天时间才做出一个
demo。如果你的摄像头配置比较好,如果可以通过各大摄像头厂商给demo连接上,那就会省下很多麻烦事。**
一定一定在做之前看摄像头的配置,支持什么,不支持什么!!!**因为时间肥肠的宝贵。
一些必要的认知
- 一些常见的流媒体传输协议:RTSP、RTMP、HLS、HTTP-FLV
当时我查阅文档的时候也很蒙b,这些都是什么啊,这么多协议,而且都用来干啥的。反正就是一脸懵逼,
经过好多番的学习。我这边提供的摄像头是支持RTSP取流的,所以打算在服务器上通过ffmpeg进行取流,然后推流到Nginx上,*
Nginx将流处理成对前端友好的传输格式HLS*(m3u8格式的文件),然后前端再拉流就行了。这里实现的流程是这样的
什么你说什么拉流推流,根本听不懂诶!
说实话,我也不懂,我三天的摸索下来,似乎还不能正确的理解推流和拉流。最后我是这么理解的:
推流:女主播把画面推到服务器上
拉流:我点开女主播的直播间,看女主播跳舞(doge)
RTSP协议
当然没这么简单,媒体文件的传输肯定是要基于某个协议进行传输。由于这里摄像头提供了RTSP协议的地址(很多监控摄像头厂商都有的)
,手机移动摄像头我不懂。
RTSP协议,RTSP(实时流传输协议)是一个网络控制协议,用于在线实时观看和控制流媒体服务器。它的作用类似于流媒体服务器的远程控制
这里说的比较清楚。
调试工具
学习了这些知识,我对视频流的传输渐渐有了一些理解,上文提到我们监控摄像机提供了RTSP流的地址常见摄像机厂商RTSP地址格式
,我们可以通过一些工具去播放这个流,比如VLC、potPlayer
播放器。这里建议使用VLC,因为它真的很轻量!potPlayers也行,两个都是究极好用的媒体播放器
VLC:打开软件**–>媒体–>**打开网络串流
potPlayer:浏览器–>打开链接
这里把他们当作调试工具用就行啦,因为不管是RTSP流、RTMP流、FLV流、HLS流都能播放。在搭建服务之前得保证自己的摄像机正常的在工作。
然后就是重头戏了,nginx和ffmpeg。叠个甲,对ffmpeg我是第一次用,nginx也仅限于了解,平时部署项目是宝塔面板一键部署的。
ffmpeg
这个就不多说了(因为我说不来哈哈哈)
,是一个开源的程序库,通过命令行的方式来使用他的功能,就专门用来处理媒体文件的,这里挂一个官网的下载地址
。如果使用的是宝塔面板,软件商店就有,一键安装就行。什么?命令行的方式?当然,我想,你在找文档,而且最好是中文文档。这里也准备好了ffmpeg中文文档。
把他当作一个中间工具就行了。
Nginx
这位才是重量级,真正让服务跑起来的还得是nginx,因为不熟,本来不打算走这条路(原本想用Node来搭),到头来还是避不开Nginx(
踩坑过后,嗯Nginx真香)
很重要的一点!一定要给nginx添加rtmp模块,在这里踩了很多坑,什么模块安装不上、配置文件不生效….em反正就踩了很多坑。
二、实战
RTSP地址
这边老师给提供的是海康威视的摄像头,地址格式是rtsp://摄像头用户名:摄像头密码@摄像头ip:rtsp端口号/h264/ch1/main/av_stream
画面测试
有了上文的地址,可以先在vlc和potPlayer里看一看,画面是否能正常预览画面,这里放一个正常取流的结果
安装ffpemg
这里给出了两种方式安装
- 宝塔面板
我是用宝塔面板安装的,因为方便嘛!
- 手动安装
来到ffmpeg中文官网,选择静态构建
点击sorce
下载第一个就行
下载完了之后把他扔到服务器上面去
这里先不着急,ffmpeg安装还依赖一些东西,nasm
同样也是下载完了扔到服务器上就行
万事俱备,解压编译安装
先是解压nasm
1 | tar -xvf /www/server/mypack/nasm-2.16.01.tar.gz #解压到当前目录 |
这里我解压到了/www/server/nasm目录下
进入该目录后配置makeFile然后进行编译安装
1 | ./configure --prefix=[你的安装路径] |
nasm安装完了之后就可以安装ffmpeg了
还是一样,解压,配置makeFile,编译,安装即可tips
我习惯给安装的软件配置一个软链接
(它很像windows中的快捷方式),方便全局使用,一般是这样的
1 | ln -s [软件安装目录下的bin目录或者sbin] [自己机器的sbin] |
以nasm为例,我的nasm是安装在/usr/local/nasm下面
因为我这里已经配置过了,所以whereis显示/usr/local/sbin/nasm
来看看/usr/local/nasm目录下有什么,一个bin目录(用于存放该软件的指令,有些软件是sbin)
命令如下:
1 | ln -s /usr/local/nasm/sbin /usr/local/sbin/nasm |
这里我已经建立过了,所以会显示文件已经存在
照葫芦画瓢,ffmpeg也是如此安装
安装完了并建立了软链接,使用ffmpeg -version
检查是否安装上了。
安装Nginx
到这里开始踩坑了,nginx-rtmp-module模块的安装,因为我的机器原本就安装了nginx,按道理说这并不麻烦,不就是添加一个功能模块嘛,尝试过各种办法老是装不上。这里有两种情况,这两种情况都是要下载rtmp和nginx-http-flv模块的,先下载它吧,有可能会出现一些
网络问题,这里自己解决啦
1 | git clone https://github.com/arut/nginx-rtmp-module.git 模块存放路径/默认当前 |
- 机器没有nginx
没有就装呗,这里我就不写了,因为不同的Linux发行版包管理工具都不一样
这里给出Centos7的安装历程
- 安装一些依赖
1 | yum install -y gcc-c++ #因为要通过编译安装nginx,所以这里要安装c/c++编译器 |
- 下载nginx
下载nginx有很多方式,你可以在windows上下载,然后再扔到Linux上,也可以用包管理工具安装,这里选择前者。
找个工具扔上去就行
1 | 这里选择解压到/usr/local目录下 |
ls /usr/local/
查看解压出来的nginx
发现已经解压好了,然后进入该目录cd /usr/local/nginx-1.24.0
配置./configure 脚本
1 | ./configure \ |
后期实践证明,压根不需要rtmp模块,要http-flv模块就行了,昨晚复盘的时候发现不装nginx-rtmp-module也能跑通
mmp,特别像这根水管一样,去网上找各种文章,然后东拼西凑,居然能跑起来,你就说能不能用吧
编译安装nginx
1 | make && make install #如果你想看编译是否通过,建议是make和make install分开执行 |
安装完并且软连接建立,nginx -t
检查
nginx默认对应的是80端口,在启动nginx之前检查一下自己的防火墙,看看80端口有没有放行
1 | firewall-cmd --list-ports |
如果没有放行
1 | --zone #作用域 --add-port=80/tcp #添加端口,格式为:端口/通讯协议 |
这个时候启动nginx
1 | nginx |
打开浏览器,输入你的服务器ip就能看到这个默认界面了,要是出现其他的错误,仔细看终端的错误信息。
nginx配置
编辑nginx的配置文件nginx.conf
内容如下
1 |
|
使用ffpemg进行拉流转码
tips
如果拉流转码的服务不在本机上运行,命令会有一些改动。具体怎么改请查阅ffmpeg的官方文档
1 | ffmpeg -re -rtsp_transport tcp -i rtsp://admin:123456@ip:port/h264/ch1/main/av_stream -c copy -f hls -hls_time 10 -hls_list_size 0 /www/tmp/hls/test.m3u8 |
跑起来是这样的
不用担心ts片段会堆满你的磁盘,因为之前已经在nginx的nginx.conf文件配置过了,多余的ts片段会直接丢掉。
测试
要是没什么问题那么现在用VLC访问http://ip:8888/hls/test.m3u8是可以看到监控画面的,
要是**有问题 **那多半是对应的端口没放行
成功!
有了这个hls流的地址,就可以很方便的将监控画面放进移动端页面,网页端页面了,这里我就不过多的介绍了,
vue3中使用
用的video.js这个插件,这个自行学习安装了
1 | <script setup lang="ts"> |
结果:
三、总结
几天的试验与探索,收获很多,我也想过为什么不能让rtsp流直接在web网页中显示,那得具体的问问研究流媒体传输协议的大佬了,究其原因还是浏览器不支持直接播放rtsp流。所以没办法还是要转码,转码就会花时间,延迟自然就出现了。而且这个demo转码是直接在本机进行的,并不需要再推流到服务器上了,实际情况可能转码和流媒体服务器是分开的,延迟会更高,假设又抛一个回放的需求….要回放XXXX年XX月XX日,某某时间段的录像,好了我的服务器已经宕机了。有错误的地方请指正
性能问题(实际环境中)
我的机器比较垃圾,一个ffmpeg进程已经负载累累了,还有一个问题是画面延迟,hls方案延迟会比较高,我没做过其他的解决方案。这个demo的延迟大概10S这样
平均负载
IO
暂时没有想到优化的解决方案。如果有好的优化方案可以聊一聊,我也想学!
ffmpeg后台24小时运行
这个应该很简单了,我就直接把指令贴出来了
1 | ffmpeg -nostdin -re -rtsp_transport tcp -i rtsp://admin:123456@ip:554/h264/ch1/main/av_stream -c copy -f hls -hls_time 10 -hls_list_size 0 /www/tmp/hls/test.m3u8 2> /dev/null & |
为了防止拉流转码服务挂掉,可以写一个shell脚本,每隔一段时间去检查一下ffmpeg进程是否还在,不在重启就可以了
重启脚本restart.sh
1 | ffmpeg -nostdin -re -rtsp_transport tcp -i rtsp://admin:123456@ip:554/h264/ch1/main/av_stream -c copy -f hls -hls_time 10 -hls_list_size 0 /www/tmp/hls/test.m3u8 2> /dev/null & |
检查脚本check.sh
这里我没有在脚本中写定时器,而是通过宝塔面板计划任务去实现的,方便嘛
1 | !/bin/bash |