zoukankan      html  css  js  c++  java
  • 关于直播,所有的技术细节都在这里了(三)

    关于直播,所有的技术细节都在这里了(三)

    作者:UCloud云计算
    链接:https://zhuanlan.zhihu.com/p/23531863
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    引言

    网络视频直播存在已有很长一段时间,随着移动上下行带宽提升及资费的下调,视频直播被赋予了更多娱乐和社交的属性,人们享受随时随地进行直播和观看,主播不满足于单向的直播,观众则更渴望互动,直播的打开时间和延迟变成了影响产品功能发展重要指标。那么,问题来了: 如何实现低延迟、秒开的直播?

    先来看看视频直播的5个关键的流程:录制->编码->网络传输->解码->播放,每个环节对于直播的延迟都会产生不同程度的影响。这里重点分析移动设备的情况。受限于技术的成熟度、硬件环境等,我们针对移动场景简单总结出直播延迟优化的4个点:网络、协议、编解码、移动终端,并将分四期来一一解密UCloud直播云实现低延迟、秒开的技术细节。


    本篇是该系列的第三篇,上篇《关于直播,所有的技术细节都在这里了(二)》中,我们讲述了直播应用层协议及传输层协议的选择以及对直播体验影响的分析 。本篇中我们将介绍在传输直播流媒体过程中的内容缓存与传输策略优化细节原理。



    基础知识:I帧、B帧、P帧

    I帧表示关键帧。你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成。(因为包含完整画面)

    P帧表示这一帧跟之前的一个关键帧(或P帧)的差别。解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)

    B帧是双向差别帧。B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况)。换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。

    B帧压缩率高,但是编解码时会比较耗费CPU,而且在直播中可能会增加直播延时,因此在移动端上一般不使用B帧。


    关键帧缓存策略

    一个典型的视频帧序列为IBBPBBPBBP……

    对于直播而言,为了减少直播的延时,通常在编码时不使用B帧。P帧B帧对于I帧都有直接或者间接的依赖关系,所以播放器要解码一个视频帧序列,并进行播放,必须首先解码出I帧,其后续的B帧和P帧才能进行解码,这样服务端如何进行关键帧的缓存,则对直播的延时以及其他方面有非常大的影响。

    比较好的策略是服务端自动判断关键帧的间隔,按业务需求缓存帧序列,保证在缓存中存储至少两个或者以上的关键帧,以应对低延时、防卡顿、智能丢包等需求。



    延迟与卡顿的折中

    直播的延时与卡顿是分析直播业务质量时,非常关注的两项指标。互动直播的场景对延时非常敏感,新闻体育类直播则更加关注播放的流畅度。

    然而,这两项指标从理论上来说,是一对矛盾的关系——需要更低的延时,则表明服务器端和播放端的缓冲区都必须更短,来自网络的异常抖动容易引起卡顿;业务可以接受较高的延时时,服务端和播放端都可以有较长的缓冲区,以应对来自网络的抖动,提供更流畅的直播体验。

    当然,对于网络条件非常好的用户,这两项是可以同时保证的,这里主要是针对网络条件不是那么好的用户,如何解决延时与卡顿的问题。

    这里通常有两种技术来平衡和优化这两个指标。

    一是服务端提供灵活的配置策略,对于延时要求更敏感的,则在服务端在保证关键帧的情况下,对每个连接维持一个较小的缓冲队列;对于卡顿要求更高的直播,则适当增加缓冲队列的长度,保证播放的流畅。

    二是服务端对所有连接的网络情况进行智能检测,当网络状况良好时,服务端会缩小该连接的缓冲队列的大小,降低延迟;而当网络状况较差时,特别是检测到抖动较为明显时,服务端对该连接增加缓冲队列长度,优先保证播放的流畅性。


    丢包策略

    什么时候需要丢包呢?

    对于一个网络连接很好,延时也比较小的连接,丢包策略永远没有用武之地的。而网络连接比较差的用户,因为下载速度比较慢或者抖动比较大,这个用户的延时就会越来越高。

    另外一种情况是,如果直播流关键帧间隔比较长,那么在保证首包是关键帧的情况下,观看这个节目的观众,延迟有可能会达到一个关键帧序列的长度。上述两种情况,都需要启用丢包策略,来调整播放的延时。

    关于丢包,需要解决两个问题:

    一是正确判断何时需要进行丢包

    二是如何丢包以使得对观众的播放体验影响最小。较好的做法是后端周期监控所有连接的缓冲队列的长度,这样队列长度与时间形成一个离散的函数关系,后端通过自研算法来分析这个离散函数,判断是否需要丢包。

    一般的丢帧策略,就是直接丢弃一个完整的视频帧序列,这种策略看似简单,但对用户播放的影响体验非常大。而应该是后台采用逐步丢帧的策略,每个视频帧序列,丢最后的一到两帧,使得用户的感知最小,平滑的逐步缩小延时的效果。

    ——————

    以上就是UCloud直播云:内容缓存与传输策略优化细节原理。

    关于终端优化,请参阅即将发布的《关于直播,所有的技术细节都在这里了(四)》。

    敬请期待!


    相关阅读推荐:

    关于直播,所有的技术细节都在这里了(二)

    关于直播,所有的技术细节都在这里了(一)

    ​本文由『UCloud流媒体研发团队』提供。

    「UCloud机构号」将独家分享云计算领域的技术洞见、行业资讯以及一切你想知道的相关讯息。

    欢迎提问&求关注 o(*////▽////*)q~


    以上。

  • 相关阅读:
    Python3学习笔记22-文件读写
    Python3学习笔记21-实例属性和类属性
    Python3学习笔记20-获取对象信息
    Python3学习笔记19-继承和多态
    Python3学习笔记18-访问限制
    Python3学习笔记17-类与实例
    Python3学习笔记16-错误和异常
    Python3学习笔记15-迭代器与生成器
    Python3学习笔记14-迭代与列表生成式
    Python3学习笔记13-函数的参数
  • 原文地址:https://www.cnblogs.com/zhehan54/p/6362308.html
Copyright © 2011-2022 走看看