直播与短视频相继爆发,也促使众多企业纷纷加入其中,对于许多传统企业和中小企业而言音视频开发成为了最大难点,而视频云客户端SDK也就无疑成为了不错的选择。本文是全民快乐研发高级总监展晓凯在LiveVideoStackCon 2017上分享的整理,主要从架构设计、模块的拆分实现、跨平台视频处理系统和推流系统的构建几部分着重介绍。

演讲 / 展晓凯

整理 / LiveVideoStack

我是来自全民快乐的展晓凯,曾就职于淘宝开发机票搜索,在唱吧上线之初加入,经历了唱吧从上线到拥有4亿用户的整个过程,在此期间负责唱吧音视频的开发,其中涉及多个产品线,包括唱吧、唱吧直播间、火星等产品。目前在全民快乐负责直播产品线业务,主要面向海外市场。

在唱吧和全民快乐多年的音视频技术积累,展晓凯也在近期发售了业内第一本音视频移动端开发书籍《音视频开发进阶指南——基于Android和iOS平台的实践》。(文末有彩蛋)

本次分享将从以下几部分来介绍视频云客户端SDK的设计与实现:音视频领域的发展,SDK的核心应用场景,视频录制器和视频播放器模块的拆分,跨平台视频处理系统和推流系统的构建,以及未来的机遇与挑战。

视频云客户端SDK发展和核心场景

音视频架构与开发的演进历经很长时间,大致可以分为以下几个过程:最开始是广电领域,也就是给电视台提供直播以及转码等服务;后来扩展到了PC端的音视频领域;而近几年则是在移动端音视频领域发展比较火热。

对每一个视频云厂商,除了提供持续、稳定、高可用的线上服务外,它其实也提供了客户端的SDK,以方便客户在不了解音视频细节的条件下,也可以快速构建自己的APP,这样也可以更加关注与自身所在垂直领域相关的业务。

那么SDK的核心场景有哪些?为了方便讲解,我们把SDK核心场景分为录播场景和直播场景:对于录播场景,主播端或者内容贡献者需要录制一个视频,后期对视频和音频频添加特效,比如主题、贴纸、混音、BGM等等,最终把视频上传到服务器,观众端则需要使用播放器播放以及社交互动即可;而对于直播场景同样包含这两个角色,主播端需要将内容进行实时直播,并针对于观众的一些行为完成实时互动,观众端则需要使用定制的播放器观看,这个场景下的播放器并非使用系统提供的播放器即可,必须加以定制化。

针对于录播和直播两个场景,他们的共同特点都包含视频录制器和视频播放器;区别则主要体现在是否具有实时交互性;他们需要在各自场景下做一些特殊的配置,比如对于直播来说推流的稳定性和拉流的秒开,对于录播则是后期视频处理和上传。

视频录制器的架构设计

  • 模块拆分

视频录制器分为三部分:输入、处理和输出。输入就是通过摄像头和麦克风这类采集设备去做音频和画面的采集。处理则是针对采集到的画面和声音进行处理,比如大家熟知的美颜、回声抑制、混响等等。最终输出会分为几部分:首先是预览,比如用手机录制视频时,在屏幕上会有预览画面;第二部分是编码,在安卓平台采用硬件编码+软件编码,而iOS平台的兼容性较好,所以只采用硬件编码就可以达到要求;最后将音视频数据封装成一个容器——FLV或MP4,再进行IO输出,IO输出有可能是磁盘——录播场景,也有可能向流媒体服务器推流——直播场景。

  • 音频架构设计

上图是音频架构图,由于Processor比较复杂,因此在里面没有做体现。从图中可以看到,音频架构分为Input、Output、队列和Consumer几部分,架构图上下部分分别是安卓平台和iOS平台实现的结构。

