某椒直播APP客户端技术演进之路

LiveVideoStack 2017年5月25日

本文主要分为以下部分:

 
  • 直播兴起的历史

  • 摸索学习阶段

  1. 基本情况

  2. 技术问题

  • 秀场直播阶段

  1. 趟过的坑和解决过的问题

  2. 直播的底层技术

  • 互动秀场阶段

 

在经历了野蛮发展的2016直播大战后,App端的技术扮演越来越重要的角色,好的技术可以让App在大量同质化的直播App中脱颖而出,让用户体验和用户留存率显著提升。

 

互联网老码农、朝阳区老群众唐赓将在本次分享上介绍花椒直播App在手机端技术的探索和实践、以及对未来的展望和思考。本文将涉及265、GPU技术、游戏级交互引擎、人工智能、深度学习等技术在直播中的应用和展望。

 

一、直播兴起的历史

 

如今,随着直播平台如雨后春笋般的兴起,一旦有大事件发生,新闻采访时都是下面这样的:

 

上面这张图摄于2015年,我们也是其中之一。随着国外直播平台PeriScope和Meercat的成功,国人也发现了其中的机遇,于是纷纷效仿。

 

 

映客和花椒是国内起步较早的直播平台,后面又有各种各样的其它平台出现。

 

二、摸索学习阶段

 

基本情况

 

初期,我们的很多基本体验都是基于模仿的,甚至初期我们是完全照搬了MeerCat的模式。

 

最初的内容比较繁杂,囊括了各种信息,包括达人才艺展示、授课、烹饪、杂耍等。基本的交互方式就是点赞、分享、文字交流以及视频,我们对自己的定位就是“视频版微博”,包括界面的整体布局全都是效仿微博的,连按钮位置和页面布局都几乎一模一样。整个页面的主要关注点在Feed流上面。

 

后在滤镜比较火爆的时候,我们又加入了图片滤镜功能,然后又加入了自拍短视频的功能。出于对社交的重视,我们又加入了私信功能。

 

 

在初期摸索阶段,由于产品经理以及开发人员对整个App的定位缺乏明确的认识,我们只能采取跟风做法,将市场上比较潮流的内容一网打尽,全部加上去。

 

技术问题

 

在这个阶段,大家所解决的都是类似的问题:

 

1、硬编硬解

 

我们分析过映客,结果发现映客所用的硬编硬解代码与我们所使用的一模一样,连临时文件的文件名都一模一样。原因在于:我们所使用的都是同一套开源代码。

 

最初iOS8还不普及,大多设备都是iOS7系统,想要做硬编硬解只能依赖系统的MovieWriter那套API(从磁盘的MP4临时文件中读取编码结果)。为了解决问题,当时有一个外国人分享了一套开源编码,解决了硬编硬解实现的问题,因此大家全都去用这套开源代码。后来到了iOS8,由于原生支持硬编硬解,这个问题才不复存在。

 

2、看播花屏

 

类似的问题还有很多,现在看起来觉得很基础的问题,当时却是很大的问题,比如看播花屏。丢了一帧再强行解码,就会出现花屏的问题。解决方法很简单,完全丢弃GoP里后续的内容。

 

3、音视频同步

 

根据我们对各家平台的分析,所有直播平台基本都不同步,只不过大家采用的方式各不相同。例如:将音频视频分开采集,并分别通过不同的通道进行传播。在此过程中,我们需要尽量保证音频是连续的,视频相对就没那么重要,这样就会导致音频和视频总有些不同步。解决办法就是保证时间戳准确。

 

我们让QA测试是否同步的简易办法是,利用一支笔敲击桌面,同时在视频的那个瞬间,也必须要有声音发出。相对于对口型等方式,这样的方式更简单也更直接。

 

当然,我们也尝试了很多其它方案,不过利用不同的方案去采集声音,时间戳总会有些问题存在。在这个阶段,我们做了很多尝试,一个个解决掉了这些问题。

 

4、降低看播录播CPU消耗、直播间CPU总消耗

 

