6月24日,又拍云OpenTalk |2018音视频技术沙龙·上海站顺利落幕,这是又拍云OpenTalk | 2018音视频技术沙龙系列活动的第二站。作为又拍云技术分享的看家活动,本次OpenTalk邀请了网易云、谷人云、又拍云、战旗等四家公司的讲师。四位讲师在活动中拿出了看家本领,为到场、观看直播的观众贡献了精彩的分享!

战旗直播高级流媒体研发工程师石硕,在现场分享了《视频直播的用户体验体系与质量监控方案》,重点介绍了直播质量监控方案的搭建,以及直播卡顿、延时监控、首屏秒开三个方面的优化。

  • 直播质量评价体系

  • 直播质量监控方案的结构和逻辑

  • 卡顿优化的十条法则

  • 延时监控:自定义扩展、数字水印

  • 首屏秒开的三个优化方向

image.png

△  石硕:战旗直播高级流媒体研发工程师

以下是石硕分享内容的整理:

大家好,我是来自战旗直播平台的高级流媒体工程师石硕。今天我主要讲两个内容:第一方面,直播、点播的整体用户体验体系。现有公开场合讲整体用户体验体系的内容偏少一点。另一方面,“质量监控方案”,这也很少有提及的。

从本质上来讲,用户体验和质量监控,做的是一件事情,即:在一定程度上保证用户观看直播的体验是较好的。

我的分享内容主要分为四个部分:

  • 直播质量评价。用户体系覆盖了哪些方面,用户整体的体验由几部分组成的。

  • 卡顿监控与优化。卡顿优化依赖于监控体系如何发现卡顿现象。

  • 延时监控的难题。视频延时监控存在难题,因为现在业界对于“延时”的监控还是比较欠缺,商用方案里面还没有看到比较切实有效的办法。

  • 首屏优化要点。首屏优化在行业里讲得比较多,我简单罗列一下要点。

  

直播质量评价体系

直播质量评价这一块,先讲一下音视频的质量评价体系。

音视频评价起源比较早。早在1996年,ITU国际组织就已经有了主观评价流媒体音视频的传输质量,当时主要评测电话的通话质量。然后在2003年根据个人主观评价提出了一套MOS体系,2012年、2013年对MOS体系进行了不同方面的补充,推出了vMos体系。

今天我主要讲华为的U-vMOS主观质量评价体系。一方面,对整套体系,国内中文的资料比较充实;另一方面,U-vMOS在vMOS的基础上面做扩展的,U-vMOS的整个质量体系,也是在vMOS内容里面的。

MOS质量评价的主要目的,是根据用户的主观体验来对音频或者是视频质量进行评分。它的分值,常规意义上是分为五分,分值越高它的质量就越好。

image.png

△  MOS质量评价

image.png

△  U-vMOS质量评价的建模方法

MOS质量评价体系针对音频质量。视频质量的评价可以在这个基础上做一个延伸,具体看一下U-vMOS质量评价体系。

U-vMOS将视频质量评价分为三个部分:

  • 视频质量,指视频的分辨率、帧率、码率、编码级别;

  • 互动体验,主要指被叫视频载入时间的长短;

  • 观看体验,主要指画面的花屏和卡顿。

针对视频质量的各种相关因素,其中我们能取到的“典型分值”的“分”,主要是播放设备的屏幕尺寸及视频的分辨率,这两个相关度是比较大。

 

视频质量的评分

image.png

△  视频质量:视频分辨率与屏幕尺寸的关系

4分以上可以算是比较好的观看体验,看这张表格,4.5寸、5.5寸的手机屏幕,都至少需要有720P的视频流才能达到4分以上。那我们做手机的视频服务时,如果用户对于视频的要求不是特别苛刻,通常情况来讲720P足够了;个别提供1080P,其实对观看体验并没有特别大的提升,仅从4.3分提升到4.6分,这个过程不光对码率有要求,视频帧率、解码难度都会高出很多。

一般电视端想要达到4.0分以上的观看体验的话,需要1080P的视频。这个表格对直播企业的对于视频流分辨率的选择是具有一定参考意义的。

 

视频体验,首屏秒开的标准

互动体验,主要是涉及到常规意义上所讲的“首屏秒开”。首屏秒开通常被认为在100毫秒以内才算完美。

这个要求是局域网环境下,公网环境下首屏秒开达到100毫秒的几乎没有,或者说特别少。常规意义上,我们都会努力让首屏秒开做到1秒也就是1000毫秒左右的时间。

我们能了解到的,现有像快手、斗鱼、虎牙这一类的App,通常首屏时间都会做到3秒以内。3秒是一个界限,大家一般是2秒左右。

image.png

△  互动体验(首屏秒开)的典型分值

 

观看体验:花屏不再,重在优化卡顿