用户在K歌过程中需要混入伴奏音乐,对于安卓平台而言,需要有一个MP3的Decoder,它可以通过MAD、Lame或者FFmpeg等开源库来实现,最终通过AudioTrack 的API或者OpenSL ES的API来播放,同时我们把播放PCM数据放到PCM队列中。而在采集过程,我们一般使用Audio Recoder或OpenSL ES来采集人声,采集到的人声也会放在一个PCM队列中。在一般架构设计中,队列一般承担生产者和消费者中间解耦的角色,因此可以看到Input和Output就是上面两个队列的生产者,而Consumer线程中的Encoder就是消费者——从队列中取出PCM数据进行编码。

对于iOS平台,我们使用的AUGraph,它底层使用的是AudioUnit,其中RemoteIO类型的AudioUnit可以采集人声,AudioFilePlayer类型的AudioUnit可以播放伴奏。然后通过Mixer类型的AudioUnit将人声和伴奏混合之后入队,后面Consumer线程中的Encoder从队列中取出PCM数据进行编码。

  • 视频架构设计

视频部分的结构设计相对会简单一些。安卓平台通过Camera采集视频,在Output中首先是通过EGL Display来回显预览界面,其次编码则是采用MediaCodec硬件编码和Libx264软件编码相结合的实现方式(由于安卓平台硬件编码有可能出现兼容性问题)。

而在iOS平台则会更简单,直接使用Camera采集,然后通过GLImageView来进行渲染——GLImageView的实现方式是继承自UIView,在LayerClass中返回CAEAGLLayer,然后构造出OpenGL环境用来渲染纹理,最终再用VideoToolbox进行编码输出。编码后的数据会放到H.264队列中,那么这里的生产者就是编码器,消费者实际上是Consumer模块,它把H.264队列中数据Mux后再进行IO操作(输出到磁盘成为mp4文件或者输出到流媒体服务器)。

视频播放器架构设计

  • 模块拆分

视频播放器的模块拆分和视频录制器非常相似,同样分为输入、处理和输出三部分。首先是IO输入——本地磁盘或远程拉流,拿到码流后需要进行解封装(Demux)过程,也就是封装(Mux)的逆过程,它会把FLV中音频轨、视频轨以及字幕轨拆解出来,然后进行解码过程,一般采用采用硬件+软件解码的方案。

视频播放器中中间处理过程使用的并不算很多,音频处理上可以做一些混音或者EQ处理,画面处理则是画质增强,如自动对比度、去块滤波器等,当然播放器处理中非常重要的一环就是音视频同步,目前一般有三种模式:音频向视频同步、视频向音频同步以及统一向外部时钟同步。我们一般会选择视频向音频同步,这主要是由于两方面的原因:一方面是由人的生理特性决定的,相比于画面,人对声音的感受会更加强烈;另一方面音频PCM是线性的,我们可以信赖播放器也是线性的播放,因此在用视频帧向音频帧同步时,我们允许对视频帧进行丢帧或重复帧渲染。最后,输出则主要包含音频渲染和视频渲染两部分。

  • 运行流程

对一个多媒体文件,视频播放器会对其进行Demux和Decode处理,当解码器解码出一帧视频后给到队列,这时如果是软件解码则一般解码出来的是YUV格式,然后放入到内存队列中;如果是硬件解码则一般是显存中的纹理ID,会放到循环显存队列中。解码出音频的PCM数据也会入队。

对于这两个队列来说也同样存在生产者和消费者,解码器就是生产者,右边的Output则是消费者。这里值得一提的是,可以通过设置两个游标值来做队列的控制——minSize和maxSize,当队列中的音频大小到达minSize时,消费者则会开始工作,而当音频大小到达maxSize时,解码线程就要暂停工作(wait住),当消费者消费了队列中的内容后,队列中音频大小小于maxSize的时候,会让解码线程继续工作(发出Singal指令)。而消费者的工作流程为:从音频队列中取出一帧音频帧给音频播放模块进行播放,然后会通过AVSync音视频同步模块取出一帧对应的视频帧给视频播放模块进行播放。当生产者、消费者周而复始的运转起来,整个播放器也就运行起来了。

  • 音视频同步策略

