HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

腾讯课堂点播上云客户端实践总结

  • 2020-01-19
  • 本文字数:4368 字

    阅读完需:约 14 分钟

腾讯课堂点播上云客户端实践总结

一、课堂腾讯云点播 HLS 播放

1. HLS 浅析

(1) HLS 协议


点播业务目前用的是 HLS 协议。HLS 协议全称是 HTTP Live Streaming,它是一个由苹果提出的基于 HTTP 的流媒体网络传输协议。HLS 协议规定:


  • 视频的封装格式是 TS;

  • 视频编码格式为 H264,音频编码格式为 MP3、AAC 或者 AC-3;

  • 除了 TS 视频文件本身,还定义了用来控制播放的 m3u8 文件。


HLS 的工作流程如下图(来源苹果官网)所示:



  • 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 客户端请求并提供相关联的资源给客户端。


(2)HLS 的 index 文件


index 文件就是 m3u8 文本文件,如下图(来源苹果官网)所示。客户端播放 HLS 视频流的逻辑是先下载一级 Index file,它里面记录了二级索引文件(Alternate-A、Alternate-B、Alternate-C)的地址,然后客户端再去下载二级索引文件,二级索引文件中记录了 TS、dk 的下载地址,这样客户端就可以按顺序下载 TS、dk 文件并连续播放。



以企鹅辅导为例,一级 index(master_playlist.m3u8)文件如下图所示:



  • #EXTM3U —表明该文件是一个 m3u8 播放列表文件,必须在第一行给出;

  • #EXT-X-VERSION:3 —播放列表文件的版本,现在主流版本是 3;

  • #EXT-X-STREAM-INF —不同码率的数据流 ;

  • PROGRAM-ID=0 —唯一标记;

  • BANDWIDTH=92166 —这个值是十进制整数代表每秒钟的比特率,这个值必须是整个播放列表中码率的峰值;

  • RESOLUTION=384x288 —视频流的分辨率。


二级 index(对应任意一个清晰度)文件如下图所示:



  • #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. 播放器本地代理

(1) 播放器直连 Server


以企鹅辅导为例,播放器直连远端 Server 的播放流程如下图所示:



该流程存在一些缺点,比如:用户播放视频的时候可能等待的时间较长,造成流量的浪费,无法做缓存、预加载等优化策略等。


(2) 通过本地代理播放


基本流程如下图所示:



企鹅辅导详细流程如下图所示:



具体流程可以概括为:


  • 启动本地代理服务器(一期采用 mongoose);

  • 视频源地址传给本地代理服务器;

  • 将视频源地址转换成本地代理服务器(127.0.0.1)的地址作为播放器的视频源地址;

  • 播放器向本地代理服务器发送请求;

  • 本地代理服务器截取这个请求,再根据解析出来请求的信息向远端服务器发起请求;

  • 本地代理服务器开始接受数据,写入文件并将文件数据再返回到播放器;

  • 播放器接收到这些数据之后播放。


目前是使用 mongoosehttps://github.com/cesanta/mongoose)来实现本地 Http Server,在这里简单介绍一下 mongoose。


mg_mgr:用于管理连接、事件等的 Manager ;mg_connection:单个连接,保存了连接信息。


主要用法步骤


  1. 调用 mg_mgr_init 进行初始化;

  2. 调用 mg_bind,第 2 个参数为需要监听的端口号,第 3 个参数为处理请求的 handler;

  3. 调用 mg_set_protocol_http_websocket 将上一步返回的 mg_connection 与内建的 http handler 绑定。这样我们的 handler 才能收到 http 事件;

  4. 通过一直调用 mg_mgr_poll 接收请求。


(3) Cache 功能


使用本地代理一个重要作用就是 Cache。


  1. 首先缓存 m3u8 文件内容;

  2. 当播放器请求第 1 个 ts 分片,异步请求下一个 ts 分片并缓存数据;

  3. 当播放器请求分片 data 时,内存有就内存返回,内存没有就向远端 Server 请求。


缓存淘汰


假定用户经常看的视频不能优先淘汰,那么用 LFU 淘汰策略即可。每个缓存块设置一个 count,缓存命中一次就 count++,触发淘汰的时候,把 count 最小的先淘汰。


流量控制


例如用户只看了视频前面一点,就暂停了,那么后面的视频不再下载等,具体细节后续文章将会详细说明。


seek