起初我们并没有意识到这个问题,结果上线后突然出现了卡顿等意外。经过深入分析,我们发现这是由于CPU的消耗非常严重引起的。实际应用与测试环境不同,由于实际环境下使用人数众多,点赞、发言、送礼等操作都会对CPU造成巨大的消耗。

 

通过模拟,我们找到了各种各样的性能瓶颈,并一点点地改进。彼时大约有50%的因素是因为客户端CPU消耗太高,导致推流时会出现卡顿。

 

5、回放/回放弹幕优化

 

剩下的问题在于服务端,类似回放、回放的弹幕优化等问题都有可能造成卡顿。

 

有一次我们请了范冰冰来做直播,平时的弹幕文件也就是几兆而已,结果那次弹幕文件的大小达到了200多兆。读取要花费很久,即便读取成功,下载的弹幕文件在载入时也会出现内存超过限制,随后闪退的情况。类似这样的问题层出不穷,我们也只能一个个解决。

 

6、私有协议与公有协议、TCP与UDP

 

在这个阶段,我们摸索了很长一段时间,包括究竟用私有协议还是公有协议,究竟用TCP还是UDP等等。不过事实上到现在,这些问题仍旧存在。我们的线上还是既有私有协议又有公有协议,既有TCP又有UDP。

 

私有协议的好处在于,我们可以肆无忌惮地加入各种各样的功能,包括对其进行优化,性能调试等,但公有协议的好处在于它支持CDN,各家CDN都可以拿过来直接使用。我们自己的CDN只在国内一些大城市有,像奥运会这样的活动,如果要去巴西,或者要去直播欧洲杯,都要借助其它的CDN。

 

TCP和UDP的问题在于:UDP的性能比TCP好得多,没有超时重传这些消耗。而且TCP还有一个问题,就是可靠连接的问题。它必须要确保数据到达,一旦出现阻塞,要想放弃的话就只能把链接断掉。

 

7、回放录制,HLS生成

 

一般来说,如果网络不好的话,信息流经常会出现断裂以及缺失。如果录制的回放中有缺失,生成HLS之后,通过一些私有播放器是可以正常播放的,但之前系统的播放器是无法播放这类视频的。

 

当时我们想了很多办法,包括重整时间戳,进行其它的处理,都是为了解决播放的问题。不过现在就没关系了,用我们自己编写的播放器来播放,是始终可以正常播放的。

 

8、秒开

 

放在以前,大家点进去以后等一两秒再打开,都觉得挺快了。但现在来讲,超过三百毫秒都不合格。秒开应当是所有直播软件必备的功能了。

 

在改进时,我们通过抓包分析,了解从点击到视频的第一帧展现之间,都发生了哪些事情,再把所有不必要的东西全部拿掉。例如之前先点进去的话,可能要去找对应的流服务器,需要通过302跳转。而现在在广场上就把类似这些所有的必要信息全都拿到。点击后,原本打开直播间时要加载头像、豆币等内容,但为了实现秒开,这些全部要让道,所有东西必须等到第一帧展现出来以后才开始进行。

 

根据我们的分析,映客App做得更多一些。从手指向上滑的时候就开始切换,当手指落点超过屏幕的1/3后,就会开始加载下一个直播。这样一来,借助偷跑的零点几秒,它的秒开性能更加优越。

 

其它优化问题还包括CDN优化,使用成熟的CDN厂商会带来更好的效果。比如映客的GoP就是一秒,我们的GoP是两秒,都可能是因为相关的优化问题。

 

9、用户定位、调度

 

至于用户定位和调度的优化问题,有这样的案例:某个人明明在美国,但我们采集到的IP定位显示他在广州,根据分析他实际是使用了广州移动的sim卡漫游到美国。由于移动的原因,我们会显示他的IP在广州。

 

这种情况下,再去对他进行调度,一定会出错。我们经常发生这种事情,比如有人特别卡,我们就会去看他实际所在的位置,是否跟我们将他调度所分配到的服务器不在同一个地方。

 

