企鹅电竞直播关键技术大揭秘

2019-05-31 10:40:16 浏览数 (1)

16年壮观的直播百团大战相信大家历历在目,至19年初所剩无几的直播寡头,来去如风的直播战场,离不开背后强大的直播技术支撑,本文通过直播基础技术介绍、剖析企鹅电竞直播构架、关键技术、常见问题排查、带领大家了解直播技术细节。

直播基础技术扫盲

分辨率

分辨率是度量位图图像内数据量多少的一个参数。通常表示成每英寸像素(Pixel per inch, ppi)和每英寸点(Dot per inch, dpi),包含的数据越多,图形文件的长度就越大,也能表现更丰富的细节。但更大的文件需要耗用更多的计算机资源,更多的内存,更大的硬盘空间等,另外平常我们习惯的分辨率叫法如720P,实际上是指分辨率1280*720像素——可以计算就是1280×720=921600像素。

色彩空间(RGB/YUV)

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色。

YUV主要用于优化彩色视频信号的传输,使其向后相容老式黑白电视。与RGB视频信号传输相比,它最大的优点在于只需占用极少的频宽(RGB要求三个独立的视频信号同时传输)。

其中“Y”表示明亮度(Luminance或Luma),也就是灰阶值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。“亮度”是透过RGB输入信号来建立的,方法是将RGB信号的特定部分叠加到一起。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和Cb来表示。其中,Cr反映了RGB输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。

帧率FPS

所谓的FPS,即每秒传输视频帧数(Frames Per Second),见下图,可直观反映帧随时间变化的关系。

码率

编码器每秒编出的数据大小,单位是kbps,比如800kbps代表编码器每秒产生800kb(或100KB)的数据,通俗一点的理解就是取样率(每秒钟采集多少样本),单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件。

分辨率、帧率和码率三者对应直播质量的影响因素

帧率:

影响画面流畅度,与画面流畅度成正比:帧率越大,画面越流畅;帧率越小,画面越有跳动感。如果码率为变量,则帧率也会影响体积,帧率越高,每秒钟经过的画面越多,需要的码率也越高,体积也越大。帧率就是在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。

分辨率:

影响图像大小,与图像大小成正比:分辨率越高,图像越大;分辨率越低,图像越小。

清晰度:

在码率一定的情况下,分辨率与清晰度成反比关系:分辨率越高,图像越不清晰,分辨率越低,图像越清晰。在分辨率一定的情况下,码率与清晰度成正比关系,码率越高,图像越清晰;码率越低,图像越不清晰。

软编/软解、硬编/硬解

软编码/软解码:使用CPU进行软编码/软解码,实现直接、简单,参数调整方便,升级易,但CPU负载重,性能较硬编码低,低码率下质量通常比硬编码要好一点。

硬编码/硬解码:使用非CPU进行硬解码/硬解码,如显卡GPU、专用的DSP、FPGA、ASIC芯片等,性能高,低码率下通常质量低于软编码器,但部分产品在GPU硬件平台移植了优秀的软编码算法(如X264)的,质量基本等同于软编码。

FFmpeg

FFmpeg的名称来自MPEG视频编码标准,前面的“FF”代表“Fast Forward”,FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。可以轻易地实现多种视频格式之间的相互转换。

FFmpeg的用户有Google,Facebook,Youtube,优酷,爱奇艺,土豆、腾讯等。FFMPEG的视音频编解码功能确实太强大了,几乎囊括了现存所有的视音频编码标准,因此只要做视音频开发,几乎离不开它。

使用FFMPEG作为内核视频播放器:Mplayer,ffplay,射手播放器,暴风影音,KMPlayer,QQ影音...

使用FFMPEG:设置帧率、码率、分辨率、视频格式转换、放大缩小、旋转翻转、添加logo、打马赛克、分帧等等。

如采用ffmpeg视频分帧:

ffmpeg -i videos/1/test.mp4 -r 1 -vf "crop=380:340:885:352,scale=224:224"images/1/test_M.jpg

转码

是指将已经压缩编码的视频码流转换成另一个视频码流,以适应不同的网络带宽、不同的终端处理能力和不同的用户需求。转码本质上是一个先解码,再编码的过程,因此转换前后的码流可能遵循相同的视频编码标准,也可能不遵循相同的视频编码标准,例如企鹅电竞的流,会经由腾讯云后台做转码处理,转码成H265类型流、蓝光、高清等不同码率流。

