教育场景下的实时音频解决方案

640?wx_fmt=jpeg


本文来自网易云信 资深音频算法工程师 李备在LiveVideoStackCon 2018讲师热身分享,并由LiveVideoStack整理而成。在分享中李备详细分析了在线教育的音频需求,以及一般软件音频框架,和行业的挑战。


文 / 李备

整理 / LiveVideoStack

直播回放:

https://www.baijiayun.com/web/playback/index?classid=18100937220683&session_id=201810110&token=qJU73GZ_Sypg5tXwrQlPW-dYf81fngNF6RfMSjQA80ffLA0n-BEkqaRIbUQmUGIKXn3EFapSbJeMCTpCPak4Cg


大家好,我是来自网易云信的李备,今天我将与大家一起探究教育场景下的实时音频解决方案。


本次分享将围绕以下几部分进行:


640?wx_fmt=png


1. 实时音视频的市场需求


1.1 市场观察


随着我国互联网行业的蓬勃发展与宽带水平的提升,消费者早已不满足于通过简单的文字图片浏览新闻,而是期待通过更佳生动精彩的音视频获取知识了解世界。根据网易云信平台观测的数据,音视频社交应用时长在近两年呈现飞速增长,随之增长的同样还有中国在线教育市场交易规模,从2010年至2017年增长近10倍,并预计在2018~2019年保持增长。可以说,实时音视频技术助力众多产业转型升级,并使得视频会议等经典应用场景重获新生。众多的新兴场景与行业借助实时音视频技术实现了更佳丰富炫目高效准确的场景表达与业务落地,同时也进一步促进了实时音视频的技术演进与行业探索。实时音视频正在各个千亿、百亿市场快速发展并逐渐成为基础设施型重要技术。


1.2 应用场景


640?wx_fmt=png


我们的音视频行业主要存在以下应用场景:以网易公开课为代表的点播,以Finger为代表的直播,以网易云课堂为代表的互动直播与以各种P2P、小班教学、大型培训为代表的实时音视频。


640?wx_fmt=png


1.3 直播/点播框架


下图展示的是直播与点播的技术框架。


640?wx_fmt=png


而与上述直播/点播框架不同的是,互动直播框架更加强调音视频的实时性与强互动性。来自Web 端连麦观众的音频数据会通过WebRTC网关传输至实时音视频中转服务器,并在此与来自手机连麦观众和PC端主播的音视频数据一起由实时音视频中转服务器转发至互动直播服务器。互动直播服务器会对这些数据做合成/推流处理,传输至融合CDN流媒体服务器,由流媒体服务器推送数据给观看互动直播的普通观众。与此同时,实时音视频中转服务器同样负责手机连麦观众与PC端主播的直播互动数据交换,从而实现互动直播的效果。


640?wx_fmt=png


2. 软件层实时音频解决方案


2.1 实时音框架的线程模型与数据驱动方式


640?wx_fmt=png


上图展示的是实时音频的简单框架线程模型,这里需要提醒的是,其中的解码主要由客户端完成,实时音的服务端不参加解码而是把来自各端的数据包筛选之后传递给其他端。我们以音乐教学场景为例,学生与老师正在上课,此时来自学生的音频信号被其移动终端采集模块采集,经过混音消除、降噪、自动增益控制等音频的前处理过程,由音频编码器进行编码。这里的编码器主要分为专属语音编码器与音乐编码器。音频数据经过编码器的编码处理后会被发送至网络,此时接收端会收到一个缓冲抵抗网络抖动的Jitter Buffer。解码后的音频数据经过快慢速调制与TSM后进行后处理,最后播放。播放时产生的回声会被捕捉并重复上述流程。