由于经常发生类似问题,我们也形成了一套比较自动的补救机制。以前都是固定调度,调度以后在直播过程中就不能再更改了。但由于类似错误太多,我们修改了相应机制,使其能够在当直播中重新调度,强制执行一个离用户最近的流服务器。

 

10、VR直播?

 

这个时间段,我们还尝试了VR直播,那段时间VR特别火。为了增加这个功能,我们在客户端增加了VR播放器,结果让安装包又扩大了好几兆,结果并不成功,这个属于我们趟过的坑。

 

三、秀场直播阶段

 

趟过的坑和解决过的问题

 

1、礼物系统

 

做了大半年之后,我们才找到一个比较好的定位,就是做秀场直播。既然是秀场直播,就得有秀场必须要有的东西,包括各种各样的礼物,连发礼物、全屏礼物、私信礼物,实际上一加上这些东西,就又会遇到各种各样的CPU问题。

 

怎么优化这些CPU的占用?比如说,像用PNG序列(实现的礼物)----我们一个最大的PNG序列可能会有80帧甚至180帧,全部一起加载的话,一瞬间的CPU占用会非常高。一两秒之内,推流都会停止。类似这种情况,我们都是在性能分析阶段才发现的。采用的解决方案是:让图片加载得慢一点,加几帧之后就停一下。

 

2、金币系统

 

金币系统,我们也走了一些弯路。最早我们用的是单币体系,就是整个世界里交易的只有一种东西,就是花椒豆。我送给你一百豆,你就拿到一百豆,当然最终提现的时候会有一些手续费。

 

但单币体系有一个问题,就是你拿一百豆又可以送给我,我又可以再送给你,我们之间就可以无限刷下去。这样会导致一个结果:在我们的整个体系里,无论经验值还是其它的,只要跟消费量有关的东西,就可以随便刷了。

 

其实大家在上线这个东西的时候,就已经意识到可能会有这样的问题,但由于缺乏经验,最终还是决定上了。之后就发现有人通过各种各样的方式利用这个规则,因此我们赶紧改掉,用双币种的模式,送花椒豆给对方得用币,再用币来买豆或者提现的话,就得有一定的折损。

 

有了这样的游戏规则以后,整个生态环境就变得健康多了。实际上这个弯路走得挺不值的,因为包括YY、映客等App,都早就采用了双币系统。

 

3、附近的人

 

这个也算一个坑。当时这个功能我们都做了,后来又拿下了。原因在于:假设用户位置定得过于精确,会让主播产生顾虑——如果可以定位到哪个小区,别人在小区门口守着怎么办?以前我们还有一个地图视图,可以在地图上将用户标记出来。虽然有一定的误差,但通过多收集几个手机的数据,就有可能定位到具体的位置。

 

最后,我们还是采用了映客的方式,也就是九宫格头像。在下面稍微标注一下这个人距离你有多远,而且那个数字也是调整过的。地图视图对主播伤害很大,一般有这个功能,他们就不愿意用了。

 

4、美颜功能

 

美颜算是我们做得比较好的一个功能。这个功能并不是我们第一个上的,就手机APP来讲,映客就比我们上得早。之后我们了解了一下,映客用的是虹软的方案,就去找虹软谈。但虹软用的是CPU方案,所有数据的读取和处理都要凭借CPU,之后再返回。对于本来就很紧张的CPU而言,这个方案会有很大问题。最后,我们用了GPU的方案,直接在GPU内部进行美颜的处理。

 

 

最早我们尝试了多家不同的方案,上线后让很多主播一个个尝试,看哪个滤镜的美颜效果最好。最后通过实验,换了好几家的方案之后,我们终于找了一家比较好的。以前我们调到最好的状态,就觉得跟映客差不多了,但后来我们找了一个新的解决方案以后,明显感觉比虹软的效果要高一个档次。

 

不过,现在我们所用的美颜方案已经完全是我们自己开发的方案了,这个后面也会提到。这个新方案与之前我们所用的那个效果最好的技术提供商方案,从肉眼上已经看不出区别。

 