观看体验包括两部分:花屏和卡顿。

现在直播平台在又拍云等CDN服务商的努力下,“花屏”已经出现得很少了,主要影响观看体验得因素是“卡顿“,主要指的是在一分钟内卡顿出现了多少次,每一次卡顿的时长有多少,得出来一个卡顿的时长占比。观看体验的质量评价体系是实验室环境下得出的。

image.png

△  观看体验的典型分值 (卡顿统计周期1分钟)

  

直播质量监控方案的结构和逻辑

国外针对于这一套体系的执行方面可能会更多一些,国内企业目前来说主要关注的可能是卡顿和首屏秒开。延时的话,关注相对会少一些。

我们重点讲一下卡顿的优化体系,包括“卡顿监控”,以及监控的结果收集完之后进行的一些优化工作。

image.png

△  直播质量监控系统组成

卡顿主要分为四个部分:数据收集、数据分析、数据展示、预警系统。

数据收集,收集主播端和观看端的设备信息、网络环境。设备信息主要是指设备机型、用户IP,以及视频流的分辨率、码率,包括播放过程中的CPU使用率、GDP使用率、内存使用率。网络环境,主要指连接方式。还有一些需要探测才能得知的数据,比如:优先收集手机到本地路由器的网络情况,然后收集手机到公网出口的环境,以及手机到CDN节点的网络情况。第三部分数据是正常监控需要的,包括卡顿数据、首屏数据、延时数据。

数据分析,收集完之后,放到大数据中心做一些数据过滤、综合分析;把用户ID分门别类的处理成我们实际上运营需要的监控数据。

第三是数据展示,这一块主要是地图展示。在一张地图上面,把卡顿率及其它的一些数据展现出来,就是观看会更方便一些。这是战旗整体卡顿监控的监控图表,左下角标注了卡顿率从低到高,可以看到,战旗的卡顿率应该在“4”个点以内,一般是3点多。

image.png

△  卡顿数据展示示意图

第四部分是预警系统。这一块主要是运维人员及CDN厂商。常规意义上,这个预警通常会直接给自己公司的运营人员。但是做直播的,基本上都会用到CDN厂商的云加速服务。如果我们发现用户卡顿的话,其实会分析得出来用户卡顿原因是CDN某个节点不好,把这个分析反馈给CDN,让CDN进行相应的调整。

 image.png

△  卡顿监控体系的运行逻辑

整个监控体系,我们这边可以简单的分为五大部分:客户端、监控系统、运维支持、智能调度、CDN厂商。

监控系统首先是给运维支持,然后是给CDN厂商,告诉发生了某个事。然后是给智能调度系统,这一部分的报警级别相对低一点,是针对个别用户的报警。我们可以针对用户报警,根据他的硬件设备情况及网络情况做一次智能调度。比如:探测到带宽不够,发生了卡顿;调度系统只需要给客户端发一条命令,告诉它带宽不够,让它把码率降一级,可能卡顿情况就会缓解。

 

卡顿优化十条法则

针对于卡顿优化,我们这边可以分为十个部分:

  • HTTP-DNS调度

  • 播放端本地调度

  • 服务端智能调度

  • 服务端手动调度

  • CDN手动调度

  • 使用UDP推流

  • 推流端流畅度监控

  • 提供多种清晰度选择

  • 播放器优化

  • 用户反馈系统

HTTP-DNS调度:在国内DNS污染会比较严重,可能会把DNS解析到错误的节点上去。这个解析服务,可能会把你的域名,比如把海徐汇区的域名解析到浦东新区去。我们尽可能去避免这种错误,这个时候就需要HTTP-DNS调度。我们每次拉一个地址之前,使用自己的服务器先做一次解析,保证每次反馈给你是较近的服务节点,这就会比较流畅。

播放端本地调度:如果发现用户播放比较卡顿,我们本地会有一些检测机制。比如检测是硬件CPU不高,CPU使用率超高了,我们可能就会把它的分辨率、解码率降一下,让CPU有所缓解,这个时候卡顿就会缓解。另外,也可能是网络导致的本地卡顿,我们就可以给他换一个服务节点,或者是做一些其它的处理。

服务器端智能调度、服务器端手动调度:服务器端的智能调度、手动调度,这个主要是在后端通过远程方式去做一些调整。在智能调度系统里面,我们会根据用户的情况做统一调度。比如用户硬件不够了,我们帮他加一点。如果用户卡顿的话,我们先要判断是CDN节点的问题,还是用户自己的问题。如果是CDN节点的问题,我们帮他自动调到下一个节点去。

CDN手动调度:指手动干预的方式。比如:现在发生了用户卡顿,智能调度系统比如发现上海徐汇区的一个服务节点特别不好,我们可以手动把这个节点拉黑掉,用户不会访问到这个质量比较差的节点。

