AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

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

  • 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:085756

评论

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

Python黑科技揭秘:多窗口操作不再是难题,这些技巧让你轻松搞定

测吧(北京)科技有限公司

测试

读TiDB源码聊设计:引子

泊浮目

分布式数据库 TiDB HTAP

Dapp/DeFi/Swap交易所代币质押项目挖矿系统开发详情

l8l259l3365

Python黑科技揭秘:多窗口操作不再是难题,这些技巧让你轻松搞定

测试人

Python 软件测试 自动化测试 测试开发

华为云命令行工具KooCLI—高效云端管理的秘诀

华为云PaaS服务小智

云计算 API 华为云

春招开始,面试也多起来了

王磊

Java 面试

QCN9274/Super WiFi 7: Explore the unlimited potential of next-generation networks

wallysSK

RDS for MySQL Serverless公测上线:弹性伸缩,最高可降成本超80%

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 华为云Serverless

如何防止 Elasticsearch 服务 OOM ?

极限实验室

ES console Gateway easysearch

国内主流AI大模型都是Python 开发的,国外AI大模型是什么语言开发的?为什么要用python?

算法的秘密

Amazon Q :企业级的对话智能导航

亚马逊云科技 (Amazon Web Services)

LED户外广告屏寿命的关键因素及解决方案

Dylan

广告 维护 系统维护 LED显示屏 户外LED显示屏

详解Python中sys模块的功能与应用

华为云开发者联盟

Python 开发 华为云 函数 华为云开发者联盟

Programming Abstractions in C阅读笔记:p312-p326

codists

算法与数据结构

内含资料下载丨黄东旭:2024 现代应用开发关键趋势——降低成本、简化架构

PingCAP

数据库 TiDB AI技术 应用开发

掰扯掰扯需求分析:从工程到生活中的4个case

泊浮目

系统设计 需求分析

小红书笔记详情API:为开发者开启的新世界大门

技术冰糖葫芦

API 接口 API】

【FAQ】HarmonyOS SDK 闭源开放能力 —Account Kit

HarmonyOS SDK

HarmonyOS

探索Terraform实践:优化基础设施管理

SEAL安全

架构 运维 Terraform

为什么说 TiDB 在线扩容对业务几乎没有影响

PingCAP

数据库 TiDB TiKV

Selenium帮助你轻松实现浏览器多窗口操作

霍格沃兹测试开发学社

教你用Ubuntu快速搭建饥荒服务器

华为云开发者联盟

开发 华为云 华为云开发者联盟 华为云服务器 饥荒

AmzTrends x TiDB Serverless:通过云原生改造实现全局成本降低 80%

PingCAP

数据库 数据分析 云原生 TiDB

JavaScript之structuredClone现代深拷贝

南城FE

JavaScript 前端 深拷贝

请查收!“全国大学生智能汽车竞赛”线上赛备赛指南

飞桨PaddlePaddle

人工智能 百度 AI BAIDU 百度飞桨

2024中国云计算大分野:重回当年,还是走向未来?

脑极体

云计算

请认真对待你的简历

老张

面试 简历优化 简历

深入了解手机App开发:从构思到上线的全过程

天津汇柏科技有限公司

数字化转型 低代码开发 定制软件开发 软件开发定制

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