这里还有一个很有意思的事情,我们是做技术的,自己觉得肉眼没有区别。我们换了一款滤镜之后,一丢出去结果就立刻真有主播找过来,问我们是不是换滤镜了,是不是改什么东西了,我要的那个效果没了,也不知道他们是不是有特异功能。我们是完全看不出来什么区别的,最后就只能用算法来做对比,将两个算法摆在一起,用程序去分析红分量、绿分量等各种分量,以及界面上有肤色的地方究竟有什么区别。因为我们所有的工程师用肉眼看完,都觉得没有问题了,只要一丢出去,就立刻有主播找过来,问我们是不是改东西了。

 

目前来讲,我们还是有这个信心的,在美颜这块我们算有比较明显的优势。

 

5、萌颜功能

 

2016年初FaceU大火的时候,我们就想到了将这个想法插入直播App中。最初的第一个版本仅花费了两天时间就出炉了,用的是苹果自带的人脸识别方案,但做出来的效果与FaceU差距很大,原因在于苹果自带的人脸识别,抖动非常厉害。即使用户和手机都保持静止,系统每一帧所识别出来的图像也会不停抖动,导致人头大小一直变化。

 

经过了解,我们发现FaceU未采用系统自带的方案,而是用了SenseTime的方案。于是我们迅速搜寻相关信息,并积极沟通,购买相关引擎。

 

同时我们也在开发人工智能的相关功能,例如下面写着360人工智能研究院,识别的图片。我们也有针对相关问题,积极组织工程师团队进行攻关。

 

 

不过短期内我们不可能立刻做出一套能把SenseTime比下去的方案,因此前期我们用的都是SenseTime的方案。借此解决了几个问题,一个是人脸识别的问题,识别之后在GPU内部进行处理,播放的视频效果就是视频1这样的。最终形成的结果,就是将需要的效果与真实图像叠加在一起。这个问题我们解决得很快,应该是第一个上线这个功能的APP了。

 

 

具体细节我印象还很深刻,大约2016年初即将过春节的时候,之前的周末我刚把代码写完,第二天立刻找SenseTime去签合同购买引擎。对方的工程师刚上火车,经过协商,对方在火车上给我们Build版本。由于我们自己春节也要赶火车,时间非常紧张。到最后,我还是在火车上继续把代码写完的,然后打包上线这个功能了。当时这也确实是抢了一个先机,算是直播app里第一个上线该功能的,就算到现在来讲,有这个功能的App也不是很多。

 

6、换脸、瘦脸、大眼功能

 

当时我们还做了换脸、瘦脸、大眼这些功能。换脸就是类似下图这样的效果,这个功能我们已经下线了。原因是用了一段时间之后,我们发现整个花椒的直播间在晚上的时候,效果会非常惊悚,整个气氛都不对了。后来这个功能就被下线了。

 

 

但是瘦脸和大眼的功能现在还是有的,主播现在用的这个版本就可以选择瘦脸和大眼,以及美颜、美白、磨皮程度的。

 

7、K歌/曲库,音效

 

当时在做K歌功能的时候,我们也遇到了很多问题。比如音效功能。话筒讲话会带有一定的混响或音效,比如大礼堂、大房间、小房间这样的。当时我们找了一些解决方案后就匆匆上线了,实际上有一个问题并未解决,就是实时返听的功能。上线之后,我们就在攻关实时返听的功能,现在看来很简单,在iOS下面根本就不是问题,只要用AudioUnit就可以达到三毫秒以下返听的效果。

 

但当时来说,不拿着K歌软件尝试一下,我们完全体会不出返听效果5毫秒和10毫秒之间差别有多大。根据我们通常的认识,比如打电话,只要差别在一百毫秒之内,我们会认为它是实时的,基本没有问题。但在唱歌的时候,连10毫秒的时差都是难以忍受的。唱歌时耳朵所听到的声音,和自己发出的声音之间相差超过10毫秒,歌手就没法唱下去了。实际上,iOS系统对这个问题解决得比较好,安卓系统并不是所有的手机都会支持,而iOS就可以把这个时差控制在5毫秒之内,用户耳朵里听到的声音跟自己唱得声音几乎是同步的。

 