第四点、第五点是会有一定的重合度,因为CDN的手动调度也是根据智能调度系统收集到的数据、下发的数据来进行相应的一些处理。

UDP推流:TCP的协议容灾和慢恢复机制导致它抵抗网络抖动的能力会比较差。为了解决因为网络抖动导致的卡顿问题,我们会使用“自定义”或者是自有UDP协议处理这个问题。谷歌之前有推出类似于“类UDP”的各种SDK包,使用UDP代替TCP对抗网络抖动,可以把TCP的容灾机制、恢复机制规避掉,可以快速地恢复网络。UDP还有一个作用,在丢包的情况下“抗丢包能力”比较好,它可以自己自主决定“重发多少数据包”。

推流端流畅度监控:这一块主要是监控主播推流是否有音视频不同步或者帧率不够的情况。如果主播端卡顿的话,所有的用户调度到任何节点都会卡顿,所以推流端监控相对会重要一些。针对于主播端的监控,我们实时反馈给主播,让主播切换网络或者是做一些调整。

提供多种清晰度选择:提供多种清晰度选择,这个主要针对于用户手动操作的。通常情况下会提供标情、高清、超清等多种分辨率。不同的分辨率对应的码率、编码复杂度都是不一样的。清晰度越高,相应解码的难度就会越高。让用户可以手动去选择,在整体情况比较好的时间,他可以提高清晰度。当发生卡顿的情况下,可以手动降清晰度或者是降分辨率,可以解决一部分卡顿的问题。

播放器优化:播放器的优化,针对于卡顿主要是处理两个事情:一个是音视频不同步导致的卡顿。第二部分,主要是针对于缓冲区的处理,缓冲区相对于对抗“网络抖动”是比较有用处的。

用户反馈系统:这一块是用户主动提供一些卡顿的建议或者问题,用户的反馈系统可以作为我们整体监控系统的一个补充,可以帮我们改善整个监控系统。

 

延时监控:自定义扩展、数字水印

下面讲一下“延时监控”。“延时监控”我主要讲两个部分的内容:

第一部分,开发阶段延时的计算及延时的优化;

第二部分,发布阶段的延时计算。

通常情况下,直播研发的开发阶段的延时都会以“北京时间”的方式做对比。

image.png

△  左图是推流端本地的“北京时间”,右边是播放器播放的“北京时间”

开发阶段的延时,推流工具、播放工具在同一台机器上。左边的时间减去右边的时间,实际上就是直播延时。我们可以看到上图的直播延时是2秒2毫秒。

开发阶段的延时计算到了发布阶段已经不管用了,因为正常情况下不可能实时盯着用户手机看“延时多高”,也不可能在视频流里面嵌入一个“北京时间”。

发布阶段延时计算需要借助一些另外的手段,一种方式是自定义扩展,一种方式是数字水印。

 

自定义扩展实现延时监控

自定义扩展利用直播协议里面的一些自定义字段做延时监控。

一个选择是FLV协议的metadata字段。FLV协议本身有字段,可以嵌入,然后在推流时发“北京时间”放到这个metadata字段里面去,接到之后把它和本地的“北京时间”做差值。

第二个可以扩展的地方,是H.264、H.265编码的SEI字段,这个字段也可以自定义做扩展,计算延时的方法也是相同的,就是在这个字段里面嵌入“北京时间”就可以了。

自定义扩展的两种方法有好处——配置比较简单。

当然也有比较难的地方。因为CDN本身会有转码系统和分发系统,如果不和CDN厂商强调的话,所有的自定义字段从CDN系统过一遍之后全部都会删除掉。

还有一个有问题的地方,在于CDN分发视频流,默认会把所有的视频流,无论是从什么时间开始拉流的,都会“从零开始”。这个时候我们在字段里面嵌入的“北京时间”,实际上就没有参照对象,因为我们是根据视频流里面每一帧视频的时间,以及嵌入到自定义字段的时间,还有本地时间三者做“差”得到的延时,这一部分会有影响。

 

数字水印实现延时监控

基于前面两种方法的缺点,然后我们又扩展出了根据“数字水印”来嵌入数据计算延时的方法。“数字水印”出现得比较早,原来是用于音视频版权确认,在音视频嵌入不可见、听不到的数据,这对于整体音视频质量影响比较小,但是通过某种算法可以嵌入进去、可以被提取出来,主要是应用在这个方面。

我简单讲一下“数字水印”的原理,数字水印可以嵌入的地方比较多。