前面提到我们音视频同步策略是采取视频向音频同步,也就是说假设我们在播放音频第一帧时,对应的第一帧视频没有过来,而此时马上要播放音频第二帧,那么我们就会选择放弃第一帧视频,继续播放第二帧从而保证用户感受到音视频是同步的;那么假设当没有播放第三帧音频时已经接收到对应的视频帧时,则会将视频帧返回,直到对应音频播放的时候再取出对应的视频帧。

那么对于普通开发者而言,想要实现播放器每一个细节其实是非常复杂的,尤其对于一些创业公司或者对于音视频积累比较薄弱的公司来说,所以直接接入CDN厂商提供的SDK是不错的选择,这样可以尽快实现自身业务逻辑,而伴随着业务的发展,后期可以针对特殊需求基于SDK进行二次开发。

从个人经验来讲,我认为SDK中技术含量较高的主要有两点:跨平台的视频处理系统和跨平台的推流系统构建,接下来我会做重点介绍。

跨平台的视频处理系统

跨平台的视频处理系统实际可以说是跨平台的图片滤镜系统,它所应用的场景主要有实现美颜、瘦脸这种单帧图片的处理,也有如雨天、老照片等主题效果,以及贴纸效果这几种。为了达到效果,我们通过OpenGL ES来实现,如果用软件(CPU中计算)做视频处理是非常消耗性能的,尤其在移动端无法接受。因此它的输入是纹理ID和时间戳,时间戳主要用于主题和贴纸场景的处理。输出则是处理完毕的纹理ID。

  • GPUImage

这里特别介绍下GPUImage框架(以iOS平台作为讲解),它的整个流程分为Input、Processor和Output。首先通过GPUImageVideoCamera采集画面;然后转化为纹理ID就可以通过模糊、混合、边缘检测、饱和度等一系列处理进行优化;最终Output中使用GPUImageView把处理完的视频帧渲染到屏幕上,而对于录制则提供了GPUImageMovieWriter,它可以将纹理ID硬件编码到本地文件。除了视频录制过程,它对视频播放器和离线处理场景提供了GPUImageMovie作为Input的实现。

  • 跨平台的视频处理系统构建

对于搭建跨平台的视频处理系统,我们需要搭建两个客户端的OpenGL环境,安卓平台使用EGL来提供上下文环境与窗口管理,iOS使用EAGL来提供上下文环境与窗口管理,然后我们抽象出统一接口服务于两个平台。

这是结构图,左边是根据平台搭建的环境——Platform OpenGL Environment,右边是视频处理系统—VideoEffectProcessor。整个过程为:首先通过Camera或者Decoder采集或者解码出视频帧纹理,将纹理ID交给VideoEffectProcessor完成视频处理功能,而这里面可能需要很多支持,比如集成一些第三方库解析XML、解析Json、libpng等等,同时我们也要暴露一些可以动态添加和删除Filter的功能。当处理完成后会输出一个Output TexId做渲染,最终呈现到界面上,或者给到Encoder做离线保存。

跨平台的推流系统

我们先来看跨平台推流系统的应用场景,首先无论网络是否抖动都要维持交互的实时性,其次要保证正常直播的流畅性,并能根据网络条件的好坏来决定清晰度,最后要有统计数据来帮助产品运营做策略优化,比如提升码率、分辨率等等。针对这三点场景分析,如何从技术角度实现?首先在弱网下做出丢帧,第二是码率自适应,第三为了保证主播端持续直播,需要做到自动断线重连。

那为什么要做跨平台的推流系统?这主要考虑到开发成本和效率的问题,从开发策略制定和测试的角度来看都可以节省一部分成本,而且一套代码在后期维护中也有很多好处。那么跨平台推流系统应该如何实现?我们使用FFmpeg将AAC和H.264封装成FLV格式,然后使用RTMP协议推到流媒体服务器上就可以。

  • 弱网丢帧