后来我们还做了变声、变调效果,以及气氛、音效等,基本都是对照着像全民K歌之类的软件,把能做的功能全都做上了。

 

直播底层技术

 

关于直播的底层技术,我们也做了很多尝试。

 

1、降低CPU的消耗

 

我们做了很多降低CPU消耗的尝试,包括调整在GPU里处理的画面的大小,让处理的像素少一些。效果非常明显,最下面那根线就是我们改进之后的效果。

 

 

之前我们的CPU消耗还是很高的,经过处理后一下子就降了下来。这个问题的解决办法,就是要保证在GPU里,所处理的像素是最少的。因为最终我们要把画面从GPU里拿出来,放到CPU中进行传输,只要把这个像素压缩小了,读取所消耗的时间也会相应减少许多。

 

2、码率、帧率、分辨率自适应,带宽自适应、崩溃续推

 

当时我们还做了码率、帧率、分辨率的自适应功能,以及带宽自适应、崩溃续推等功能。

 

之前我们遇到画面崩溃的问题,就在考虑续推的解决方案。后来发现,这个问题非常简单,整套直播体系本来就支持这个功能。原因在于:用户的网络本身就会断掉,闪断然后再连上,本身就说明它已经具有这个续推的功能了。网络都断了,又继续新建连接。于是我们就做了一个简单的提示,如果需要续推,我们会提示用户刚刚发生闪退,是否要回到直播间,这就OK了。

 

3、画质改善/清晰度测试(PSNR/静态画质清晰度/动态清晰度)

 

我们还做了许多改善画质的工作。一种是用PSNR这个业内比较直截了当的方式,但我们同时借鉴了单反相机评测的方法,用了一些比较标准化的测试。原本是用来评测单反相机的解析度,后来我们用那个标准,对我们各种各样的算法和处理进行打分。这个功能其实也做了蛮长时间的,应该来讲效果还是比较明显的。

 

四、互动秀场阶段

 

新的尝试

 

1、双人连麦和多人连麦

 

现在我们新加入了双人连麦的功能,实际上最近我们还在做多人连麦的功能,昨天才发了新版。之前我们一直熬夜加班在加这个功能,不过我也不敢保证上线后一定会很好。目前我们做了一些比较激进的策略,比如不连麦的时候,我们会切换到成本比较低的线路上。一旦真正开始连麦了,再切换回成本比较高的BPG线路上去,当中会发生各种各样的切换,主播要切换、嘉宾要切换、观众那边也得切换,只能等上线后再看效果,再看会有什么问题。

 

 

