iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >怎么在IOS上使用ReplayKit与RTC
  • 123
分享到

怎么在IOS上使用ReplayKit与RTC

2023-06-14 12:06:31 123人浏览 八月长安
摘要

小编给大家分享一下怎么在iOS上使用ReplayKit与RTC,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!直播场景下的屏幕分享,不仅要将当前显示器所展示的画面分

小编给大家分享一下怎么在iOS上使用ReplayKit与RTC,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

直播场景下的屏幕分享,不仅要将当前显示器所展示的画面分享给远端,也要将声音传输出去,包括应用的声音,以及主播的声音。鉴于这两点需求,我们可以简单分析出,进行一次屏幕分享的直播所需要的媒体流如下:

  1. 一条显示器画面的视频流

  2. 一条应用声音的音频流

  3. 一条主播声音的音频流

ReplayKit 是苹果提供的用于 ioS 系统进行屏幕录制的框架

首先我们来看看苹果提供的用于屏幕录制的 ReplayKit 的数据回调接口:

override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {        DispatchQueue.main.async {            switch sampleBufferType {            case .video:                AGoraUploader.sendVideoBuffer(sampleBuffer)            case .audioApp:                AgoraUploader.sendAudioAppBuffer(sampleBuffer)            case .audioMic:                AgoraUploader.sendAudioMicBuffer(sampleBuffer)            @unknown default:                break            }        }    }

从枚举 sampleBufferType 上,我们不难看出,刚好能符合我们上述对媒体流的需求。

视频格式

guard let videoFrame = CMSampleBufferGetImageBuffer(sampleBuffer) else {    return}        let type = CVPixelBufferGetPixelFORMatType(videoFrame)
type = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange

通过 CVPixelBufferGetPixelFormatType,我们可以获取到每帧的视频格式为 yuv420

帧率

通过打印接口的回调次数,可以知道每秒能够获取的视频帧为30次,也就是帧率为 30。

格式与帧率都能符合 Agora RTC 所能接收的范围,所以通过 Agora RTC 的 pushExternalVideoFrame 就可以将视频分享到远端了。

agoraKit.pushExternalVideoFrame(frame)

插入一个小知识

显示器所显示的帧来自于一个帧缓存区,一般常见的为双缓存或三缓存。当屏幕显示完一帧后,发出一个垂直同步信号(V-Sync),告诉帧缓存区切换到下一帧的缓存上,然后显示器开始读取新的一帧数据做显示。

这个帧缓存区是系统级别的,一般的开发者是无法读取跟写入的。但是如果是苹果自身提供的录制框架 ReplayKit 能够直接读取到已经渲染好且将用于显示器的帧,且这一过程不会影响渲染流程而造成掉帧,那就能减少一次用于提供给 ReplayKit 回调数据的渲染过程。

音频

ReplayKit 能提供的音频有两种,分为麦克风录制进来的音频流,与当前响应的应用播放的音频流。(下文将前者称为 AudioMic,后者为 AudioApp)

可以通过下面的两行代码,来获取音频格式

CMAudioFormatDescriptionRef format = CMSampleBufferGetFormatDescription(sampleBuffer);const AudioStreamBasicDescription *description = CMAudioFormatDescriptionGetStreamBasicDescription(format);

AudioApp

AudioApp 会在不同的机型下有不一样的声道数。例如在 iPad 或 iPhone7 以下机型中,不具备双声道播放的设备,这时候 AudioApp 的数据就是单声道,反之则是双声道。

采样率在部分试过的机型里,都是 44100,但不排除在未测试过的机型会是其他的采样率。

AudioMic

AudioMic 在测试过的机型里,采样率为 32000,声道数为单声道。

音频前处理

如果我们将 AudioApp 与 AudioMic 作为两条音频流去发送,那么流量肯定是大于一条音频流的。我们为了节省一条音频流的流量,就需要将这两条音频流做混音(融合)。

但是通过上述,我们不难看出,两条音频流的格式是不一样的,而且不能保证随着机型的不同,是不是会出现其他的格式。在测试的过程中还发现 OS 版本的不同,每次回调给到的音频数据长度也会出现变化。那么我们在对两条音频流做混音前,就需要进行格式统一,来应对 ReplayKit 给出的各种格式。所以我们采取了以下几个重要的步骤:

