如何在IOS上使用ReplayKit与RTC
在日益繁多的直播场景中,如果你也是某位游戏主播的粉丝的话,有一种直播方式是你一定不陌生的,那就是我们今天要聊的屏幕分享。
直播场景下的屏幕分享,不仅要将当前显示器所展示的画面分享给远端,也要将声音传输出去,包括应用的声音,以及主播的声音。鉴于这两点需求,我们可以简单分析出,进行一次屏幕分享的直播所需要的媒体流如下:
- 一条显示器画面的视频流
- 一条应用声音的音频流
- 一条主播声音的音频流
replaykit 是苹果提供的用于 ios 系统进行屏幕录制的框架。
首先我们来看看苹果提供的用于屏幕录制的 replaykit 的数据回调接口:
从枚举 samplebuffertype 上,我们不难看出,刚好能符合我们上述对媒体流的需求。
视频格式
通过 cvpixelbuffergetpixelformattype,我们可以获取到每帧的视频格式为 yuv420。
帧率
通过打印接口的回调次数,可以知道每秒能够获取的视频帧为30次,也就是帧率为 30。
格式与帧率都能符合 agora rtc 所能接收的范围,所以通过 agora rtc 的 pushexternalvideoframe 就可以将视频分享到远端了。
插入一个小知识
显示器所显示的帧来自于一个帧缓存区,一般常见的为双缓存或三缓存。当屏幕显示完一帧后,发出一个垂直同步信号(v-sync),告诉帧缓存区切换到下一帧的缓存上,然后显示器开始读取新的一帧数据做显示。
这个帧缓存区是系统级别的,一般的开发者是无法读取跟写入的。但是如果是苹果自身提供的录制框架 replaykit 能够直接读取到已经渲染好且将用于显示器的帧,且这一过程不会影响渲染流程而造成掉帧,那就能减少一次用于提供给 replaykit 回调数据的渲染过程。
音频
replaykit 能提供的音频有两种,分为麦克风录制进来的音频流,与当前响应的应用播放的音频流。(下文将前者称为 audiomic,后者为 audioapp)
可以通过下面的两行代码,来获取音频格式
audioapp
audioapp 会在不同的机型下有不一样的声道数。例如在 ipad 或 iphone7 以下机型中,不具备双声道播放的设备,这时候 audioapp 的数据就是单声道,反之则是双声道。
采样率在部分试过的机型里,都是 44100,但不排除在未测试过的机型会是其他的采样率。
audiomic
audiomic 在测试过的机型里,采样率为 32000,声道数为单声道。
音频前处理
如果我们将 audioapp 与 audiomic 作为两条音频流去发送,那么流量肯定是大于一条音频流的。我们为了节省一条音频流的流量,就需要将这两条音频流做混音(融合)。
但是通过上述,我们不难看出,两条音频流的格式是不一样的,而且不能保证随着机型的不同,是不是会出现其他的格式。在测试的过程中还发现 os 版本的不同,每次回调给到的音频数据长度也会出现变化。那么我们在对两条音频流做混音前,就需要进行格式统一,来应对 replaykit 给出的各种格式。所以我们采取了以下几个重要的步骤:
无论是 audiomic 还是 audioapp,只要进来的流为单声道,我们都将它转化为双声道;
无论是 audiomic 还是 audioapp,只要进来的流采样率不为 48000,我们将它们重采样为 48000;
通过第一步与第二步,我们保证了两条音频流都为同样的音频格式。但是由于 replaykit 是一次回调给到一种数据的,所以在混音前我们还得用两个缓存区来存储这两条流数据;
replaykit 有选项是否开启麦克风录制,所以在关闭麦克风录制的时候,我们就只有一条 audioapp 音频流。所以我们以这条流为主,去读取 audiomic 缓存区的数据长度,然后对比两个缓存区的数据长度,以最小的数据长度为我们的混音长度。将混音长度的两个缓存区里的数据做融合,得到混音后的数据,写入一个新的混音缓存区(或者直接写入 audioapp 缓存区);
最后我们再将这段混音后的数据拷贝进 agora rtc 的 c++ 录制回调接口里,这时候就可以把麦克风录制的声音与应用播放的声音传输到远端了。
通过对音视频流的处理,结合 agora rtc sdk,我们就完成了一个屏幕分享直播场景的实现了。
以上就是如何在ios上使用replaykit与rtc的详细内容,更多关于ios上使用replaykit与rtc的资料请关注其它相关文章!
上一篇: 小猪佩奇儿童动画片学习娱乐两不误
下一篇: 路考的笑话,看路别看我