每当大型活动和赛事来临, 对于视频平台来说, 高涨的不仅仅是人气, 还有大流量视频分发上的挑战,虽然有CDN平台,但流量突发,很可能会遇到意想不到的问题。这是因为突发流量,骨干网就会有瓶颈,若是预估不准、CDN资源准备不足,还会伴有更严重的视频分发质量问题。
P2P则是解决这个问题的良方,自古至今还没有那个系统可以宣称能很好地抗突发,除了P2P是一个例外,它宣称:看的人越多,效果越好。
众所周知,欲想P2P,必须得经过三步:
- 按照固定格式分割数据切片,这将是点对点对等网络相互分享的最小数据单元;
- 连接CDN、连接其他节点分别获取不完整的数据分片;
- 按照分片原来的组织方式,还原出最初的数据,并交付。
接下来将结合这三步,从连接、切片的方式逐步介绍X-P2P在Web HLS P2P上的实践。
| WebRTC
把时间拨回到2020年12月20日,彼时chrome吹响了下线flash的冲锋号,意味着flash时代落下帷幕。随之落幕的还有一整个flash的生态,包括flash动画、flash游戏、flash音视频等,其中flash音视频被H5内置的audio、video取代,带有P2P能力的RTMFP也被更加规范的WebRTC替代。
那WebRTC如何作用到P2P音视频辅助分发加速呢?
前面有几篇文章已经隆重介绍过WebRTC的很多概念,作为实时媒体传输界标准的WebRTC,其中就有ICE打洞穿越和节点间的传输协议,详见这篇「技术解码 | WebRTC ICE 模块剖析」。
诚然,P2P的重要基础便是先能让节点能够直连,并且提供节点间相互传输的能力,恰好WebRTC都解决了,虽然WebRTC的ICE十分复杂,但好在js的接口还算简单、易用。又因当前对称型NAT越来越多的情况下,造成WebRTC的真实打洞成功率很低,在国内环境只有20%,但对于P2P内容辅助分发网络而言也足够用了!
这里还想说一句题外话,解释一下实际上WebRTC流媒体的一个误区:如果问WebRTC如何实现的低延迟实时通信,大部分人会不假思索地给出“因为WebRTC用的UDP直连啊!”然而,这显然不是单纯的UDP和直连做到的,而是在UDP上做的复杂的传输协议和应用逻辑支撑的,其复杂性甚至远超TCP了,实际上WebRTC也极其庞大复杂;实时通信也不是靠直连达成的,因为上文说到WebRTC在国内环境打洞成功率很低,而且直连通道选择不当并不比云中转通道好。
| 什么是HLS?
HTTP-FLV是典型的流式载体,在国内有很多应用,然而其需要经过一道切片处理确认最小分享数据单元才能P2P,受限于各种实现切片方式的不同,故而很难达到统一。HLS则不同,天然就是切片,天生就适合P2P,可以做到无论使用哪家CDN,都能愉快地进行P2P。
HLS 全称是 HTTP Live Streaming,是一个由 Apple 公司提出的基于 HTTP 的媒体流传输协议,用于实时音视频流的传输。目前HLS协议被广泛的应用于视频点播和直播领域.。HLS 协议由三部分组成:HTTP、M3U8、TS。这三部分中,HTTP 是传输协议,M3U8 是索引文件,TS 是音视频的媒体信息。
HLS协议基于最基本的HTTP协议,因此可以轻松的使用已有的CDN设施来分发流媒体。
HLS的基本播放流程:
- 播放器向server请求主M3U8, 获得2级M3U8列表, 列表中包含了不同码率的M3U8;
- 播放器选择一个码率, 向server请求对应的2级M3U8, 返回TS或CMAF列表;
- 播放器下载TS开始播放;
- 播放器根据网络状况自动选择合适的TS码率。
如上, 播放器面对多个码率, 需要结合自身网络带宽情况, 选择一个最合适的码率, 即能平稳播放不卡顿, 又能看到最清晰的视频. HLS支持的这一特性即为自适应码率(ABR Adaptive Bitrate Streaming)。这也是HLS的最大优势之一:通常在遇到弱网时,视频播放质量优化不下去的时候,没有什么更好的办法来创造带宽了,只能降码率或者丢帧!
| 基于HLS的P2P
目前PC浏览器, 除Apple的safari外, 基本都不会支持HLS直接播放。由此, 业界大神创建了hls.js项目,项目的原理是基于浏览器的MSE接口,将HLS转封装为fMP4,曲线救国让浏览器播放转封装后的MP4。
基于hls.js已有的工作,再集成XP2P将十分容易,直接拦截本来该向CDN发起的ts请求,改为向其他节点或CDN混合请求的方式去获取ts,其中CDN用于兜底。XP2P只代理请求获取ts数据,同时将ts数据的下载性能(如耗时)反馈给hls.js,即可让hls.js内部的自适应码率模块依然正常工作,而XP2P则能够代理请求变换码率之后的ts,这种方式让接入十分简单,仅需数行代码即可快速集成hls.js,同时XP2P还提供通用接口, 其他HLS播放器均可集成. 目前已经服务于央视网等客户, 承担了其大型赛事的辅助内容分发加速。
const video = document.getElementById('video');const hls = new Hls(); // 创建hls.js实例
// 接入SDKif (HLSP2P.isSupported()) { // 首先确定是否支持sdk const hlsp2p = HLSP2P.create(hls, config); // 创建sdk实例 hlsp2p.on(HLSP2P.Events.Rollback, () => { // 监听sdk抛出的异常 hlsp2p.destroy(); // 销毁sdk });}// 接入ok了
| 自适应码率的挑战
前面提到的自适应码率功能,无P2P时, 是基于CDN下载耗时统计的基础上。当引入P2P后, 便打破了这个定式,XP2P仅仅是做纯碎的代理请求获取ts,那从不同节点获取ts的速度也不尽相同,更不似向CDN请求获取ts一样稳定,然而绝不能因为向一个差的节点请求获取ts慢了,就要切换到低码率,亦不可因向一个优质节点请求获取ts快就立刻切到高码率,决定码率切换的每一个ts的下载时长等关键数据又是XP2P提供的,因此XP2P还是影响到自适应码率决策的,这其实是XP2P遇到的一个十分棘手的问题。
码率选择的原则如下:
- 确保观看稳定, 不会经常随意跳变码率,随意跳变将很影响观看体验;
- 观看的码率匹配当前网络带宽。
因此存在如下两种码率选择方式:
- 根据播放器过往的请求, 预测即将需要的码率, 通过和其他用户P2P传输;
- 假定播放器当前处于稳定状态, 假定后续播放都使用当前的码率。
相比于第一种P2P自行预测播放器即将播放的码率, 会极大增加实现的复杂度, 我们在这里选择第二种策略,因为通常一个人的播放在发生波动后, 最终播放器会趋于收敛到某个码率。
由于P2P可能会提前缓冲好ts切片, 当播放器请求到达时, 会一瞬间将数据返回给播放器, 如此会导致播放器对网速预估产生偏差, 进而影响自适应码率的效果, 导致码率切换不准确和码率切换频繁。
为了避免上述情况, P2P SDK采用加权移动平均算法, 使用过往CDN/P2P的ts下载信息, 估算出当前返回给播放器P2P 数据的下载时长信息, 并且通过对加权参数的调优, 使得P2P下的自适应码率效果可以媲美纯CDN。
| 支持多CDN云厂商调度
通常为了确保服务的可用性,客户会选择多家CDN云厂商进行调度。使用纯CDN的时候,在CDN云厂商之间相互调度没有什么问题,而一旦集成了多云厂商的P2P服务,就要确认P2P是否能跨云厂商使用。
虽然HLS有着天然的切片, 但却依然有可能不同云厂商间的ts内容不尽一致,一方面是因为每家CDN厂商边缘节点缓存的hls切片更新不及时,一方面还有hls转码时不同云厂商转码集群不同的原因。本来XP2P是仅限与腾讯云CDN联合使用的,后来经过深思熟虑,我们认为客户使用多云策略是一个强需求,况且hls切片比较统一,都是ts文件,只不过不同云CDN分发的ts文件内容不尽相同,最终XP2P后来支持了多云CDN服务下的加速分发方案。实现方式也很简单,即本来认为URL中的path唯一代表一个ts,可相互分享,但这只适用于单一云原则;为了扩展到多云原则,将域名 path组合起来唯一代表一个ts,即让同一个云CDN服务商下的用户才相互分享,就可以了。
| P2P技术对网络的优化
除了降低成本,合理利用P2P对降低网络负载、提升观看体验也有很好的效果。早些年运营商对P2P技术实施封堵策略,在带宽不充裕的年代,P2P技术确实占用了大量的网络带宽。但如今基础网络设施早已与当年不可同日而语,合理的利用P2P技术,反而会降低网络的压力!
传统的云-端传输,需要每个播放器都访问到CDN的边缘节点。即使两观众处于同一局域网,依然要分别从CDN边缘节点拉取直播流,对于边缘节点而言,同样的数据被同时重复发送两次,占用两份带宽。
这里要提一下组播技术。组播技术源于IP通信, 传统的IP通信有两种:
- 单播: 是源主机和目标主机间的点对点通信;
- 广播: 是源主机的数据包, 子网中所有的主机都会收到。
此时源主机要将数据包发给部分主机,如果采用单播的方式,给每个目的主机都发送一次,那么重复的包不仅占用大量带宽,而且会增加主机的负载。如果采用广播的方式,那么会浪费大量带宽。因此传统的广播和单播都不能解决这种单点发送多点接收的问题。
组播是用来以最小的开销解决单点发送多点接收的问题,如图示,假设Host B、Host D、Host E在同一个组播,借助组播路由协议,数据在离接收者近的地方才开始复制分发。
P2P技术和组播有着异曲同工之妙,举例来说,小区内有多个人观看同一视频,其中用户A从CDN拉取数据,并分发给其他人,即实现了CDN只分发一份,邻域网内的其他主机也可以获取到数据,此时A充当了组播路由器的角色。如下图,相比于组播中组播路由器同时拷贝数据给目标主机,P2P这种方式称得上为某种形式上的"异步组播"。因此在合理利用P2P的基础上,广域网的网络负载实际是在降低的。
最后:
腾讯云XP2P从2017年开始护航多家头部直播平台英雄联盟S赛。2020年S10赛事, XP2P量级近20T,千万在线量级。我们基于自研高效传输协议和极高的NAT穿透成功率,构建起强大的万物互联框架。借此基础,高性能精简的sdk可运行于安卓、iOS、Window、Linux、Web乃至智能路由器、IoT摄像头。未来,我们将继续打磨产品,为客户提供更低延迟,分享率更高,网络更友好的XP2P服务。
参考:
高清视频点播-AI让你看片更丝滑:https://cloud.tencent.com/developer/article/1153315?fromSource=waitui
组播概述:http://www.h3c.com/cn/d_200805/605846_30003_0.htm