当检测到H.264或AAC队列的大小超过一定域值时,我们要做丢帧处理,因为此时可能会导致现在的数据很长时间发不出去,从而交互的实时性就无法得到保证。当我们需要进行丢帧处理时,对于视频帧要明确丢弃的是否为I帧或P帧;对于音频帧则有多种策略,可以简单丢弃与视频丢帧相同时间长度的音频帧。

  • 码率自适应


对于码率自适应,我们需要检测上行网络带宽的情况,准确的说是上行网络到推流的流媒体服务器节点的情况。当需要降低码率,我们要把现在编码队列中高码率的视频帧丢掉,并让编码器强制产生关键帧,以保证最新的视频以低码率推到服务器上完成整场直播的交互性。改变编码器的输出码率,对于libx264来说,需要在它的客户端代码中改变vbv buffer size,并Reconfig X264编码器才可以;而对于FFmpeg的API则是需要改变rc buffer size,并且需要ffmpeg 2.8版本以上才能支持;对于MediaCodec和VideoToolbox则使用各个平台硬件编码设置。

这张图是通过当前发送的码率调整实际编码器产生的视频码率,这里调整的不仅仅是码率,同时也包括帧率。当帧率较低时,单纯提升码率也无法达到视频质量提升的效果,因此两者会一起做调整。

  • 链路选择与自动重连策略

在链路选择方面,尤其在某一些特殊场景下,DNS解析不一定能找到最佳链路,我们可以选择直接接入CDN提供的接口,在主播推流前向CDN厂商请求一个最优节点,而不依赖Local DNS去解析IP地址;对于主播端,也可以POST一个500KB的flv文件,在多个推流节点测试网络链路情况,从中选择最优链路。再者推流一段时间后,网络链路有可能会出现拥塞的情况,IDC机房节点也有可能出现问题,因此SDK底层需要有自动重连机制来保证重新分配更优的链路和CDN节点,从而保证主播持续推流不受影响。

  • 数据收集

最后是数据收集,数据收集涉及到后期调优、评判链路节点等等,因此非常重要,而这也是用定制播放器的原因。基本统计的点包括连接时长、发布时长、丢帧比例、平均速率、设置速率和码率自适应的变化曲线等等。

以上是本次分享的全部内容。

酷炫短视频开发进阶&新书抽奖

此外,我们还特别邀请了展晓凯在下周二线上与我们一同分享酷炫短视频开发的设计架构、实现思路以及研发过程中的经验。

在参与直播互动的小伙伴中,将抽出10位赠送展老师的新书《音视频开发进阶指南——基于Android和iOS平台的实践》,同时我们也会面向参与直播的小伙伴开放购书优惠通道。

扫描下方图中二维码,加入直播群。

