一、课堂腾讯云点播 HLS 播放
1. HLS 浅析
(1) HLS 协议
-
视频的封装格式是TS;
-
视频编码格式为H264,音频编码格式为MP3、AAC或者AC-3;
-
除了TS视频文件本身,还定义了用来控制播放的m3u8文件。
-
Server
Server获取媒体输入流,Media编码 MPEG-4(H.264 video 和 AAC audio),然后打包到 MPEG-2 (MPEG-2 transport stream)的传输流中,传输流会经过Stream segmenter,MPEG-2传输流会被分散为小片段然后保存为一个或多个系列的 .ts 格式的媒体文件。 -
Distribution
Stream segmenter会创建一个索引文件,通常会包含这些媒体文件的一个列表,也能包含元数据,一般都是一个.m3u8的列表,列表元素会关联一个 URL 用于客户端访问,然后按序去请求这些 URL。 -
Client
Client主要接受Client客户端请求并提供相关联的资源给客户端。
-
#EXTM3U ---表明该文件是一个m3u8播放列表文件,必须在第一行给出;
-
#EXT-X-VERSION:3 ---播放列表文件的版本,现在主流版本是3;
-
#EXT-X-STREAM-INF ---不同码率的数据流 ;
-
PROGRAM-ID=0 ---唯一标记;
-
BANDWIDTH=92166 ---这个值是十进制整数代表每秒钟的比特率,这个值必须是整个播放列表中码率的峰值;
-
RESOLUTION=384x288 ---视频流的分辨率。
-
#EXT-X-KEY ---媒体文件有可能要被加密,该标签描述了如何解密媒体文件;
-
METHOD ---包括NONE、AES-128、和SAMPLE-AES。如果该值是NONE或播放列表没有定义该标签,表示媒体段没有被加密。如果设置了NONE,则其他属性不会出现。其中AES-128表示媒体是由AES-128标准构造的的128bit的 key,和密码块链接(CBC)和PKCS7加密组成的,URI 参数必须出现在METHOD后面;
-
URI ---描述了如何获取key文件;
-
IV ---IV可以不存在,如果没有IV则使用序列号作为IV进行编解码,将序列号的高位赋到16字节的buffer中,左边补0,如果有IV,则将该值作为16字节的16进制数;
-
#EXT-X-MEDIA-SEQUENCE ---m3u8播放列表中第一个出现的媒体段的序列号;
-
#EXT-X-TARGETDURATION ---该标签描述了媒体段的最大时长,EXTINF后面的实际媒体段时长不能超过这个标签描述的值,否则会引起错误;
-
#EXTINF ---该标签描述了媒体段的时长,在3.0版本后时长可以是浮点数,否则必须是整数。
2. 播放器本地代理
-
启动本地代理服务器(一期采用mongoose);
-
视频源地址传给本地代理服务器;
-
将视频源地址转换成本地代理服务器(127.0.0.1)的地址作为播放器的视频源地址;
-
播放器向本地代理服务器发送请求;
-
本地代理服务器截取这个请求,再根据解析出来请求的信息向远端服务器发起请求;
-
本地代理服务器开始接受数据,写入文件并将文件数据再返回到播放器;
-
播放器接收到这些数据之后播放。
目前是使用 mongoose (https://github.com/cesanta/mongoose)来实现本地Http Server,在这里简单介绍一下mongoose。
mg_mgr:用于管理连接、事件等的 Manager ;mg_connection:单个连接,保存了连接信息。
主要用法步骤:
-
调用mg_mgr_init进行初始化;
-
调用mg_bind,第2个参数为需要监听的端口号,第3个参数为处理请求的handler;
-
调用mg_set_protocol_http_websocket将上一步返回的mg_connection与内建的http handler绑定。这样我们的handler才能收到http事件;
-
通过一直调用mg_mgr_poll接收请求。
-
首先缓存m3u8文件内容;
-
当播放器请求第1个ts分片,异步请求下一个ts分片并缓存数据;
-
当播放器请求分片data时,内存有就内存返回,内存没有就向远端Server请求。
3. 腾讯课堂云点播在线播放时序图解析
-
第一步通过业务 get_token 协议拿到防盗链需要的Key。这里需要注意的是防盗链的Key顺序一定要按照腾讯云文档中的顺序,带KEY防盗链的视频播放地址的校验工具;
-
第二步通过腾讯云 getplayinfo 协议拿到播放的链接,这里的链接 master和 transcodelist 都会返回;
-
第三步在请求的 URL 中拼接 voddrm.token 参数,用于鉴权;
-
第四步将请求的 URL 透传给教育自研的播放器 ARMPlayer,ARMPlayer会启动本地代理,请求数据/解码/渲染。课堂采用的是 HLS加密 [1],所以播放的时候还需要通过DK(密钥)进行TS解密。
4. 课堂腾讯云点播本地播放时序图解析
-
第一步启动本地代理,通过上层透传的本地存储的URL,读取DB中的指定清晰度的 m3u8 链接和指定清晰度的 m3u8 的内容;
-
第二步改写 m3u8 链接和 DK/TS 的域名为:127.0.0.1;
-
第三步请求本地 DK 和 TS 数据;
-
第四步解密/解封装/渲染。
二、课堂腾讯云点播优化
1. 首帧优化
-
master.m3u8 透传给FFmpeg,FFmpeg 会串行拉取3个清晰度的m3u8及第1个TS分片;
-
DNS解析耗时高;
-
每个清晰度.m3u8大小是400kb左右,拉取慢;
-
DK和TS每次都需要拉取。
这里面可能会涉及到一些问题,下面给出它们的解决方案。
问题1:master.m3u8透传给FFmpeg,FFmpeg会串行拉取3个清晰度的m3u8及第1个TS分片。
-
getplayinfo协议直接获取指定清晰度m3u8,减少master.m3u8 ->清晰度.m3u8的网络请求;
-
播放器从master.m3u8改为指定清晰度.m3u8透传给FFmpeg,减少avformat_find_stream_info串行拉取3个清晰度和第1个TS分片的耗时。
问题2:DNS解析耗时高。
-
增加DNS结果缓存模块,缓存“{域名: IP}”;
-
视频播放时,直接查表,取出域名对应的IP地址。
-
预加载;
-
预加载策略
预加载学生报名直播课结束1周内的m3u8数据和指定位置的TS、DK。
问题4:DK和TS每次都需要拉取
2. 播放成功率优化
3. 播放体验优化
-
ffplay音视频同步;