在《利用Aria搭建离线下载工具》一文末尾给自己留了一个待办事项
配合下载工具实现下载完成后自动切片,以支持HLS在线播放
其实很早就在摸索落地方案了,但是最近工作确实特别忙,一边忙工作一边断断续续的探索,直到现在,基本上方案可以定型了。方案还是遵循一个原则:低代码开发,有现成的就用。
大约在几年前吧,那个时候闲得无聊,利用SpringCloud + JS + FFMpeg做出过一个通过前端分片上传视频文件,后端自动完成切片的网站DEMO,所以在探索这个遗留事项的时候也就直奔FFMpeg而去,很快就搜索到几个候选方案。
Express-FFMpeg
一款带有CMS系统的离线转码平台。
优势
这套平台自带了很多挺不错的功能,如一键扫库(可自动将符合条件的文件加载进资源库中)、加水印(可加在切片中,也可加在播放器中)、TS文件加密以及生成预览图片等等,相关介绍请点这里。
劣势
但是它也有避不开的短板(仅针对我使用过的docker版本)如:
- 转码切片过程中CPU负载高
- 音频格式支持不全,蓝光格式视频文件很难转码成功。
- 无版本更新渠道
先说转码时的负载,对于我这样的小云(1核2G ECS)转码时CPU、内存双报警简直正常得不要不要的,虽然能理解,但接受不了。因为负载过高意味着我的其他服务就无法对外提供业务,比如我的这个博客小站。
再说格式支持不全,通过ARIA下载的高清资源以MKV居多,而其中的音频格式又基本是DTS,我不确定是否是我使用的express-ffmpeg版本太老,无法支持还是别的原因。总之在扫库之后很容易卡在转码这一步。
最后说说版本升级的事儿,从官网的介绍来看,我使用的docker版本已不再维护了,后续开发者专注到高级版以及纯净版(我理解这是2个更细分的领域)的开发工作上。因此要么停留在当前版本要么升级到新版本。官网也提供了新版本的下载地址,可是问题就在于新版本引入了key(可以理解为正版验证码)但是却没有提供申请或购买key的通道。
基于以上种种,我还是看看其他候选方案吧
SRS(Simple Realtime Server)
SRS是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT。更多介绍可点击这里
优势
与express-ffmpeg相比较最大的优势在于负载。它是以实时切HLS(或RTMP)的方式提供视频网络播放功能,也就是说它仅对当前播放时间窗内的数据切片、保存,除此之外均不操作。换个词来说,这就是网络直播。
劣势
最大的劣势在于不支持点播,回放(重新推流不算),以及没有一个更简单的控制台,SRS所提供的控制台更像是一个数据看板,只能看当前的实时情况,却没办法做太多的控制(如发起推流,或设置分类),不过若SRS本身就是定位在提供实时音视频服务的话,也确实不需要提供过多花里胡哨的东西。
同时对新手不友好,关键帮助文档欠缺。如对SRS中特有的Vhost没有更多的介绍,连Vhost之间如何跳转的没多写一个字。
综合
两套方案各有利弊,express-ffmpeg更接近开箱即用,提供端到端解决方案,虽然会遇到转码失败等问题,不过总体来讲还算不错。SRS有更强的扩展能力,并且低开销,高性能,很适合我这样的小云部署。也正是考虑到云端的开销,最终选择了SRS作为在线播放的解决方案。从部署后的运行效果来看,还算稳定。CPU实时负载游荡在告警门限值附近。
12小时系统负载
实际效果(循环推流 Tom and Jerry)
实现方案
选用SRS最大的困难在于不容易找到最直接的帮助文档,得多翻相关帮助说明,而这其中就以如何配置最为关键。在说明文档中可以看出VHost是SRS完成最主要工作的地方。那么什么是VHost呢?
VHost
网上的资料大多说VHost就是SRS虚拟出多个主机,然后可以将业务通过域名相互隔离开。并且给出了通过配置本地hosts增加DNS解析的例子。我当前并不确定SRS中设置VHost真实的目的是什么,以下均为个人猜测。
- 面向业务隔离的虚拟主机
SRS官方推荐的使用方式之一就是docker。既然都用docker了,为什么还要在SRS中引入虚拟主机的概念呢?这是玩无限套娃吗?另外用同一个SRS镜像多开几个容器不也可以实现业务间的隔离吗?为什么非要在一个服务里揉进这么多弯弯绕的东东呢?不担心复杂度高了,系统不稳定吗?
- 面向对象的数据流转
从官网的Wiki所提供的几个例子中,个人感觉VHost更像是面向对象的一种设计,即一个VHost只专注于一件事情,做完了后再传递给下一个VHost继续完成业务流。如果是这样理解的话,那么VHost就完全是SRS内部数据流转的方式了,更hosts、DNS之类的完全不沾边了。
我个人是比较倾向第二种的,当然这也仅仅是个人的猜测。
配置文件
将Docker镜像拉下来之后,只需要修改配置文件就可以让SRS工作起来。以下是当前正在使用的配置文件,大部分都是默认参数。
目标:将视频流转换成HLS,并支持通过浏览器播放。
# main config for srs.
# @see full.conf for detail config.
listen 1935;
max_connections 1000;
srs_log_tank console;
daemon on;
http_api {
enabled off;
listen 1985;
}
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
stats {
network 0;
disk sda sdb xvda xvdb;
}
vhost __defaultVhost__ {
tcp_nodelay on;
min_latency on;
play {
gop_cache off;
queue_length 10;
mw_latency 100;
}
transcode {
enabled on;
ffmpeg ./objs/ffmpeg/bin/ffmpeg;
engine ff {
enabled on;
vcodec copy;
acodec libfdk_aac;
abitrate 45;
asample_rate 44100;
achannels 2;
aparams {
}
output rtmp://127.0.0.1:[port]/[app]?vhost=__hlsVhst__/[stream];
}
}
}
vhost __hlsVhost__ {
hls {
enabled on;
hls_fragment 10;
hls_window 60;
hls_path ./objs/nginx/html;
hls_m3u8_file [app]/[stream].m3u8;
hls_ts_file [app]/[stream]-[seq].ts;
}
}
工作流
以下依然是个人推测。通过将视频推流至SRS时,入口是defaultVhost。数据流进来后会触发transcode进行视频转码,以符合HLS切片要求。完成转码后会将数据流推给hlsVhost进行HLS切片,这样就完成了视频到HLS转变了。
最后
SRS一旦上手后可玩性很强,而且4.0的功能更多,诸如支持多人视频会议等一系列特性都挺吸引人的,后面有机会再继续研究一下吧。
这几天《青蛇劫起》全网上线了,作为加班星人自认是没时间去电影院了,就默默充个爱奇艺会员支持一下吧,也愿国漫能越来越好。