视频转码是一个高运算负荷的过程,需要对输入的视频流进行全解码、视频过滤/图像处理、并且对输出格式进行全编码。最简单的转码过程仅仅涉及到解码一个比特流和用不同的编解码器重新编码两个步骤。

编码原理

在H264协议里定义了三种帧,完整编码的帧叫I帧,参考之前的I帧生成的只包含差异部分编码的帧叫P帧,还有一种参考前后的帧编码的帧叫B帧。

GOP

意思是画面组,一个GOP就是一组连续的画面,MPEG编码将画面(即帧)分为I、P、B三种,I是内部编码帧,P是前向预测帧,B是双向内插帧。

基础知识:I帧、B帧、P帧I帧表示关键帧。你可以理解为这一帧画面的完整保留;解码时只需要本帧数据就可以完成。(因为包含完整画面)P帧表示这一帧跟之前的一个关键帧(或P帧)的差别。解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)B帧是双向差别帧。B帧记录的是本帧与前后帧的差别(具体比较复杂,有4种情况)。换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是编解码时会比较耗费CPU,而且在直播中可能会增加直播延时,因此在移动端上一般不使用B帧。

H264/H265编码协议

常采用视频编码标准为:H264和H265,相比H.264,H.265能在有限带宽下传输更高质量的网络视频,也就是说只需原先H.264编码的一半带宽即可传输相同质量的视频,目前企鹅电竞推流和播放端都有采用H264和H265编码技术。

H.265是ITU-T VCEG 继H.264之后所制定的新的视频编码标准。H.265标准围绕着现有的视频编码标准H.264,保留原来的某些技术,同时对一些相关的技术加以改进。新技术使用先进的技术用以改善码流、编码质量、延时和算法复杂度之间的关系,达到最优化设置。具体的研究内容包括:提高压缩效率、提高鲁棒性和错误恢复能力、减少实时的时延、减少信道获取时间和随机接入时延、降低复杂度等。H264由于算法优化,可以低于1Mbps的速度实现标清数字图像传送;H265则可以实现利用1~2Mbps的传输速度传送720P(分辨率1280*720)普通高清音视频传送。

常见直播协议

目前常见的直播协议有三种:RTMP、 FLV 和 HLS。

RTMP

Real Time MessagingProtocol(实时消息传输协议 TCP)---常见推流协议。

RTMP协议比较全能,既可以用来推送又可以用来直播,其核心理念是将大块的视频帧和音频帧“剁碎”,然后以小数据包的形式在互联网上进行传输,而且支持加密,因此隐私性相对比较理想,但拆包组包的过程比较复杂,所以在海量并发时也容易出现一些不可预期的稳定性问题。(Android直播助手目前就是使用RTMP推流方式)

FLV 

flash video (HTTP协议传输)---目前终端APP基本上使用该协议

FLV协议由Adobe公司主推,格式极其简单,只是在大块的视频帧和音视频头部加入一些标记头信息,由于这种极致的简洁,在延迟表现和大规模并发方面都很成熟。唯一的不足就是在手机浏览器上的支持非常有限,但是用作手机端APP直播协议却异常合适。(企鹅电竞Android终端目前就是采用FLV)

HLS

HTTP LiveStreaming (HTTP协议传输)---常见H5页面播放视频都采用HLS协议;

HLS是苹果推出的解决方案,将视频分成5-10秒的视频小分片,然后用m3u8索引表进行管理,由于客户端下载到的视频都是5-10秒的完整数据,故视频的流畅性很好,但也同样引入了很大的延迟(HLS的一般延迟在10-30s左右)。相比于FLV, HLS在iPhone和大部分android手机浏览器上的支持非常给力,所以常用于QQ和微信朋友圈的URL分享。(企鹅电竞H5页面播放端采用的是HLS协议)

RTP

Real-time Transport Protocol  (UDP协议传输)较少使用

---------------------------------华丽的分割线---------------------------------

企鹅电竞直播架构和关键技术