短视频客户端SDK设计与实现相关推荐

  1. 短视频开发SDK 架构设计实践

    短视频开发SDK 架构设计实践 短视频发展史 图 1 图 1 所示是短视频及直播的发展史,众所周知,2016 年是直播元年,在这期间诞生了很多直播平台,比如熊猫.映客.斗鱼等:而在 2017 年,短视 ...

  2. 短视频APP开发:短视频特效SDK功能火爆来袭!

    为什么短视频这么火呢?因为它符合了用户碎片化时间的需求,既娱乐了大众,又不会浪费用户太多时间. 短视频APP开发以互联网技术为核心,在原有的基础上不断进行创新,进而拥有多种强大的拍摄功能,让用户可以快 ...

  3. 短视频美颜sdk的漫画拍摄和慢动作的实现流程

    时下,短视频和直播两个平台已经成了手机用户们人手必备的APP,下载量也是长期高居榜首,主要原因就是因为这两个平台的趣味拍摄玩法,用户们通过短视频美颜sdk创作了各种趣味视频,用户们得到了创作收益,平台 ...

  4. 短视频美颜sdk为什么会爆火?

    短视频平台自从问世以来热度便一直保持着高升的状态,这一点大家都是有目共睹的,直到今天短视频的热度依旧只高不低,在应用市场中长期保持着下载榜前列,用人尽皆知来形容都不为过.小编在闲暇之余也喜欢刷短视频, ...

  5. 短视频美颜SDK里的祛痘功能是怎么实现的?

    上次给同学们讲过美颜SDK美白功能的实现过程,受到了大家的一致好评,今天小编继续为大家解答一些美颜功能实现方面的问题.本次要讲解的功能和美白功能的热度不相上下,它就是我们最常用的美颜功能之一--&qu ...

  6. 类似于快手、美拍、抖音短视频录制SDK接入教程

    这几年抖音短视频非常火爆,所以很多公司也希望开发短视频录制功能,现在大部分企业是通过第三方视频SDK来完成的,当然不考虑成本的,公司也可以自己开发. 先给大家看下短视频效果,没法插入视频,直接贴视频地 ...

  7. 短视频美颜sdk人脸编辑技术详解、美颜sdk代码分析

    短视频美颜sdk中人脸编辑技术可以将人像风格进行转变,小编认为这也是未来的美颜sdk的一个重要发展方向,下文小编将为大家讲解一下短视频美颜sdk中人脸编辑的关键点. 一.人脸编辑的细分关键点 1.年龄 ...

  8. 短视频美颜SDK爆火的原因分析

    短视频近几年的热度一直保持着高增速,相信在看文章的你应该也有所了解.小编在日常闲暇时间中也喜欢刷短视频,因为其内容非常有趣,多样的拍摄玩法也勾起了小编的拍摄兴趣.实际上,这些多元化的拍摄工具都是来自于 ...

  9. 直播和短视频美颜sdk的开发流程、代码分析

    目前,美颜技术是提高视频质量的重要手段之一,特别是短视频和直播两个行业.本文将介绍其开发流程和代码分析. 一.美颜SDK的开发流程 1.需求分析 首先我们需要明确的一点就是"需求" ...

最新文章

  1. django给mysql配主从_django中的mysql主从读写分离:一、配置mysql主从分离
  2. 地址总线是单向还是双向_如何区分晶闸管的单双向问题?
  3. 计算机考研310分什么水平,知乎工学考研310是什么水平
  4. python list中append()与extend()用法
  5. 在基于数据库的任务派发系统中利用SQL Server 2005 中新的查询提示来提高系统的效率...
  6. 读书笔记 effective c++ Item 41 理解隐式接口和编译期多态
  7. 图片 过度曝光_实际拍摄中,经常遇到曝光不足或过曝的结果,6种手段帮你解决...
  8. android 文本分页显示,Android查看带有列表视图的分页器并动态添加文本
  9. android创建Menu菜单
  10. JAVA 7 正式版发布 新特性一览表
  11. 一些Gym三星单刷的比赛总结
  12. 基于SSM实现毕业设计管理系统
  13. 软件工程c语言课程设计的作用,C语言课程设计指导书2016版HNUST
  14. web微信授权登陆-配置篇
  15. mysql bitmap index_位图索引:原理(BitMap index)
  16. 微信小程序标题栏放logo 搜索框
  17. 鸡尾酒疗法(C语言)
  18. redhat还能坚持多久--红帽的“帽子戏法”
  19. 各种进制数按位权展开
  20. Android Crash signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr b56cb106

热门文章

  1. APP推广,大流量都在这里!
  2. warning C4005: “AF_IPX”: 宏重定义解决办法
  3. 计算机技术进入课堂导入的好处,课堂教学导入的重要性
  4. 23种设计模式(十一)外观模式(阁瑞钛伦特软件-九耶实训)
  5. 企业知识管理平台如何进行运营推广
  6. 通电自动高通900E是什么原理?
  7. 测试入门——搜索功能测试用例设计
  8. 车间生产如何实现数字化管理,答案全在这里
  9. 个人简历一般填什么好?怎么制作工作简历?
  10. 测试开发(社招):当当