播放视频的时候,用户会拖动进度条进行 seek,与 mp4 文件不同,对于 hls 文件 ffplay 会根据 seek 的 position,向本地服务器请求 seek 的 position 所在的 ts 分片。

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 分片。



指定清晰度.m3u8


解决方案:


  • getplayinfo 协议直接获取指定清晰度 m3u8,减少 master.m3u8 ->清晰度.m3u8 的网络请求;

  • 播放器从 master.m3u8 改为指定清晰度.m3u8 透传给 FFmpeg,减少 avformat_find_stream_info 串行拉取 3 个清晰度和第 1 个 TS 分片的耗时。


问题 2:DNS 解析耗时高。



DNS 缓存


解决方案


  • 增加 DNS 结果缓存模块,缓存“{域名: IP}”;

  • 视频播放时,直接查表,取出域名对应的 IP 地址。


问题 3:每个清晰度.m3u8 大小是 400kb 左右,拉取慢


解决方案


  • 预加载;

  • 预加载策略

  • 预加载学生报名直播课结束 1 周内的 m3u8 数据和指定位置的 TS、DK。


问题 4:DK 和 TS 每次都需要拉取



本地代理缓存


解决方案


播放器设计了一个本地代理层,播放器不直连远端 server,而是通过本地代理层发出请求,通过本地代理层实现缓存和读取本地资源进行播放。

2. 播放成功率优化

对于播放成功率,最主要是要完善监控系统以及对出现的问题各个击破,目前遇到的主要问题和解决方式如下:



主要问题和解决方式 1



主要问题和解决方式 2

3. 播放体验优化

  • ffplay 音视频同步;

  • 企鹅辅导录播多路视频流精确对齐。



精确 Seek 流程

4. 下载优化

  • 下载成功率

  • 因为教育自研的播放器下载和播放底层库共用,所以除了播放出现的类似问题,下载方面我们还针对存储、写磁盘、安全性做了优化,已下载视频采取 DB 分级映射缓存。

  • 下载速度

  • 因为 HLS 是由无数个 TS 和 DK 构成,如果是单线程下载,每次请求一个 TS 和 DK 地址都将重新建立连接,所以这里我们采用的是多线程以及播放缓存复用逻辑。

5. 缓冲优化

这里存在两个问题,下面来做出解决方案。


问题 1:旧播放器在读数据 -> 解封装 -> 解码 -> 渲染链路上均出现过因为抖动而出现的缓冲。



缓冲区


解决方案


  • 帧缓冲区,抵抗网络抖动和解码抖动;

  • 显示缓冲区,抵抗渲染抖动。


问题 2:旧播放器是顺序存储同时没有异步请求后面的 TS 分片和 DK。



多线程和存储


解决方案


  • 顺序存储和 Seek 之后的非顺序存储;

  • 多线程异步请求。

6. 安全性优化

  • 防盗链,腾讯云防盗链主要有 2 种形式 Referer 防盗链和 Key 防盗链,目前课堂采用的是 Key 防盗链,腾讯云防盗链[2];

  • HLS 加密;

  • 水印。

三、课堂腾讯云点播踩过的坑

因为腾讯课堂不仅是新生成或上传的视频要上云,同时对于之前存量的几百万 MP4 视频要重新转码上传到云上,这个过程中容易踩到不少坑。这里提供一些常见的问题以及解决方案。

1. 转码出的视频清晰度不全

这里主要有 2 个原因:机构上传的视频清晰度较低,低转高不一定能转码出来,其次 1080p 不一定能转成功。


解决方案


  • 后台重新转码;

  • 客户端健壮性,对于清晰度缺少的视频播放和下载采用降级策略,降级到最近的清晰度最清晰的视频。

2. 获取腾讯云播放链接是通过 getplayinfo 接口

回包中包括 master.m3u8 和 transcodelist 两个信息,出现 master.m3u8 包含的清晰度个数和 transcodelist 清晰度个数不一致。


解决方案:后台重新转码。

3. 播放提前结束或 seek 不准确

HLS 标准中的 EXTINF 标志的切片时间总和和 TS 分片实际的时间总和不一致,导致播放提前结束和 Seek 不准确。


解决方案:后台重新转码

4. 录播视频经过腾讯云转码出现拉伸

机构上传的原视频不是标准的 720,腾讯云重新转码会出现拉伸。


解决方案:后台重新转码。

5. 播放一直加载中

因为存量视频从原来的 MP4 视频切到 HLS,偶现从后台拉到的用户上一次 MP4 播放进度同步到 HLS,超过了 HLS 视频总时长, 播放一直 loading


