SendBirdCalls 1.10.21

SendBirdCalls 1.10.21

由以下人员维护:Young HwangMinhyuk KimSDK-AutomationDamon.ParkJed GyeongCelineTez Park



  • Young Hwang,Minhyuk Kim,Damon Park,Celine Moon,Jed Gyeong 和 Tez Park

Sendbird 为 iOS 提供的 Calls SDK

iOS 9.0+ Languages Languages Coverage CocoaPods Compatible Carthage Compatible Commercial License

目录

  1. 简介
  2. 开始之前
  3. 开始
  4. 为 SDK 配置应用程序
  5. 进行您的首次通话
  6. 实施指南
  7. 附录
  8. 故障排除

简介

Sendbird通话是我们产品组合中的最新成员。它允许Sendbird应用内的用户进行实时通话。提供了iOS、Android和JavaScript平台的SDK。开发者可以使用其中任意一种,快速将语音和视频通话功能集成到自己的客户端应用中,使用户能够在Sendbird平台上制作和接收基于网页的实时语音和视频通话。

如果您在解决问题或有任何疑问,请访问我们的社区

工作原理

Sendbird Calls SDK for iOS提供了一套框架,用于进行和接收语音和视频通话。直接通话是指在SDK中指的一对一通话。要拨打语音或视频通话,拨打者需指定目标接收者的用户ID,然后拨打。拨打后,所有被叫者的认证设备都会收到来电通知。被叫者可以从中选择一个设备接受通话。通话被接听后, Callers和Callers的设备之间建立连接,这标志着直接通话的开始。通话参与者可以静音自己或使用扬声器、麦克风等输出设备拨打具有音频的语音或音频和视频。任何一方都可以结束通话。《Sendbird Dashboard》在通话菜单中显示通话记录,供仪表板所有者和管理员查阅。

更多关于Sendbird Calls SDK for iOS

更多关于Sendbird Calls iOS的信息,请访问Calls SDK for iOS文档


开始之前

本部分展示了您在使用Sendbird Calls SDK for iOS之前需要检查的必备条件。

需求

  • iOS 11.0 及以上版本
  • Swift 5 及以上版本,Objective-C
  • Xcode 14.1 及以上版本,macOS Sierra 或更高版本。

SDK 依赖项

  • WebRTC 框架,可通过 Swift Package ManagerCocoaPodsCarthage 或手动设置进行集成。

入门指南

本节提供您开始使用 Sendbird Calls SDK for iOS 所需的信息。

安装 Calls SDK

Swift Package Manager

前往您的 Swift 包管理器的 文件 选项卡,选择 Swift 包。然后选择 添加包依赖

SendBirdCalls 框架添加到您的包仓库,使用以下 URL:https://github.com/sendbird/sendbird-calls-ios

要添加包,选择适当的依赖规则,然后单击 添加包

CocoaPods

CocoaPods 是 Cocoa 项目的依赖管理器。可以使用以下方法通过 CocoaPodsSendBirdCalls 框架集成到 Xcode 项目中。

  1. 在项目目录中运行 pod init 以将 CocoaPods 安装到项目中。
  2. 运行 open Podfile
  3. 在打开的 Podfile 中,将 pod 'SendBirdCalls' 添加到项目目标的配置下。
  4. 在项目目录中运行 pod install 以安装 SendBirdCalls 框架。

有关 CocoaPods 的使用和安装的详细信息,请参阅 CocoaPods 的 网站

注意:iOS 版本的 Sendbird Calls SDK 依赖于 SendBirdWebRTC 框架。SendBirdWebRTC 基于 GoogleWebRTC 并且已启用 bitcode 重新编译。由于 SendBirdWebRTC 作为依赖项包含在 SendBirdCalls 中,因此不需要显式下载。

Carthage

Carthage 是另一个 Xcode 项目的依赖管理器。通过以下步骤可以使用 Carthage 在您的 Xcode 项目中集成 SendBirdCalls 框架。

  1. 通过在终端运行 brew install carthage 获取 Carthage,或者选择 另一种安装方法
  2. 在与 .xcodeproj.xcworkspace 相同的目录下创建一个 Cartfile
  3. 将以下依赖项列表添加到 Cartfile 中。
