发布时间:2023-05-05 13:30
本文结合作者实际项目经历介绍如何搭建一个小型的视频直播系统,包括设计思路,开发过程以及优化方向还有踩过的坑。
2014年由于项目要求需要具备将远端的现场视频信息回传到以供多个地方的用户同时查看的功能,同时由于系统采用B/S架构,因此视频只能通过浏览器来访问,而且系统基本浏览器按照chrome设计,因此视频实时浏览必须支持chrome,此外,还需要支持历史回放。
需求总结如下:
1. 支持实时视频的预览
2. 支持历史视频的回放
3. 支持20用户的同时浏览
4. 支持chrome浏览器
5. 支持现场RTSP的视频流
好了有了大致的功能列表,我们可以进行开始系统的实现了。
首先必然是调研了,因为之前并不是十分了解这方面情况。调研也是要有目标,因此我大体梳理出来了如下几个问题
1. 目前有没有类似的系统,现在哪几种解决方案
2. 如何能够满足多用户的同时查看实时视频
3. 目前通过浏览器来查看实时视频
4. RTSP视频流是什么?
有经过一番google和百度之后有了如下的发现
有不少方案可以将rtsp转为rtmp视频流
经过以上调研,就有了下面的大体设计思路,建立一个视频转发服务,将现场的rtsp视频流转为rtmp视频流发送到流媒体服务器,用户通过web视频播放器播放流媒体服务器的rtmp视频流。
有了以上的思路,就展开了第二轮调研,主要是对于流媒体服务器选型,web播放器的选型以及最重要的视频转码方案的确定。
流媒体选型方向:
在网络上流媒体服务器的资料最为丰富的是red5和fms,fms是商业软件需要购买的因此就选了red5,同时发现了一个神器adobe的live encoder这个软件就能将摄像头的视频转为rtmp的视频流,同时发现有一个fvplayer就能直接播放视频。
流媒体选型涉及到一个关键的20并发的性能指标,我们就是通过搭建了live encoder+fvplayer+red5的测试平台快速验证了red5的性能指标。
web播放器方向:
web视频播放器选择jwplayer,虽然也是商业软件,但免费版也能先凑用,
视频转码方向
关键的视频转发方案则选择了最为简单的ffmpeg 命令行的方式,
初步确定 的命令行大概是这样。
ffmpeg -i rtsp:url -b:v 2000k -an -y rtmp://10.0.4.150/live/20150423201047382
在这些问题确定后,我们的视频转发系统的总体设计就完成了,由于我们系统还需要跟主要的业务系统联动,因此系统框图如下所示。
确定好设计方案,实现就相对简单了。
整体实现可以被划分为下面几个阶段
视频转发控制模块的开发
red5 的部署网络上有相当多的资料可以查询到,这里就不再赘述了。
Ffmpeg的命令行主要可以分为输入配置,输出配置,保存配置这三块,输入配置和保存配置较为简单,需要注意的是输入配置中需要确定rtsp的视频源url这个是根据不同设备不同的。而输出配置最为复杂配置项又可以分为带宽,编码,格式,帧率,进程等部分。最终命令行如下所示(针对海康的视频服务器),
ffmpeg -i rtsp://admin:12345@20.10.114.36:554/PSIA/streaming/channels/101 -c copy -vcodec libx264 -f flv -r 25 -threads 0 -b:v 2000k -an -y rtmp://20.10.114.150/live/20150423201047382 "C:/Z111W/out.mp4"
web前端开发也是很简单,html+js就能搞定,jwplayer的初始化代码如下所示。
<html>
<head>
<script src="/jwplayer/jwplayer.js">script>
head>
<body>
<div id='myplayer'>div> <script type='text/javascript'>
jwplayer('myplayer').setup({
file: 'rtmp-url',
width: '640',
height: '480' });
script>
body>
html>
视频转发控制器初期功能其实很简单,就是根据视频源的信息,解析为ffmpeg的命令行配置参数,最后再启动ffmpeg进行视频转发。整体采用springboot框架,采用restful接口与业务系统对接,通过直接调用cmd ffmepg的方式启动视频转发。
在开发环境内的局域网的测试联调还是比较顺利的,系统初步开发完成。
自己造轮子最有挑战性的阶段并不是开发阶段,而是后来的填坑阶段
要填的坑有以下几个
能同时转发多少路视频以及优化方向
由于篇幅原因,这里就不一一详细说明这几个坑是怎么填的,这里只是给出几个大体思路
1.通过管理转发线程id,视频转发任务id的对应的表,在要进行结束转发时发送ctrl+c指令到对应的线程停止视频转发
2.通过将保存的实时视频归档到red5的live文件夹下,通过业务系统的记录归档的文件名返回用户,用户通用通过jwplayer读取历史文件进行回放
3.试验试验试验
4.通过扩展视频转发模块来组合命令行扩展ffmpeg支持的视频流,对于不支持的视频流则采用前置硬件转码器进行转码譬如h265;
5.通过重构视频转发模块采用执行转码的模块与控制模块分离的策略,通过消息中间件来实现控制与转码模块的对接,利用转码服务集群的水平扩展提高视频转发性能。
该系统随着时间的推移,经过不断的重构所用技术甚至架构已经跟最开始的设计非常不一样的,这个过程正好体现了系统演进的过程。
说明了一个普遍现象只要时间和资源不是问题,那么技术本身就不是问题。
DRY在开发上是真理,但在技术成长上优势偶尔突破一次也会有不同的收获。
人有多大胆,地有多大产啊,但这是建立在技术直觉的基础上的,否则就是只挖坑不填坑。
最后,这个系统并不复杂,但我希望在搭建和开发这个系统的思路还是对大家是有帮助的。