在硬件层面,终端制造商对音频处理流程中所需要的硬件都有一套同一切完善的参数调整经验,例如麦克风的采集帧率、拾音距离、回声延迟等都有统一规范;而考虑软件层面的实时音频则需面临设备数量庞大的难题,我们需要统一海量设备与不同平台的复杂数据输入并且考虑到软件层面的不可预知性,也就是我们需要一个完善的音频处理系统,优化各模块之间的协同工作并保证算法的稳定性。因此在这里我向大家展示一下WebRTC线程模型的设计和数据驱动方式:不同的颜色代表不同的线程。首先,音频数据被采集模块采集后进行音频前处理,之后经由交付Buffer被交至音频Codec进行编码。(这里强调的是,我们不把音频Buffer和Codec放在一个线程的原因是音频Codec的实时性计算量要求较高,需要单独的一个线程运行。而经过网络发送时一般网络线程是直接将数据传输至Audio Jitter Buff-er,Audio Jitter Buffer获取数据后会在网络线程上接收数据包,并更新网络统计和策略,而playback的callback请求往上回调至Audio Jitter Buffer请求数据过程是运行在Playback的Callback线程上。经过解码后音频数据会进行TSM、MIX等(如果是处理多路MIX,有些厂家可能会使音频解码单独在一个线程上运行,这一点视应用场景而定,如果是处理一路MIX则可以简单地运行在播放线程上。)关于其中的驱动方式,一些开发者喜欢使用Timer机制驱动数据,但这在实时音频框架中并不推荐。以Audio三维算法处理为例,音频每一帧处理需要大约10毫秒的时间,对时间的精度要求很高;而简单的Timer驱动无法满足这种高精度,尤其是在复杂的系统中很容易出现延迟,这为整个音频处理系统带来的影响无疑是毁灭性的。因此我们一般采取将驱动运行在系统(回调)中的解决方案,因为系统(回调)的高优先级可确保整个系统的稳定运行。Google就曾经在I/O大会上面推荐把audio process放到系统的采集播放线程里 ;右侧展示的主要有两个系统:收包网络系统与底层的用来驱动音频解码、后处理、MIX的Playback。一个音频引擎框架的稳定性直接决定了其输出声音的质量与实时性。


2.2 音频前处理框架


640?wx_fmt=png


捕捉到的音频数据会进入Audio 3A处理。其中Audio 3A由AEC、ANS、AGC组成。不同的应用场景三者的处理顺序也不同,如在WebRTC中音频数据回依次经过AEC和NS 或者 NS 与AECM(AECM 是WebRTC专门为移动端打造的算法,计算量低,而AEC 是为PC打造的)。而在AEC(回声消除算法),为什么需要这个算法呢?当一个设备在播放声音经过空间中的多次反射会被麦克风再次捕捉并采集到系统当中,这时音频的输入既有空间反射的回声也有本端说话声,如果缺少此模块就意味着通话中说话人一直可以听到自己的声音回来,这是非常差的一种体验,这当然是需要我们避免的。这里AEC的作用就是通过播放的参考信号跟踪出回声并从采集信号中把回声消除掉,随后再经过降噪处理去除噪声。而其中的AECM是在NS模块之后通过获取clean与noise数据进行分析,AEC则是NS模块之前直接获取noise数据进行分析。音频数据完成AEC与NS的处理后会进行AGC处理,其包括AAGC(模拟域的自动增益控制)与DAGC(数字域的自动增益控制)。其中AAGC的主要作用是通过系统的采集音量设置接口调整输入信号(大多用于PC端,移动端一般没有输入音量的系统接口),如借助Windows上的的API调整采集音量等参数。AAGC可为输入的音频数据带来明显的质量优化,如提高信噪比,避免输入信号溢出等。但由于我们服务的跨平台要求,我们需要构建一个面向多平台设备的框架,在不同的输入平台和设备都会有不同的输入音量,DAGC可以根据对输入信号的跟踪,尽量的调整信号到达期望大小(幅值或能量),从而避免不同设备采集带来的音量差异过大。完成AGC处理的音频数据,即可进入Audio Encode进行编码操作。


640?wx_fmt=png


这里我想特别介绍一下Audio Jitter Buffer,由于视频的发送码率较高容易对网络造成较大冲击比较大,而音频在窄带与中等码率的情景下的发送码率在50KBPS上下,不会为网络带来较大压力,很多厂家在做音频QOS的时候并不会控制发送带宽(因为宽带的音频带宽不高,对于网络拥塞贡献不大),而把重点工作都放在接收端的jitter buffer策略上。但我们的人耳对连续性非常敏感,一旦有包没能及时传递出现丢包,那么观众就可体验到瞬间的卡顿,这种频繁的卡顿会让用户体验大打折扣。因此我们需要一个抵抗抖动的Buffer来抵抗网络抖动的冲击,从对Delay要求高、平滑稳定过渡的角度考虑我们希望选择较长的Buffer,而从实时性出发我们又希望尽可能缩短buffer。为了平衡网络抖动与实时性,我们引入Audio Jitter Buffer进行处理。一般用来在接收端控制网络抖动,而在不同模式下采取的抗抖动方案也不尽相同。Jitter Buffer框架与其包含的模块展示在这张图中,其中黄色代表网络线程。Audio Play Callback的数据首先传输至Manager,同时上传一些必要信息,此时音频数据会经过Jitter Policy处理传输至Audio Decode并在播放端触发callback,再由Callback驱动整个抓包流程。JitterBuffer请求包时会根据Jitter Policy进行音频解码或PLC/CNG、Slience等。最后经过后处理与MIX的反复处理,数据被传输至Audio Play Callback。不同厂商的Jitter Policy处理方案也不一样,如较为出名的WebRTC NeTEQ算法,其中集成了自适应抖动控制算法以及语音包丢失隐藏算法。除此之外, JitterBuffer在跟踪预测准每一个包的jitter的时候,也需要考虑实际的缓存播放策略,比如三个包的jitter 分别是100ms,50ms和150ms,如果每次都紧跟预测的jitter,当第一个包来的时候需要缓存100ms,然后第二个包来的时候发现只需要缓存50ms,实际缓存多了需要TSM 调整,直到第三个包来,发现要缓存的又要变化了,又需要需要TSM 调整,那么这样最后的效果将是非常糟糕的。JitterBuffer的目标就是缓存适合的数据可以抵抗网络jitter的抖动,自适应既要兼顾考虑时延,又不能变化过于频繁破坏声音体验,也不能不跟不上网络变化造成缓存不足造成丢包。


2.3 Active Speaker List


640?wx_fmt=png


Active Speaker List(下文简称ASL)主要被用于解决大型会议的一些痛点。我们知道,实时音服务器一般不做服务器端解码,如果服务器解码会导致服务器计算量增加;随着Client的增多与业务的拓展,加之分发到Client的功能与操作越来越多,服务器的压力会越来越大直到威胁整个服务的正常运行;为了确保服务器有着更好的并发的能力与扩展性,可将此解码工作转移至Client端实现并且允许Jitter Buffer监控整条链路及时调整策略。如果在大型的会议里,如千人会议里面,每一路的音频下行都接近一千路,光是纯音频的带宽就非常高了。由于人的听觉最多可同时拾取三路声音并获取其中信息,而多人开会最多的情景是一个或几个人主讲剩下的人聆听,因此我们需要ASL在服务器上选择说话的线路并将线路上的音频数据传给其他所有参与者,如果面对几百上千人同时讲话,ASL则会选取音量最高或者讲话内容最清晰的进行推送,这可极大方便大型视频会议的顺利开展。


3. 行业痛点


640?wx_fmt=png


音频行业之痛主要是复杂的网络对音频的冲击与碎片化的终端设备背后差距悬殊的硬件。尤其是对Android平台而言,软件层面不同厂家定制系统的处理流程、硬件层面手机的工业设计、处理器、传感器等都不相同,难以用统一的平台解决方案处理这些设备的音视频问题,主要体现在算法的挑战难度上;与此同时,我们希望算法鲁棒性更强,这就意味着需要考虑更多的案例,而算法不可能考虑到所有的案例,我们必须根据实际情况进行相应取舍……这些都是在未来亟待解决的行业痛点。



精品文章推荐






线上分享:



技术干货:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值