if (channels == 1) {    int16_t* intData = (int16_t*)dataPointer;    int16_t newBuffer[totalSamples * 2];                for (int i = 0; i < totalSamples; i++) {        newBuffer[2 * i] = intData[i];        newBuffer[2 * i + 1] = intData[i];    }    totalSamples *= 2;    memcpy(dataPointer, newBuffer, sizeof(int16_t) * totalSamples);    totalBytes *= 2;    channels = 2;}

无论是 AudioMic 还是 AudioApp,只要进来的流为单声道,我们都将它转化为双声道;

if (sampleRate != resampleRate) {    int inDataSamplesPer10ms = sampleRate / 100;    int outDataSamplesPer10ms = (int)resampleRate / 100;    int16_t* intData = (int16_t*)dataPointer;    switch (type) {        case AudioTypeApp:            totalSamples = resampleApp(intData, dataPointerSize, totalSamples,                                       inDataSamplesPer10ms, outDataSamplesPer10ms, channels, sampleRate, (int)resampleRate);            break;        case AudioTypeMic:            totalSamples = resampleMic(intData, dataPointerSize, totalSamples,                                       inDataSamplesPer10ms, outDataSamplesPer10ms, channels, sampleRate, (int)resampleRate);            break;    }    totalBytes = totalSamples * sizeof(int16_t);}

无论是 AudioMic 还是 AudioApp,只要进来的流采样率不为 48000,我们将它们重采样为 48000;

memcpy(appAudio + appAudioIndex, dataPointer, totalBytes);appAudioIndex += totalSamples;
memcpy(micAudio + micAudioIndex, dataPointer, totalBytes);micAudioIndex += totalSamples;

通过第一步与第二步,我们保证了两条音频流都为同样的音频格式。但是由于 ReplayKit 是一次回调给到一种数据的,所以在混音前我们还得用两个缓存区来存储这两条流数据;

int64_t mixIndex = appAudioIndex > micAudioIndex ? micAudioIndex : appAudioIndex;        int16_t pushBuffer[appAudioIndex];        memcpy(pushBuffer, appAudio, appAudioIndex * sizeof(int16_t));        for (int i = 0; i < mixIndex; i ++) {   pushBuffer[i] = (appAudio[i] + micAudio[i]) / 2;}

ReplayKit 有选项是否开启麦克风录制,所以在关闭麦克风录制的时候,我们就只有一条 AudioApp 音频流。所以我们以这条流为主,去读取 AudioMic 缓存区的数据长度,然后对比两个缓存区的数据长度,以最小的数据长度为我们的混音长度。将混音长度的两个缓存区里的数据做融合,得到混音后的数据,写入一个新的混音缓存区(或者直接写入 AudioApp 缓存区);

[AgoraAudioProcessing pushAudioFrame:(*unsigned* *char* *)pushBuffer                                   withFrameSize:appAudioIndex * *sizeof*(int16_t)];

最后我们再将这段混音后的数据拷贝进 Agora RTC 的 c++ 录制回调接口里,这时候就可以把麦克风录制的声音与应用播放的声音传输到远端了。

通过对音视频流的处理,结合 Agora RTC SDK,我们就完成了一个屏幕分享直播场景的实现了。

以上是“怎么在IOS上使用ReplayKit与RTC”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 怎么在IOS上使用ReplayKit与RTC