github "sendbird/sendbird-calls-ios" ~> 1.10.7
github "sendbird/sendbird-webrtc-ios" ~> 1.7.0
  1. 在终端中运行 carthage update --use-xcframeworks
  2. .xcodeproj.xcworkspace 相同的目录下将出现一个 Cartfile.resolved 文件和一个 Carthage 目录。
  3. Carthage/Build/iOS 中构建的 .framework 二进制文件拖放到应用程序的 Xcode 项目中。

要深入了解,请从Carthage的ReadMe文档继续阅读。如果您在使用Carthage安装SendBirdCalls时遇到任何问题,请确保您正在使用最新版本的Carthage

手动设置

如果您不想使用CocoaPodsCarthage来安装Calls SDK,这里有另一种方法:您可以手动将SendBirdCalls直接集成到项目中。SendBirdCalls框架以.xcframework文件的形式提供。

  1. 以下任一方式下载框架文件:
    • 从git发布中直接下载
    • Git子模块
    • 其他包管理工具
  2. 将下载的框架文件复制到您的项目目录中。
  3. 转到Xcode项目导航器的通用标签,并滚动到框架、库和嵌入内容菜单。
  4. 点击+按钮,选择其他...下拉菜单,然后选择添加文件...选项。
  5. 从文件导航器中选择您之前下载的框架。
  6. 在所选框架的嵌入菜单中选择嵌入 & 签名选项。

因为SendBirdCalls需要SendBirdWebRTC作为依赖项,您还需要安装SendBirdWebRTC


配置应用以使用SDK

后台模式

为了支持后台操作,使用VoIP的App必须在Xcode项目> 签名 & 权限面板中启用后台模式。选择VoIP的复选框。

要接收推送通知,该应用还必须在Xcode项目 > 签名与能力选项卡中启用推送通知

有关VoIP推送通知和PushKit的更多信息,请参阅Apple的CallKitPushKit

配置应用的Info.plist文件

iOS要求应用显示授权信息以授予应用访问相机和麦克风的权限。


进行第一个拨打电话

按照以下分步说明进行验证并执行您的第一个拨打电话。

步骤1:在客户端应用中初始化SendBirdCall实例

如图所示,必须在客户端应用启动时初始化SendBirdCall实例。使用您要用于拨打电话的Sendbird应用的APP_ID初始化SendBirdCall实例。

SendBirdCall.configure(appId: APP_ID)

注意:如果有另一个APP_ID进行初始化,应用程序中所有现有数据将被删除,并将使用新的APP_ID初始化SendBirdCall实例。

步骤 2: 验证用户并注册推送令牌

为了发送和接收呼叫,使用 SendBirdCall.authenticate(with:) 方法通过 SendBird 服务器验证用户,并将 VoIP 推送令牌 注册到 Sendbird。在验证完成后,通过 SendBirdCall.registerVoIPPush(token:) 方法注册 VoIP 推送令牌。VoIP 推送通知还可以使即使在应用处于后台或已终止状态时也能接收到呼叫。还需要在 Sendbird 控制台 上注册有效的 APNS 证书: 应用 > 设置 > 通知 > 添加证书。有关推送令牌注册的更多详细信息,请参阅iOS SDK 呼叫指南

// Authenticate
let params = AuthenticateParams(userId: userId, accessToken: accessToken)
SendBirdCall.authenticate(with: params) { user, error in
    guard let user = user, error == nil else {
        return
    }
    // The user has been authenticated successfully
}

// Update push token
class AppDelegate: PKPushRegistryDelegate {
    func voipRegistration() {
        self.voipRegistry = PKPushRegistry(queue: DispatchQueue.main)
        self.voipRegistry?.delegate = self
        self.voipRegistry?.desiredPushTypes = [.voIP]
    }

    ...
    func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
        SendBirdCall.registerVoIPPush(token: pushCredentials.token, unique: true) { (error) in
            guard let error = error else {
                return
            }
            // The Push Token has been registered successfully
        }
    }
    ...
}

步骤 3: 添加事件处理器

SDK 提供两种事件处理器,用于处理客户端应用可能需要响应的各种事件:SendBirdCallDelegateDirectCallDelegate.

- SendBirdCallDelegate