解决方案:客户端容错, 超过视频总时长将 Position 置为 0。


除了上面视频本身可能会出现的坑,还有客户端灰度期间兼容两种视频源同时存在切换、Next 学位和普通课程、回放分段视频切换等也容易踩坑。目前课堂建立了完善的监控,第一时间发现解决问题。


从辅导到课堂,直播回放全量上云,各项数据和用户体验都有了很大的提升,欢迎大家一起参与腾讯课堂点播上云,一起为教育点播保驾护航!


参考资料


[1] HLS 加密:https://cloud.tencent.com/document/product/266/9638


[2] 腾讯云防盗链:https://cloud.tencent.com/document/product/266/14047


本文转载自公众号云加社区(ID:QcloudCommunity)。


原文链接


https://mp.weixin.qq.com/s/JdyL3VriaFegcoQcDj6KsQ


2020-01-19 15:085618

评论

发布
暂无评论
发现更多内容

Illustrator 2021 for mac(ai 2021中文版)

Mac相关知识分享

小说

微信多开防撤回工具WechatTweak for Mac

Mac相关知识分享

【YashanDB知识库】windows配置ODBC跟踪日志, 使用日志定位问题

YashanDB

yashandb 崖山数据库 yashandb知识库

国产化新标杆:TiDB 助力广发银行新一代总账系统投产上线

TiDB 社区干货传送门

TiDB多业务合并新玩法

TiDB 社区干货传送门

8.x 实践

Minitab Express Mac数据分析统计软件 v1.5.0激活版

Rose

获取淘宝商品详情API返回值的技术实现方案

技术冰糖葫芦

API Gateway API Explorer API 接口 API 测试 pinduoduo API

TiDB 性能测试的几个优化点

TiDB 社区干货传送门

性能调优

TiDB 在线打标签实现副本调度应用实践

TiDB 社区干货传送门

实践案例 7.x 实践

昆仑万维 X TiDB|从 MySQL Cluster 到 TiDB 的升级之路

TiDB 社区干货传送门

黄东旭:“向量数据库”还是“向量搜索插件 + SQL 数据库”?

TiDB 社区干货传送门

Royal TSX v6.0.2激活版 Mac强大的远程管理

Rose

AI应用元年,豆包大模型为消费电子、游戏行业注入智能化创新动能

新消费日报

Volcano v1.10.0 版本正式发布!10大功能全面提升统一调度和细粒度资源管理能力

华为云原生团队

云计算 容器 云原生

系统安全不求人:开发者必学的漏洞防御秘籍

巧手打字通

后端 系统安全 安全漏洞 SQL注入 xss攻击

OpenHarmony外设生态春笋行动 在2024开放原子开源生态大会上开启

最新动态

海外直播软件 Bigo 的 TiDB 4.0 线上实践

TiDB 社区干货传送门

“AI+Security”系列第3期(六):打造最懂安全的智能体-无极AI安全智能体平台落地与实践

云起无垠

使用TiDB企业版Lightning导入ORC文件到TiDB

TiDB 社区干货传送门

迁移 7.x 实践

sublime text :轻量级的文本编辑器

Rose

给Java同仁单点的AI"开胃菜"--搭建一个自己的本地问答系统

京东零售技术

Java LLM

RAW 格式图像处理软件Capture One 23 Pro for mac

Mac相关知识分享

Alfred 5 for Mac(高效功能工具)

Mac相关知识分享

Service worker 入门手册

yuanyxh

JavaScript chrome Service Worker #前端

软件测试学习笔记丨Mock的价值与实战

测试人

软件测试 测试开发

【YashanDB知识库】如何dump数据文件,转换rowid, 查询对应内容

YashanDB

yashandb 崖山数据库 yashandb知识库

TiDB 助力东南亚领先电商 Shopee 业务升级

TiDB 社区干货传送门

TiSplit 切分csv文件

TiDB 社区干货传送门

迁移 实践案例 管理与运维

macos big sur 软件icons图标大全(新增至2719枚大苏尔风格图标)

Rose

功能丰富文档编辑设计工具Author for Mac

Mac相关知识分享

【YashanDB知识库】由于hist_head$中analyze time小于tab$中analyze time导致的sql语句执行慢

YashanDB

yashandb 崖山数据库 yashandb知识库

腾讯课堂点播上云客户端实践总结_安全_云加社区_InfoQ精选文章