一、直播整体架

  • 画面采集:可通过手机录屏、PC录屏、视频录制等方式获取,目前企鹅电竞主打游戏录屏(备注:除IOS端采用系统的录屏方案外,android和PC端均采用腾讯云SDK的屏幕录制方案)。
  • 推流:主播将本地采集的视频源和音频源通过编码器编码后,推送到后台推流服务器(腾讯云),目前企鹅电竞推流端,Android和IOS端使用腾讯云RTMP推流,PC端使用OBS推流,所以经常也称为“RTMP发布”。
  • 腾讯云后台:腾讯云后台收到上传的流(upload流)后,后台会对该流进行转码操作,比如转码为H265/h264的流,转码后的流也被称为转码流,转码流再经过DC源的分发,分发扩散到CDN中,最终提供用户播放拉流使用。(这部分内容在推流出流类型章节详细描述)
  • 播放端:用户在Android、IOS、PC、H5、游戏内置页面等渠道拉流后,进行硬解/软解码,目前企鹅电竞主流播放协议移动终端使用FLV、H5页面使用HLS两种播放协议,最后通过播放器把画面帧和音频输出。

1、直播流程

从业务角度描述直播各流程细节:

  • 第一步:开播鉴权:前提得有主播权限才能开播;
  • 第二步:申请流地址:有权限的主播触发开播操作后,申请推流地址,只有申请成功才能推流;
  • 第三步:音视频数据采集:除IOS端采用系统的录屏方案外,android和PC端均采用腾讯云sdk的屏幕录制方案;
  • 第四步:音视频编码:对采集的音频进行硬编或软编编码,目前支持H265和h264的编码标准;
  • 第五步:推流:通过腾讯云RTMP混合推流(音频、视频);
  • 第六步:创建直播间:推流开始前,先要给主播创建一个直播间,否则创建直播间失败,推流也会终止;
  • 第七步:开始推流:以上步骤完成,及进入推流状态,完成主播的一次直播请求;以上任何一个步骤失败,开播则不能成功。

2、企鹅电竞播放端总体架构

从业务角度描述企鹅电竞播放端整体模块架构:

3、推流出流类型

推流整个过程到底做了什么,理解了推流出流类型后,应该比较清晰,如下图示:

企鹅电竞使用腾讯云推流,整个推流地址转换分四个环节,每个地址的流都含RTMP和FLV两个流地址:

①upload地址:采集后推流,这是推流后台收到的第一个编码后的源流地址,如果是赛事,upload流地址可以从第三方赛事方(KPL、QGC主办方)拿到;

②转码地址:对源流进行转码,比如把H264流转码为H265流,把H254流转码为H264流,也可以对源流的码率降码率,降分辨率处理,相当于是对源流的二次转码处理;

③DC源地址:DC源相当于是转码流进行分发CDN节点前的总接口;

④CDN地址:用户播放器播放时,需要从最近的CDN节点拉流,DC流最终分发到CDN扩散。

二、播放器

播放器播放技术细节

我们播放一个媒体文件一般需要5个基本模块,按层级顺序:文件读取模块(Source)、解复用模块(Demuxer)、视频频解码模块(Decoder)、色彩空间转换模块(Color Space Converter)、音视频渲染模块(Render)在播放器的5个模块中文件读取模块(Source)、解复用模块(Demuxer)和色彩空间转换模块(Color Space Converter)这三个模块都可以用ffmpeg的框架进行实现:

S1.根据协议类型(如RTMP、RTP、RTSP、HTTP等),与服务器建立连接并接收数据;

S2. 解析二进制数据,从中找到相关流信息;

S3. 根据不同的封装格式(如FLV、TS)解复用(demux);

S4. 分别得到已编码的H.264视频数据和AAC音频数据;

S5. 使用硬解码(对应系统的API)或软解码(FFMpeg)来解压音视频数据;S6. 经过解码后得到原始的视频数据(YUV)和音频数据(AAC);

因为音频和视频解码是分开的,所以我们得把它们同步起来,否则会出现音视频不同步的现象,比如别人说话会跟口型对不上;S7. 最后把同步的音频数据送到耳机或外放,视频数据送到屏幕上显示。

三、推流端动态码率自适应

推流端核心推流能力,主播端推流能力变化时,自适应动态调整码率和分辨率,减少下行全员播放端卡顿,达到推流质量的最佳平衡。

自适应调节分辨率和码率对应区间参考表:

推流码率阈值分类(游戏画质高、中、低):