使用 SendBirdCall.addDelegate(:) 方法注册特定于设备的 SendBirdCallDelegate 事件处理器。在添加 SendBirdCallDelegate 之前,用户将无法处理 didStartRinging(:) 代理事件。建议在初始化时添加事件处理器,因为它是检测 didStartRinging(:) 代理事件的前提条件。《SendBirdCallDelegate》在应用终止时会被移除。下面的代码演示了添加《SendBirdCallDelegate》后如何处理诸如 incoming calls 这样的全局事件。

SendBirdCall.addDelegate(self, identifier: UNIQUE_HANDLER_ID)
func didStartRinging(_ call: DirectCall) {
    // Process incoming call
}
方法 在以下情况下调用
didStartRinging() 接收到来电时,在被叫设备上。

- DirectCallDelegate

使用 call.delegate 注册特定的 DirectCallDelegate 事件代理。以下是如何管理针对成功建立呼叫连接等其他特定事件响应的示例。

func didEstablish(_ call: DirectCall)

func didConnect(_ call: DirectCall)

func didEnd(_ call: DirectCall)

func didRemoteAudioSettingsChange(_ call: DirectCall)

func didRemoteVideoSettingsChange(_ call: DirectCall)

func didUpdateCustomItems(call: DirectCall, updatedKeys: [String])

func didDeleteCustomItems(call: DirectCall, deletedKeys: [String])

func didStartReconnecting(_ call: DirectCall)

func didReconnect(_ call: DirectCall)

func didAudioDeviceChange(_ call: DirectCall, session: AVAudioSession, previousRoute: AVAudioSessionRouteDescription, reason: AVAudioSession.RouteChangeReason)

方法 调用标准
didEstablish() 被叫者使用 directCall.accept() 方法接受了呼叫,但打电话人和被叫者设备尚未连接到媒体设备。
didConnect() 打电话人和被叫者之间的媒体设备(如麦克风和扬声器)之间已建立连接。可以开始语音或视频通话。
didEnd() 通话在打电话人或被叫者的设备上结束。使用任何一方的 directCall.end() 方法关闭通话时,将调用 directCall.end 事件监听器。如果由于其他原因结束通话,也会调用 directCall.end 事件监听器。有关所有可能的通话终止原因,请参阅附录中的通话结果。
didRemoteAudioSettingsChange() 另一方更改了他们的音频设置。
didRemoteVideoSettingsChange() 另一方更改了他们的视频设置。
didUpdateCustomItems() DirectCall 的一个或多个自定义项目(元数据)已被更新。
didDeleteCustomItems() DirectCall 的一个或多个自定义项目(元数据)已被删除。
didStartReconnecting() DirectCall 在媒体连接中断后开始尝试重新连接到另一方。
didReconnect() 中断的媒体连接重新建立。
didAudioDeviceChange() 通话中使用的音频设备已更改。

第 4 步:发起呼叫

首先,准备包含初始通话配置的 DialParams 通话参数对象以发起通话。参数包括被叫者用户 ID、音频或视频功能以及 CallOptions 对象。一旦准备就绪,将 DialParams 对象传递给 SendBirdCall.dial() 方法开始通话。

let dialParams = DialParams(calleeId: CALLEE_ID, isVideoCall: false, callOptions: CallOptions(), customItems: [:])

let directCall = SendBirdCall.dial(with: dialParams) { directCall, error in
    //
}

directCall.delegate = self

第5步:接收电话

首先注册 SendBirdCallDelegate 来接收来电。使用 directCall.accept()directCall.end() 方法接受或拒绝来电。如果接听电话,SDK 将自动建立媒体会话。

在接受任何电话之前,必须在 SendBirdCallDelegate 中预先注册 directCall.delegate。一旦注册,DirectCallDelegate 就可以通过代理方法来响应电话中的事件。

class MyClass: SendBirdCallDelegate {
    func didStartRinging(_ call: DirectCall) { 
        call.delegate = self
    }
}

实现指南

发起电话

首先,准备包含初始通话配置的 DialParams 通话参数对象以发起通话。参数包括被叫者用户 ID、音频或视频功能以及 CallOptions 对象。一旦准备就绪,将 DialParams 对象传递给 SendBirdCall.dial() 方法开始通话。

let dialParams = DialParams(calleeId: CALLEE_ID, isVideoCall: false, callOptions: CallOptions(), customItems: [:])

