前语

  1. 好长时刻没写文章,或许排版不是很美观。
  2. 此系列文章是我对自己最近所学技能的总结和沉淀,规划到的一些技能点和完成计划并不一定是最好,如有不同意见能够在评论区留言共同讨论以及学习。
  3. 此系列文章内容大都是依据我的了解进行描述,或许大白话比较多。
  4. 下面直接进入正题。

我所了解的开播

在我的了解中,开播的整个进程在技能完成上能够了解为2条(音频 & 视频)流水线。
这2条流水线能够划分为相同的5个阶段,即:收集、事务处理、烘托、编码、推流,其中 事务处理 阶段即是咱们完成App开播事务逻辑的阶段,这个阶段的复杂度跟事务的复杂度相关。
下面对视频和音频的这5个阶段别离进行解说。

视频

基础知识概念

视频流水线上面流动到各个阶段的“物品”是什么?

并不是一段视频,而是一帧一帧的图画。至于图画也仅仅一个抽象概念,在各阶段或许会有各种不同的表现形式,如:
* 图片:UIImage,CIImage,CGImage 等。
* 像素数据:CVBuffer/CVImageBuffer/CVPixelBuffer,检查体系源码能够发现这3种其实是同一品种型,仅仅经过`typedef`重命名了罢了,所以遇到了不要慌。
* 纹路:GLTexture(OpenGLES),MTLTexture(Metal)。
以上3种图画表现形式之间都能够相互转化,详细的转化办法能够[百度](https://www.baidu.com)。

OpenGLES / Metal 是什么?

OpenGLESMetal都是用来驱动GPU做图画处理的框架。
OpenGLESAppleOpenGL进行封装,使其能够在iOS体系运用。
MetalApple针对现代化GPU设备规划的新版图画处理框架,并且选用面向对象的思维进行封装。建议运用Metal。
当然,这两者在运用上十分相似,你只要会其中一个,那么另一个对你来说也就不难了。
但你至少得会一个
假如都不会,我建议直接学Metal,详细怎么学?[传送门](https://github.com/bytedance/AlphaPlayer) 研讨研讨,研讨理解就学会了。

收集

此阶段要做的便是每隔一段时刻输出一个图画(一般是CVPixelBuffer)交给下一阶段处理。
一般来说,常用的视频收集类型有以下几种:

  • 摄像头:开启摄像头收集视频帧,能够运用体系库AVFoundation的AVCaptureSession完成此功用。
  • 静态图片:由App设置一张图片(UIImage等),在此收集类中将UIImage转化成CVPixelBuffer并以自定义的频率输出。
  • 视频:由App设置一个视频文件(mp4等),能够运用体系库AVFoundation解码并读取视频的每一帧CVPixelBuffer输出即可。

事务处理

此阶段和其他阶段不同,它不是像收集这样详细的功用,而是多个子阶段的组合,而这些子阶段则是依据详细的App事务完成的。
以咱们这个直播软件的事务来说,子阶段首要包括:

  • 美颜:接纳当时主播的图画纹路,输出添加美颜作用后的图画纹路。
  • PK合流:接纳当时主播的图画纹路 和 对方主播的图画纹路,经过OpenGLES/Metal将两个纹路兼并成一个纹路并输出。
  • 兴趣连麦:接纳当时主播的图画纹路 和 指定兴趣资源图片的图画纹路,经过OpenGLES/Metal将两个纹路兼并成一个纹路并输出。

当主播处于非PK态的事务场景时,这一阶段就只需求 美颜 处理即可;
当主播处于PK态的事务场景时,这一阶段就需求 美颜+PK合流 组合起来;
当主播处于兴趣连麦PK态的事务场景时,这一阶段就需求 美颜+兴趣连麦+PK合流 组合到一起。


注解:

  1. 美颜阶段细分的话又能够分为其他几个子阶段,比方人脸识别、磨皮、妆容、挂件等几个阶段,但由于咱们这个直播软件美颜是接入的第三方SDK,这里就不再详细分析美颜的子阶段了。后边另起文章专门解说美颜的完成吧。
  2. PK合流和兴趣连麦的完成根本共同,不同的仅仅片选着色器的代码中定义的纹路兼并规则不同。(PK合流是将画面别离制作在输出纹路的左右两边,兴趣连麦合流是将画面制作在上下两层)
  3. PK合流中 对方主播的图画纹路,咱们是经过接入的第三方视频通话SDK中的回调 获取到的。

烘托

此阶段要做的便是接纳一个图画纹路,经过OpenGLES/Metal将纹路制作到CAEAGLLayer/MTKView上。
很简单,就几十行代码,找个demo抄一下或者自己写都行。

编码

编码说直白点便是将视频帧紧缩,至于H.264和H.265等等便是一种紧缩算法。

  1. 为什么一定要编码?
稍微计算一下
假设收集阶段收集的视频帧大小是`720 * 1280`,CVPixelBuffer的像素格局是BGRA,帧率是30。
则每秒钟需求发送的数据量至少是`720 * 1280 * 4 * 30`字节,约等于105M,用户的手机网速有必要到达105M/s才干正常直播,明显这是十分不合理的。
  1. 怎么完成视频编码?
能够运用iOS体系库VideoToolBox编码,设置好帧间隔,码率,视频大小,紧缩算法等参数,然后传视频帧进去就好了。
(机械,嘎嘎,机械,我仅仅一个没有爱情的API调用机器)

这里只介绍了编码是什么,以及运用什么东西去完成它,至于详细的紧缩原理今后再另起一篇文章细说吧,假如读者猎奇,能够自行去查找相关资料,网上一大堆。

推流

这个阶段便是流水线的终点了。在主播开播的时分就要和服务端树立长链接通道,当收到编码紧缩后的视频帧时,将视频帧的二进制数据经过长衔接通道发送给服务端。

长衔接有多种协议类型,咱们目前选用的是RTMP协议推流,当然还有其他品种,详细运用什么协议由你们和自己的服务端商定。
怎么完成?
一般这种通用的长衔接协议,都是有人封装好了代码库的。要不,,,从github上找找?

音频

音频流水线和视频流水线在阶段上差不多,没有视频处理起来那么麻烦,可是需求了解一些音频数据结构相关的知识。

收集

此阶段经过麦克风录制声响并将声响存储为二进制数据输出交给下一阶段处理。
怎么完成?

运用体系库AVFoundation 或 AudioUnit。

事务处理

此阶段能够依据不同的事务对音频数据做一些处理

  1. 音效:萝莉音、大叔音、机械音等。能够经过一些算法对二进制数据修改,从而就能够到达改动音色的作用。(也有一些第三方的代码库)

  2. 混音:将多路音频数据混合成一路音频数据并输出,PK事务中会运用。

这里有两种混音计划:
* 体系库:体系供给了音频混合的API,学习怎么调用即可。
* 算法:[音频混合算法](https://blog.csdn.net/unique_no1/article/details/123520817)

烘托

音频的烘托实际上便是音频的播映
完成计划:仍是调用体系API,没什么可说的。

编码

和视频一样,编码实质上便是用了紧缩数据量的,虽然音频数据量没视频那么大,可是能少一点是一点
完成计划:仍是调用体系API,没什么可说的。

推流

和视频的推流一样,将编码后的二进制数据经过长衔接发送给服务端

  • 音视频推流的时分最好做一下时刻戳对齐,以防止画面和声响对不上的状况呈现。
  • 网络环境不好的时分。能够下降编码的码率,使画面变模糊,网络环境好时再康复;也能够选择性的丢掉掉一些帧。

总结

本篇文章扼要的介绍了开播端技能完成上的阶段和概念,并针对每个阶段供给了一些完成的计划。

收拾一下,咱们能够发现,开播最难的当地其实是事务处理阶段。由于其他的阶段,功用完成完后边根本上不会有什么变更了,并且这些阶段的完成计划大部分都是基于体系库api就能够完成,不必去找第三方的代码库。
事务处理阶段难,但其实它也不是很难,依据不同的事务场景去拼接子阶段就好了。

最后

码字不易,本文地址:https:///post/7180739989821456443