四、播放器动态缓冲区自适应策略

直观印象,先看下方动态缓冲区调整过程趋势图:

1、动态缓冲区策略逻辑

目前动态缓冲区策略android和IOS共用基层一套代码。

现网的播放器缓冲逻辑为固定每次出现缓冲时,缓冲够4s的数据才开始播放,显然,针对不同的用户采用不同的缓冲大小,可以为网速波动较小的用户减少缓冲时长而降低客户端缓冲带来的延时,网速波动较大的用户增加缓冲时长以保证流畅的播放。

具体调整策略:

①首次缓冲是拉到第一个I帧就开始播放,所以从第二次缓冲结束时开始计时m_u64BeginAdjustTime;

②若下次出现缓冲时,和上次开始计时的时间间隔,即流畅播放的时长低于m_u64AdjustInterval,则上调缓冲区大小cacheTime,幅度为m_fUpAdjustUnit;

③持续播放时长计算,每一帧播放时和上次开始计时的时间间隔,即流畅播放的时长高于m_u64AdjustInterval,则下调缓冲区大小cacheTime,幅度为m_fDownAdjustUnit;

④缓冲区大小的上限为m_fMaxCacheSize,下限为m_fMinCacheSize;

⑤本地没有写cacheTime值时,使用云控的起始缓冲大小initCacheSize;

⑥业务侧在每次调整cacheTime时,会将当前的值写本地,下次启动app的时候直接用这个值作为起始值;

⑦以上m_打头的变量皆为云控,在全局配置里面下发控制。

2、动态缓冲区策略配置

配置在管理端全局配置中,配置项分别为android_player_cache_strategy 和ios_player_cache_strategy

大致的配置内容如下及个参数细节如下详述:

 "adjustInterval": "2400",  #流畅播放时长:如果流畅播放>=该值,则下调缓冲区;如果流畅播放事件<该值,则上调缓冲区(单位是S) 

 "downAdjustUnit": "0.5", #每次下调缓冲区时下调的幅度,单位是秒  

 "initCacheSize": "4", #默认初始的缓冲区大小,单位是秒  

 "maxCacheSize": "8", #缓冲区的最大上限,单位是秒  

 "minCacheSize": "1", #缓冲区的最小下限,单位是秒  

 "testMode": "2", #缓冲区模式:2表示所有用户都采用动态缓冲区策略,1表示只有uid模3等于2的用户使用动态缓冲区(其余用户使用固定缓冲区大小),其他值表示全部用户采用固定缓冲区大小  

 "upAdjustUnit": "1"  #每次上调缓冲区时上调的幅度,单位是秒;

  流畅播放:没有出现缓冲即视为流畅播放,简单示意如下图红线——

五、清晰度切换逻辑

目前企鹅电竞涉及的清晰度有蓝光(8M/6M)、蓝光、超清、高清、流畅,具体企鹅电竞推流转码各清晰度档位分辨率及码率对应分类如下:

六、P2P播放技术

企鹅电竞从3.0版本开始接入腾讯云P2P播放,整体服务架构如下图:

1、P2P整体架构:

切片服务

直播流切片是P2P服务的关键,目的:如果不做切片流传输,peer之间没办法同步数据,因为每个peer节点从开始播放的位置都是不尽相同的,切片之后,每个peer都是相同的分片,也知道其他peer也肯定会需要这些分片,就能精准地给其他peer提供分片数据。

1、推流切片一个集群支持1000M的带宽,使用4层负载均衡将频道均匀地不记名地交给后端机器切片;

2、拉流切片使用一致性hash管理控制切片,使用ffmpeg方式组织拉流,并将流媒体数据切片;

3、切片服务最终都会立即上传到集中式存储服务,阿里云OSS(基本上已经替换成腾讯云OSS);

4、如果一个集群支撑不了那么多频道,可以在DNS添加多条A记录,增加集群应对。

Conf服务

conf服务是客户端开始播放的起点,在这里起着控制客户端程序行为,以及调度tracker的功能,conf服务主要用于客户端每次启动P2P时,給客户端可配的一些参数,比如P2P开关配置、保护窗口大小、P2P窗口大小、分到多少流、缓冲区大小设置等。

主要作用:

1、调度服务资源,以防单台stun承受不住的情况发生,也有可能因P2P流量太大导致运营商封锁P2P的端口,此时也可以通过conf修改stun服务的ip和端口来解决;