let directCall = SendBirdCall.dial(with: dialParams) { directCall, error in
    //
}

directCall.delegate = self

接收电话

首先注册 SendBirdCallDelegate 来接收来电。使用 directCall.accept()directCall.end() 方法接受或拒绝来电。如果接听电话,SDK 将自动建立媒体会话。

在接受任何电话之前,必须在 SendBirdCallDelegate 中预先注册 directCall.delegate。一旦注册,DirectCallDelegate 就可以通过代理方法来响应电话中的事件。

class MyClass: SendBirdCallDelegate {
    func didStartRinging(_ call: DirectCall) { 
        call.delegate = self
    }
}

当应用处于前台时,通过 SDK 的持久内部服务器连接接收来电事件。然而,当应用终止或在后台时,通过 PushKit 接收来电。通过 SendBirdCall 收到的 PushKit 消息必须传递到 SendBirdCall.pushRegistry(_:didReceiveIncomingPushWith:for:) 方法。

class MyClass: PKPushRegistryDelegate {
    func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
        SendBirdCall.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type) { uuid in
      
            // IMPORTANT: Incoming calls MUST be reported when receiving a pushkit push. 
            let provider = CXProvider(configuration: CXProviderConfiguration)
            let update = CXCallUpdate()
            update.remoteHandle = CXHandle(type: .generic, value: HANDLE_VALUE)
            provider.reportNewIncomingCall(with: uuid, update: update) { error in
                completion()
            })
        }
    }
}

处理当前通话

在通话过程中,可以通过directCall.muteMicrophone()directCall.unmuteMicrophone()方法将麦克风静音或取消静音。当远程用户更改音频设置时,通过DirectCallDelegate.didRemoteAudioSettingsChange()代理方法通知本地用户任何更改。

可以通过directCall.startVideo()directCall.stopVideo()方法开始或停止视频。如果远程用户更改视频设置,本地用户将通过DirectCallDelegate.didRemoteVideoSettingsChange()监听器通知。可以通过使用directCall.selectVideoDevice(_:completionHandler)更改当前视频设备。

// mute my microphone
call.muteMicrophone();

// unmute my microphone
call.unmuteMicrophone();

// starts to show video
directCall.startVideo();

// stops showing video
directCall.stopVideo();

// changes current video device
directCall.selectVideoDevice(videoDevice) { error in
    // handle error
}

// receives the event
class MyClass: DirectCallDelegate {
    ...
    func didRemoteAudioSettingsChange(_ call: DirectCall) {
        if call.isRemoteAudioEnabled {
            // The peer has been unmuted.            
        } else {
            // The peer has been muted.
        }
    }
    
    func didRemoteVideoSettingsChange(_ call: DirectCall) {
        if call.isRemoteVideoEnabled {
            // The peer has been unmuted.
        } else {
            // The peer has been muted.
        }
    }
    ...
}

结束通话

可以通过directCall.end()方法结束通话。事件将通过DirectCallDelegate.didEnd(call:)代理处理。如果远程用户结束通话,此代理也将被触发。

// End a call
call.end();

// receives the event
class MyClass: DirectCallDelegate {
    ...
    func didEnd(_ call: DirectCall) {
        // Consider releasing or destroying call-related view from here.
    }
    ...
}

注销用户和取消VoIP推送令牌注册

注销用户

当用户从他们的通话客户端应用程序注销时,他们必须使用SendBirdCall.deauthenticate(voipPushToken:completionHandler:)方法进行去认证。如果没有包含VoIP推送令牌,即使应用关闭,注销的用户也会不断地收到来电通知。

class MyClass {
    func signOut() {
        SendBirdCall.deauthenticate(voipPushToken: myVoIPPushToken) { error in
            guard error == nil else {
                // handle error
                return
            }

            // ...
        }
    }
}

注销一个或所有VoIP推送令牌

使用方法unregisterVoIPPush(token:completionHandler:)注销VoIP推送令牌后,用户将不再接收通话通知。要停止向所有已登录的用户设备发送通知,请调用方法unregisterAllVoIPPushTokens(completionHandler:)

