让小云支持视频在线播放
Keep Team Lv4

  在《利用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的通道。

What are U弄啥嘞

  基于以上种种,我还是看看其他候选方案吧

SRS(Simple Realtime Server)

  SRS是一个简单高效的实时视频服务器,支持RTMP/WebRTC/HLS/HTTP-FLV/SRT。更多介绍可点击这里

优势

  与express-ffmpeg相比较最大的优势在于负载。它是以实时切HLS(或RTMP)的方式提供视频网络播放功能,也就是说它仅对当前播放时间窗内的数据切片、保存,除此之外均不操作。换个词来说,这就是网络直播

劣势

  最大的劣势在于不支持点播,回放(重新推流不算),以及没有一个更简单的控制台,SRS所提供的控制台更像是一个数据看板,只能看当前的实时情况,却没办法做太多的控制(如发起推流,或设置分类),不过若SRS本身就是定位在提供实时音视频服务的话,也确实不需要提供过多花里胡哨的东西。

console

console

  同时对新手不友好,关键帮助文档欠缺。如对SRS中特有的Vhost没有更多的介绍,连Vhost之间如何跳转的没多写一个字。

综合

  两套方案各有利弊,express-ffmpeg更接近开箱即用,提供端到端解决方案,虽然会遇到转码失败等问题,不过总体来讲还算不错。SRS有更强的扩展能力,并且低开销,高性能,很适合我这样的小云部署。也正是考虑到云端的开销,最终选择了SRS作为在线播放的解决方案。从部署后的运行效果来看,还算稳定。CPU实时负载游荡在告警门限值附近。

12小时系统负载

CPU

MEM

LOAD

实际效果循环推流 Tom and Jerry

实现方案

  选用SRS最大的困难在于不容易找到最直接的帮助文档,得多翻相关帮助说明,而这其中就以如何配置最为关键。在说明文档中可以看出VHost是SRS完成最主要工作的地方。那么什么是VHost呢?

VHost

  网上的资料大多说VHost就是SRS虚拟出多个主机,然后可以将业务通过域名相互隔离开。并且给出了通过配置本地hosts增加DNS解析的例子。我当前并不确定SRS中设置VHost真实的目的是什么,以下均为个人猜测。

  1. 面向业务隔离的虚拟主机

  SRS官方推荐的使用方式之一就是docker。既然都用docker了,为什么还要在SRS中引入虚拟主机的概念呢?这是玩无限套娃吗?另外用同一个SRS镜像多开几个容器不也可以实现业务间的隔离吗?为什么非要在一个服务里揉进这么多弯弯绕的东东呢?不担心复杂度高了,系统不稳定吗?

  1. 面向对象的数据流转

  从官网的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的功能更多,诸如支持多人视频会议等一系列特性都挺吸引人的,后面有机会再继续研究一下吧。

  这几天《青蛇劫起》全网上线了,作为加班星人自认是没时间去电影院了,就默默充个爱奇艺会员支持一下吧,也愿国漫能越来越好。

白蛇2