2、线上平滑地,不影响播放地更换CDN,实现与CDN的解耦合;

3、一些控制P2P参数的因子,可通过conf灵活地更改,便于调优。

穿透与tracker服务

核心点就是对NAT/NAPT进行UDP穿透,也称之为打洞(Hole Punching)技术,目的是打通同一个直播客户端的多个用户实现P2P连接,实现订阅和分享。

1、穿透使用的自己定制的stun服务器,单台能支撑40w并发在线。但是与不同穿透机器连接的peer不能相互p2p,同时同一个局域网内的用户不能互相P,但可以跟其他节点P成功

2、tracker服务的义务在于P节点收集和分发,目前来看是一个压力较大的服务,这也是一个独立的服务,单独部署并配以传统的负载均衡技术并无太大压力

(具体的P2P穿透技术细节可参照:http://blog.csdn.net/overmaker/article/details/3201799)

2、企鹅电竞P2P播放业务流程

企鹅电竞接入P2P播放模式后,同时兼容非P2P播放模式,整体的业务流程有比较大的变化,用户打开直播间整体流程如下:

1、首先通过conf服务判断该直播间是否开启P2P,如果非P2P直播间,走原有CDN拉源流的逻辑;

2、打开的直播间开启P2P模式,则触发P2PLiveplayerURL事件,此时,客户端本地的P2P  sdk作为中转服务,会把origin源url 换为代理proxy url,若换URL成功,会通过穿透服务获取P2P节点(若穿透的P节点不够形成P2P拓扑,则走P2P切片服务器的CDN下载数据),有足够的P节点情况下,每个P节点都会通过订阅,分享直播流切片数据;

3、P2P模式换URL失败,则回退到原有CDN拉源流的逻辑;

4、P2P切片服务器会主动从CDN源中拉流,通过切片处理到P2P自有的CDN服务存储中,故:第一个P节点用户必须走切片服务器CDN下载切片数据,然后再分享给其他节点。

七、常见直播问题排查指引

观看直播或者测试过程,经常都会遇到卡顿、音画不同步、花屏、黑屏、画面模糊问题,但在跟开发沟通反馈问题时往往描述过于简单,不方便开发定位问题,除了摇一摇日志上报之外,按照如下的步骤,可以直播从各环境逐步自己去定位问题的根本原因,我们测试在测试和反馈问题时可以更专业。

第一步:排除推流端问题

首先可以从直播间获取到主播ID,通过测试自建直播LPT平台(http://LPT.oa.com/)可以查看主播推流的各项数据:码率、帧率、当前码率(应发速率)、发送速率,根据经验,卡顿的问题,基本上都是主播上行带宽不足造成,表现出来就是当前码率>发送速率

其次是推流工具问题,比如手机CPU占比过高等问题,通过该平台第一时间可以排除是否主播推流端问题。

第二步:排除播放端问题

首先,我们要了解推流的整个过程,推流过程环节较多,因主播推流出来后,会经过upload流地址、转码地址、DC源日志、CDN地址四个环节,可以通过从最末端到CDN播放流的地址开始,通过第三方或者原生播放器逐步对比,比如排除音画同步、花屏、黑屏、绿屏等问题基本上可以通过如下流程步骤定位最终问题原因。

例如之前排查音画不同步现象步骤:如果cdn地址的流在第三方播放器没问题,企鹅电竞播放器有问题,那就逐步上升冒泡到DC源地址对比验证,如此类推,冒泡到upload地址,如果企鹅电竞播放有问题,第三方播放没问题,那么就是企鹅电竞播放端问题推出来的流有问题;反之,那就是推流端upload流的问题,可以找对应推流端的开发反馈问题。

播放流地址第三方播放方法:

第三步: 其他原因

如果以上各方法都查询不到原因,那可以尝试查看当前使用的手机网络是否有问题(下行带宽不足也会必现卡顿及模糊现象),或者对比当前手机和其他机型,排除机型硬件兼容原因。

后期我们会根据每个维度陆续写相关的测试文章,如果你有兴趣,请关注我们哦。


长按指纹识别图中的二维码,获取更多测试干货分享!

 将我们公众号置顶 

 不会漏掉我们的原创干货哦!

0 人点赞