class MyClass {
    func removeVoIPPushToken() {
        SendBirdCall.unregisterVoIPPush(token: myVoIPPushToken) { error in
        guard error == nil else { return }
        // Unregistered successfully
    }

    func removeAllOfVoIPPushTokens() {
        func unregisterAllVoIPPushTokens(completionHandler: ErrorHandler?) {
            guard error == nil else { return }
            // Unregistered all push tokens successfully
        }
    }
}

镜像SendBirdVideoView

当摄像头面向用户时,可以将当前用户的本地视频视图设置为镜像或反转。在UIView中,可以使用如下所示的CGAffineTransform(scaleX:y:)方法轻松实现

// localSBView is SendBirdVideoView object
localSBView.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)

如果要反转变换过摄像头方向(从前置到后置以及反之)的本地视频视图,请使用以下方法

func mirrorLocalVideoView(isEnabled: Bool) {
    guard let localSBView = self.localVideoView?.subviews.first else { return }
    switch isEnabled {
        // Show Mirrored view
        case true: localSBView.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
        // Show original view
        case false: localSBView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
    }
} 


// Flipping camera
self.call.selectVideoDevice(oppositeCamera) { error in
    guard error == nil else { return }

    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        switch oppositeCamera.position {
            case .front: self.mirrorLocalVideoView(isEnabled: true)
            case .back: self.mirrorLocalVideoView(isEnabled: false)
            default: return
        }
    }
}

检索通话信息

可以通过directCall.localUserdirectCall.remoteUser属性获取到本地或远程用户的信息。

检索通话历史记录

Sendbird服务器自动存储呼叫详情,可以在将来检索以显示用户的呼叫历史记录。用户的呼叫历史记录可通过SendBirdCall.DirectCallLogListQuery实例获取。

let params = DirectCallLogListQuery.Params()
let query = SendBirdCall.createDirectCallLogListQuery(with: params)

query.next(completionHandler: { [weak query] callLogs, error in
    if query?.hasNext == true, query?.isLoading == false {
        // query.next() can be called once more.
        // If a user wants to fetch more call logs.
    }
})
方法 说明
next() 用于查询Sendbird Calls服务器中的呼叫历史记录。
hasNext 如果为true,则还有更多呼叫历史记录尚未检索。
isLoading 如果为true,正在从服务器检索呼叫历史记录。
limit 指定每次返回的呼叫历史记录条目数。
myRole 返回指定角色的呼叫历史记录。例如,params.myRole = .callee将仅返回被叫方的呼叫历史记录。)
endResults 根据呼叫结束结果(例如.completed.noAnswer等)过滤结果。如果指定多个值,它们被视为OR条件处理。例如,对于add(endResult:.noAnswer),仅返回结果为.noAnswer的历史记录。

超时选项

下表列出了SendBirdCall类的一组方法。

SendBirdCall.setRingingTimeout(30)

SendBirdCall.setCallConnectionTimeout(30)
方法 说明
setRingingTimeout(_:) 设置未接听电话的时间限制(以秒为单位)。默认值为60秒。
setCallConnectionTimeout(_:) 设置连接电话的时间限制(以秒为单位)。默认值为60秒。

音效

- 音效类型

类型 说明
dialing 指的是在呼叫被叫方时,在主叫方播放的声音。
ringing 指的是在接收到电话时,在被叫方播放的声音。
reconnecting 指当连接丢失时播放的声音,但会尝试立即重新连接。用户还可以自定义铃声。
重新连接 指当连接重新建立时播放的声音。

添加声音

- addDirectCallSound(_:forType:)

方法 说明
addDirectCallSound(_:forType:) 将特定的声音(如铃声和提示音)添加到带有URL的直接通话中。如果使用包播放声音,请使用下面的addDirectCallSound(_:bundle:forType:)方法。
参数 类型 说明
url 字符串 指定音频文件的URL。
forType SoundType 指定根据事件使用的声音类型。

- addDirectCallSound(_:bundle:forType:)

方法 说明
addDirectCallSound(_:bundle:forType:) 将特定的声音(如铃声和提示音)添加到具有文件名和包的直接通话中。
参数 类型 说明
名称 字符串 指定音频文件的名称。请确保还指定了文件扩展名。例如:dialing.mp3
bundle 指定包对象。默认为主包。
forType SoundType 指定根据事件使用的声音类型。