先了解下通过修改YUV原始数据或PCM原始数据植入数字水印。以720P分辨率的视频流为参照,每一张画面是1280×720像素点,每个像素点是由一个Y以及1/4U、1/4V组成的。通常情况下在Y里面,每一个Y像素是有8比特数据组成的。也就是说,数据范围可以从-127到127。Y数据总共有8比特,我们可以把它末三位抹掉,然后再嵌入我们想要的数据。比如:我们想要的第一个Y像素点里面,就嵌入一个数字“0”或者是“1”,我们可以把8比特后3位抹掉,在里面嵌入后3位是“0-7”的,我们嵌入一个“3”代表“0”,嵌入一个“6”代表“1”。嵌入之后,然后根据同样的方式把这个方式再提取出来,然后把这个数据再还原,就可以得到我们嵌入的YUV里面的数据。这种方式嵌入的话,会有一定的影响。因为正常情况下,我们知道Y数据是“-127”到“127”。末三位改变以后会对色彩有影响。数据准确率越高,就需要抹掉的比特位数越多,对于视频的损伤就越大。我们想要准确度越高,又需要比较多的比特位数,这个时候就需要做一些取舍。

PCM也是同样的方式,在末位不重要、比较小的数据上面做一些修改。

再看下通过AAC量化子带或H.264块的DCT参数实现数字水印。

AAC量化子带由一系列的参数组成的,我们可以改写参数第一位。

H.264块的DCT参数,相应这个参数的修改方法也是一样的,改第一位的不重要的这些数据。

客观地讲,刚才几种方式里面,在数据的嵌入、提取的过程中会受到CDN转码系统的一定影响。因为正常情况下,我们知道从YUV数据到H.264重新再解码出YUV的时候,这个YUV数据其实是发生了一些变化,只是这个变化被控制在一定的范围内,绝大多数的情况下是看不出差别。

这个时候,在刚才讲到的这些算法之上,延伸出了一些算法,针对于这些数据的这些参数;我们刚才讲的是直接在这些数据里面做修改,做延伸处理的方法是把这些数据放进,像压缩通常会用到的“离散预选”参数。这个算法相对来说,对于原始数据的修改会更小,然后提取的成功率也会更高。

  

首屏秒开的三个优化方向

简单过一下首屏秒开优化的要点。首屏优化的话题可能会特别多,我这里就不一个一个去解释了;这里提供首屏秒开的三个优化方向,有优化需求的话,按照推流、转发、播放三个方向去做优化,肯定能收到效果。 

推流优化——主播端:

  • 合理的GOP值(建议2秒)

  • 减少帧间依赖,不使用P帧

  • X264无延时编码

  • 合理的分辨率、码率、帧率

  • 使用UDP对抗网络抖动

转发优化——CDN

  • 缓存GOP数据

  • 提前预热资源

  • TCP单边加速

  • 提供多路转码流 

播放优化——播放端

  • 优先加载视频流数据

  • 可变缓存,先小后大

  • 使用HTTPDNS分配节点

  • 优化FFmpeg视频流探测

  • 网络请求并行加载

我今天讲的内容大体上就是这些,谢谢大家的聆听。

问答部分

Q1:赛事直播、游戏直播的时候,主播推流一定会延迟。昨天我遇见一个主播,延迟就已经有20秒,也就是说在编码完了之后,会有20秒才会推出来,这样的话,数字水印是不准确的。我看战旗也有很多游戏主播,这个问题怎么解决的?

石硕:这分为两方面。我们如果要做延时计算,相应来说直播用的工具我们是可控的。像刚才您讲的情况,应该是这个主播用的是开源的OBS推流工具。针对于OBS的推流工具,我们需要做一些特殊的处理。战旗为OBS开发一个插件,这个插件是嵌入视频水印的。第二这个插件要获取OBS缓冲延时,把这个数据获取之后,针对嵌入的视频水印会做一些特殊处理。如果是用自己的直播软件,相应的来说时延就是本地的缓冲区都是自己设置的,相应做一下处理就好了。

Q2:我前两天刚上线了网页端的H.265,码率比较低;发现卡顿主要原因来自于硬件情况,比如CPU不够或者GPU不行。我考虑在网页端加一些什么样的东西,获取到用户的硬件情况,然后发现能获取到的硬件情况非常有限,跟移动端在上H.265完全不一样的状态。国内主流的浏览器可以获取到用户的内存情况,但获取不到GPU等信息,即便有问题很难定位。战旗在这一块,目前是怎么解决的?

石硕:这是一个很好的问题。现在主流的浏览器、比较常见的浏览器,通常情况下如果用HTML5做直播,会默认更多得去选硬件。受限于浏览器,我们是拿不到GPU信息的。这个时候,我们会获取一些再外围的数据信息,比如去拿CPU型号,进而获取GPU信息。某几个GPU幸好解1080P确实不行,这个时候我们可以尝试把它的分辨率从1080降到720P,这个时候它的GPU是能吃得消的。