本文链接: https://www.lsjlt.com/news/270783.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么在IOS上使用ReplayKit与RTC
    小编给大家分享一下怎么在IOS上使用ReplayKit与RTC,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!直播场景下的屏幕分享,不仅要将当前显示器所展示的画面分...
    99+
    2023-06-14
  • IBeacon怎么在IOS中使用
    这期内容当中小编将会给大家带来有关IBeacon怎么在IOS中使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。什么是iBeacon?iBeacon 是苹果公司2013年9月发布的移动设备用OS(iOS7...
    99+
    2023-06-14
  • 怎么在IOS中使用Cordova插件
    这篇文章给大家分享的是有关怎么在IOS中使用Cordova插件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、准备插件功能:打开IOS相机1:创建插件plugman create --name [插件名称] -...
    99+
    2023-06-14
  • 如何在 iOS 17 上使用待机模式
    您是否已准备好 unleashing the potential of iPhone through iOS 17 With its included features, your life will be made easier.。其中一...
    99+
    2023-08-02
  • 如何在iOS 17上使用个人语音
    iOS 17:如何使用个人语音苹果iPhone的辅助功能使有特殊需求的人更容易使用该设备。为了与这一策略保持一致,Apple正在iOS 17中引入另一项称为“个人语音”的功能,这对于有可能失去声音或说话能力的人来说非常有益。您可以使用此工具...
    99+
    2023-07-16
  • IOS NSTimeInterval怎么使用
    在iOS中,NSTimeInterval是一种时间间隔的数据类型,以秒为单位。你可以使用NSTimeInterval来表示两个时间点...
    99+
    2024-03-05
    IOS
  • 怎么在Mac上配置iOS开发环境
    本篇内容主要讲解“怎么在Mac上配置iOS开发环境”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么在Mac上配置iOS开发环境”吧!第一步:安装PlatformAssistant 当你布署iO...
    99+
    2023-07-01
  • 怎么在IOS中使用ADisplayLink刷新屏幕
    怎么在IOS中使用ADisplayLink刷新屏幕?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。什么是CADisplayLink我们在应用中创建一个新的CADisplayL...
    99+
    2023-06-15
  • iOS中NavigationController怎么使用
    在iOS中,可以通过以下步骤来使用NavigationController:1. 创建一个NavigationController对...
    99+
    2023-09-26
    iOS
  • iOS中CocoaPods怎么使用
    要在iOS中使用CocoaPods,您需要按照以下步骤进行操作:1. 首先,您需要在您的mac上安装CocoaPods。打开终端并输...
    99+
    2023-09-29
    iOS
  • iOS中AFNetworking怎么使用
    在iOS中使用AFNetworking可以按照以下步骤进行:1. 导入AFNetworking库:将AFNetworking库添加到...
    99+
    2023-09-21
    iOS
  • iOS中PerformSelector怎么使用
    在iOS中,`performSelector`方法用于调用对象的指定方法。使用方法如下:1. 调用无参数方法:```swiftlet...
    99+
    2023-09-06
    iOS
  • iOS中CAKeyframeAnimation怎么使用
    在iOS中,可以使用CAKeyframeAnimation实现关键帧动画。下面是使用CAKeyframeAnimation的步骤:1...
    99+
    2023-09-29
    iOS
  • 如何在 iPhone iPad 和 iOS 上使用 Apple Messages 应用程序
    iPhone 和 iPad 消息应用程序为用户提供了一个全面的数字通信工具,提供了一系列功能来增强您的消息传递体验。从管理已发送的消息到个性化您的个人资料,该应用程序为您的所有消息传递需求提供了一个用户友好的界面。无论您是偶尔发送短信的临时...
    99+
    2023-07-16
  • 怎么在Windows笔记本上调试运行在iOS设备上的前端应用
    本篇文章为大家展示了怎么在Windows笔记本上调试运行在iOS设备上的前端应用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。我在每天工作中需要在不同的移动设备上测试我们开发的前端应用是否正常工作,...
    99+
    2023-06-05
  • 怎么在Linux上使用pkgsrc
    本篇内容介绍了“怎么在Linux上使用pkgsrc”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么使用 pkgsrc?除了 MacOS ...
    99+
    2023-06-16
  • 怎么在Linux上使用tarball
    这篇文章主要介绍了怎么在Linux上使用tarball,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。“tarball” (LCTT 译注:国内也常称为“tar 包”)一词通常...
    99+
    2023-06-16
  • iOS开发中nstimeinterval怎么使用
    NSTimeInterval是一个双精度浮点型的时间间隔,它表示自2001年1月1日午夜(GMT)以来的秒数。在iOS开发中,我们可...
    99+
    2023-08-24
    nstimeinterval
  • iOS开发中rangeOfString怎么使用
    rangeOfString是一个NSString类的方法,用于在字符串中查找指定的子字符串。它返回一个NSRange结构体,指示子字...
    99+
    2023-09-15
    iOS
  • iOS开发中AvaudioPlayer怎么使用
    在iOS开发中,你可以使用AVAudioPlayer类来播放音频文件。下面是使用AVAudioPlayer的基本步骤:1. 导入AV...
    99+
    2023-09-13
    iOS
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作