这个功能中间还是有很多坑的,因为切换需要CDN厂商的支持,当时我们也是找了CDN与我们一同进行修改。至于后效如何,也只能等着看了。(LiveVideoStack注——唐赓反馈了低成本连麦策略的运行情况:经过一个多月上线运行,稳定性超预期,没有发生需要救火的情况,我们设计的连麦异常自动补救机制有效运行。同时,明显降低了成本,用户连麦活跃度明显增加,连麦推流流量(BGP流量)却降低了,直接减少了5成以上费用,同时对用户体验基本没有影响,没有用户抱怨我们在后台切换线路导致的短时卡顿,完全达到了我们的设计初衷。

 

2、2D和3D互动礼物

 

如今已经是后秀场时代,我们必须更多地跟主播进行互动,因此我们加了很多东西,包括2D和3D的礼物。然后也尝试了很多游戏引擎之类的内容,实际上熊猫直播也尝试过,他们加了Unity引擎,不过后来失败了。我们需要的引擎,其生命周期应当是与直播间的生命周期接近的,甚至是跟礼物的生命周期接近的,出现礼物包的时候才用,不用的时候就释放掉。但这与游戏引擎的设计理念不符,对Unity这样的3D游戏引擎来讲,中途释放是释放不干净的。后来我们对Cocos2D-X也是做了非常多的改造,才比较完美地解决了这个问题,包括各种内存泄露、状态清理不干净的问题,当然最终效果还需要大家等待一下,我们很快就会上线。

 

3、多人游戏/PK,语音场控/DJ/主持

 

比较有意思的功能还有一个,就是主播跟观众之间的互动游戏功能。

 

 

上面的图片实际上是截自YY,他们加了语音场控、DJ、主持人的功能,以及多人游戏、PK这些功能,我们也在努力,尽快上线这些功能。

 

4、多人连麦游戏

 

 

最近狼人杀等App就用到了12路甚至15路连麦的技术,上图来自于美播,其中的一些思路我们也是可以借鉴的。这些都能让直播间的玩儿法更丰富起来。

 

互动秀场的AI应用

 

1、绿幕和FABBY抠像

 

我们做的绿幕抠像技术,实际上主播一开始是下面第一张图的情况,背后是绿色的。当他选好背后的背景视频之后,绿幕就会被替换掉,换成第二张那样视频。不过这里有个要求:主播背后必须是一块绿色的背景。

 

 

我们对这个功能并不是很满意,做完这个功能之后,有一款新的APP出来了,叫做FABBY。它可以在没有绿幕的情况下,就把人像给抠出来。它们所使用的方案是深度学习方案,360研究院也立刻就跟进了,上图是我们做出来一些效果。

 

2、其他

 

我们还有很多其他研究,包括手势识别、场景识别、物体识别、主播自动分类(性感、清纯等)、画质监控、聊天机器人等。

 

 

手势识别:在很低的CPU消耗下,系统自动识别出主播的手势,比如比心。

 

引入265

 

简单说一下265,我们对市场上各种265的解决方案进行了测试,结果发现确实能带来非常明显的带宽节省效果。节省的带宽高达40%甚至54%,这个数字非常夸张了。具体数字如下:

 

  • 896*504,265 300k > 264 500k,带宽节省大于40%

  • 1280*720,265 500k=264 1100k ,带宽节省54%

但是,由于现在H5或者其他的一些分享渠道都必须用到264,我们必须在服务端进行转码。由于对转码集群的需求,会有一定的费用消耗。此外,金山的这个方案本身也非常贵,因此这个方案整体来说也是有一定成本的,并且还需要CDN厂商的支持,才能将265的内容传递出去。

 

因此,我们需要整体做一个权衡,去考虑损益。不过在目前来看,我们觉得这是未来的一个趋势,而我们也一定会紧跟这个趋势。

 

游戏录屏

 

现在我们还推出了游戏录屏功能,我们所使用的是AIRPLAY的录屏功能,实际上苹果建议使用REPLAYKIT,但由于REPLAYKIT会要求游戏厂商本身要提供支持,我们还是采用了AIRPLAY的方案。

 

 

这里有个问题:AIRPLAY的方案是苹果明令禁止的,我们在实现时使用了它的私有API,以企业发布的形式发布了采用AIRPLAY的这个版本。

 

人头拾音

 

这也算是个黑科技,如果观众戴上耳机去听的话,会觉得主播是真的在耳边说话。声音会跟随主播从左耳慢慢走到右耳,甚至连触摸耳朵的感觉都能感觉出来,闭上眼睛汗毛都要竖起来了。

 

 

更多UGC内容

 

我们认为,一个直播平台想要成功的话,必须要有更多的UGC内容。这点快手就做得非常漂亮,我们的app在内容的丰富度上跟快手相比差太远了,快手上什么都有,有人在展示如何修理iPhone手机,有人在玩儿飞机,有人玩儿多肉植物,有人玩儿玉器,各种各样的内容全都有。

 

 

 

而我们的多样性还相距甚远,主要都是妹子唱歌跳舞这些,需要后期等待运营人员的改进。

还可输入800
全部评论
作者介绍

唐赓

花椒直播

技术部总监

文章

粉丝

视频

阅读排行
  • 2周
  • 4周
  • 16周
热门视频

WebRTC视频数据流程分析

许建林/《WebRTC Native开发实战》书籍作者