一个现代化的 iOS 直播工具是怎么样的?

如果简化移动端的直播,最简单的直播工具要如何设计?

首先是场景的确认,因为受制于 iOS 本身,只可能有两种直播方案:

  1. 主程序作为主体,那么可以 1 路视频(摄像头)输入,1 路音频(麦克风)输入,简单的视频拍摄场景,外加一个数据发送就结束了
  2. 其他程序作为主体,那么就是 ReplayKit 的方案,以 App Extension 方式工作,1 路视频(屏幕)输入,2 路音频(App+麦克风),此时需要考虑 2 路音频的混流问题,以及 50M 内存的限制

如果需求真的只是这么简单,那么绝大部分第三方 SDK 已经可以满足你的要求,选一个就好。但是往往现实都是残酷的

摄像头方案(主程序)

音频方面,背景音乐/本地文件可能是个小众选项,但是远端流可能是个无法跨越的障碍😂,对,连麦。当然也可能是另一路正在在直播的内容(解说/转播)。因此音频端你无法逃离使用一个混音器。Apple 平台自带的 AUGraph 或者 AVAudioEngine 是大概率的选项。前者已被标记废弃,后者如果要做回音消除需要 iOS 13+。CMSampleBufferAVAudioBuffer 的相互转化也不是件容易的事。CMTimeAVAudioTime 的理解也得好一会儿。还需要注意 Node Tap 的延迟。

视频方面,大概率你需要引入场景(Scene)这个概念,虽然这种情况不需要转场,但是图层一复杂,还是需要一定的抽象。单/多相机的视频流来自 AVCaptureSession。 文件/远端流解码后的 CMSampleBuffer -> CVPixelBuffer 还是相对统一。图像编解码尽量考虑硬件编解码器,VideoToolBox 中有足够的支持。图层合并从简到难可以考虑使用 CIFliterMetal Performance Shaders 或者就直接上 Metal 吧,这样预览图层也可以直接使用 MTKView

此时无数对的小溪终于汇集成了长江与黄河,你得到了最终的音视频流,如果你没有多路发布,或者写入本地文件的需求,还是可以使用支持数据流输入的第三方 SDK。但是由于大部分将编码与发送整合在一起,一旦你要一稿多投就可能重复压缩,既增加功耗,又影响性能。此时,你需要阅读一下 RTMP 的源码来找出如何发送数据。当也需要一些 mp4 的知识。但注意 RTMP 没有支持 H.265/HEVC,需要使用的话得自己和服务端确认扩展规则。

ReplayKit 方案(App Extension)

内容上基本大同小异,这种情况下大多为游戏/教学直播场景,所以背景音乐就不能忽略了。由于 ReplayKit 只能拿到激活应用的音频,因此,一个版权安全的音乐库十分重要。Apple Music 是相对比较方便的,可以直接和 AVAudioEngine 联合使用。缺点是执行设备上需要有订阅激活的 Apple Music。

今天的话题就先到这里。