移除声音

名称 说明
removeDirectCallSound(forType: ) 从直接通话中移除特定声音。
参数 类型 说明
forType SoundType 指定根据事件使用的声音类型。

附录

回调和委托线程处理

回调可以被指定在特定的后台线程上运行以保持主线程不被干扰。要指定线程,请运行 SendBirdCall.executeOn(queue: CUSTOM_QUEUE)。否则,SendBirdCall 将在 DispatchQueue.main 上异步运行。

然而,由于 VoIP PushKit 需要立即和同步处理回调,因此 SendBirdCallDelegate.didStartRinging(_)SendBirdCall.pushRegistry(_:didReceiveIncomingPushWith:for:completion:) 的完成处理程序将在调用它们的线程上同步运行。换句话说,只有在 SendBirdCall.executeOn(queue:) 中指定的线程上运行的这两个过程。

class AppDelegate: UIResponder, UIApplicationDelegate {
    
    let callbackQueue = DispatchQueue(label: QUEUE_LABEL)

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Set specific callback queue.
        SendBirdCall.executeOn(queue: self.callbackQueue)

        ...
    }
}

extension AppDelegate: SendBirdCallDelegate {

    func didStartRinging(_ call: DirectCall) {
    // This delegate may not be executed on the thread set by SendBirdCall.executeOn(queue:).
        ...
    }

}

extension AppDelegate: DirectCallDelegate {

    // Runs on the custom thread.
    // In this sample code, runs on the callbackQueue above.
    func didEstablish(_ call: DirectCall) { ... }
    func didConnect(_ call: DirectCall) { ... }
    func didEnd(_ call: DirectCall) { ... }
    
    ...
}

通话中继协议

Sendbird Call 基于WebRTC,使用P2P连接为用户提供实时通话,但有时由于网络策略不允许WebRTC通过防火墙和NAT(网络地址转换器)通信,用户可能会遇到连通性问题。为此,Sendbird Call 使用两种不同的协议,即 Session Traversal Utilities for NAT (STUN)Traversal Using Relays around NAT (TURN)。STUN 和 TURN 是支持在用户之间建立连接的协议。

注意:请参阅我们的GitHub页面,了解相关要求和如何在防火墙后使用 Calls SDK。


STUN和TURN的工作原理

会话穿越NAT(STUN)是一种协议,帮助主机发现NAT的存在及其IP地址,从而实现两端之间的连接。使用NAT周围中继(TURN)的穿越是一种为双方数据传输提供中继扩展的协议。

Sendbird Calls首先尝试直接使用Calls SDK建立点对点(P2P)连接。如果用户位于NAT/防火墙之后,Calls将利用STUN发现主机的公网IP地址作为建立连接的位置。在大多数情况下,STUN服务器仅在连接设置期间使用,一旦会话建立,媒体将直接在两个用户之间传输。如果NAT/防火墙仍然不允许两个用户直接连接,将使用TURN服务器通过中继用户之间的媒体数据来建立连接。大多数WebRTC流量都与STUN连接。

呼叫结果

EndResult 说明
noAnswer 被叫方未能接受或拒绝呼叫在一定的时间内。
canceled 呼叫方在另一方接受或拒绝之前取消呼叫。
declined 被叫方拒绝了呼叫。
completed 双方任一方结束通话后通话结束。
timedOut Sendbird服务器未能在本规定时间内为呼叫方和被叫方之间建立媒体会话。
connectionLost 由于WebRTC连接问题,呼叫方或被叫方的数据流已停止。
dialFailed dial()方法调用失败了。
acceptFailed accept()方法调用失败了。
otherDeviceAccepted 来电在另一设备上被接受。此设备收到了来电通知,但通话在另一设备接受时结束。

编码配置

类别 说明
帧率 24 fps
最大分辨率 720p 1280x720 px; 标准高清
音频编解码器 OPUS
视频编解码器 H.264, VP8 H.264 是 iOS 设备间默认的编解码器。

iOS SDK 大小

文件 原始文件 编译大小
调用 SDK (1.7.0) 77.1 MB 2.32 MB
WebRTC SDK (1.3.0) 1.18 GB 6.32 MB

(Xcode 12.3, 任意 iOS 设备 (arm64))

- 最近更新:2021年6月18日