实现纯语音互动
本文介绍如何集成声网实时互动 SDK,通过少量代码从 0 开始实现一个简单的实时互动 App,适用于互动直播和视频通话场景。
首先,你需要了解以下有关音视频实时互动的基础概念:
- 声网实时互动 SDK:由声网开发的、帮助开发者在 App 中实现实时音视频互动的 SDK。
- 频道:用于传输数据的通道,在同一个频道内的用户可以进行实时互动。
- 主播:可以在频道内发布音视频,同时也可以订阅其他主播发布的音视频。
- 观众:可以在频道内订阅音视频,不具备发布音视频权限。
更多概念详见关键概念。
下图展示在 App 中实现音视频互动的基本工作流程:
- 所有用户调用
joinChannel
方法加入频道,并根据需要设置用户角色:- 互动直播:如果用户需要在频道中发流,则设为主播;如果用户只需要收流,则设为观众。
- 视频通话:将所有的用户角色都为主播。
- 加入频道后,不同角色的用户具备不同的行为:
- 所有用户默认都可以接收频道中的音视频流。
- 主播可以在频道内发布音视频流。
- 观众如果需要发流,可在频道内调用
setClientRole
方法修改用户角色,使其具备发流权限。
前提条件
在实现功能以前,请按照以下要求准备开发环境:
- Xcode 12.0 或以上版本。
- Apple 开发者账号。
- 如需使用 Cocoapods 集成 SDK,则确保已安装 Cocoapods,否则请参考 Getting Started with CocoaPods 进行安装。
- 两台 macOS 10.10 或以上版本的设备。
- 可以访问互联网的计算机。如果你的网络环境部署了防火墙,参考应对防火墙限制以正常使用声网服务。
- 一个有效的声网账号以及声网项目。请参考开通服务从声网控制台获得 和临时 。
临时 Token 的有效期是 24 小时。Token 过期会导致加入频道失败。
创建项目
按照以下步骤,在 Xcode 中创建一个项目:
-
参考 Create a project 创建一个新的项目。Application 选择 App,Interface 选择 Storyboard,Language 选择 Swift。
信息如果你没有添加过开发团队信息,会看到 Add account… 按钮。点击该按钮并按照屏幕提示登入 Apple ID,点击 Next,完成后即可选择你的 Apple 账户作为开发团队。
-
为你的项目设置自动签名。
-
设置部署你的 App 的目标设备。
-
添加项目的设备权限。
在项目导航栏中打开
info.plist
文件,编辑属性列表,添加以下属性:注意- 下表中列出的权限均为可选权限。但如果不添加所列权限,你将无法使用麦克风进行实时音频互动。
- 如果你的项目中需要添加第三方插件或库,且该插件或库的签名与项目的签名不一致,你还需勾选 Hardened Runtime > Runtime Exceptions 中的 Disable Library Validation。
- 更多注意事项,可以参考 Preparing Your App for Distribution。
Key Type Value Privacy - Microphone Usage Description String 使用麦克风的目的,例如:for a call or live interactive streaming。 进入 TARGETS > Project Name > Signing & Capabilities,在 App Sandbox 和 Hardened Runtime 中添加如下权限:
Capability Category Permission App Sandbox Network - Incoming Connections (Server)
- Outgoing Connections (Client)
App Sandbox Hardware - Camera
- Audio Input
Hardened Runtime Resource Access - Camera
- Audio Input
集成 SDK
根据实际情况,在以下集成方式中任选一种,在你的项目中集成 SDK。
- 通过 Cocoapods 集成
- 手动集成
- 通过 Swift Package Manager 集成
-
在终端里进入项目根目录,并运行
pod init
命令。项目文件夹下会生成一个Podfile
文本文件。 -
打开
Podfile
文件,修改文件为如下内容。注意将Your App
替换为你的 Target 名称。Rubyplatform :macos, '10.11'
target 'Your App' do
# x.y.z 请填写具体的 SDK 版本号,如 4.0.1。
# 可通过发版说明获取最新版本号。
pod 'AgoraRtcEngine_macOS', 'x.y.z'
end -
在终端内运行
pod install
命令安装声网 SDK。成功安装后,Terminal 中会显示Pod installation complete!
。 -
成功安装后,项目文件夹下会生成一个后缀为
.xcworkspace
的文件,通过 Xcode 打开该文件进行后续操作。
-
前往下载页面,获取最新版的 SDK,然后解压。
-
将 SDK 包内
libs
路径下的文件,拷贝到你的项目路径下。 -
打开 Xcode,添加对应动态库,确保添加的动态库 Embed 属性设置为 Embed & Sign。
信息声网 SDK 默认使用 libc++ (LLVM),如需使用 libstdc++ (GNU),请联系 sales@shengwang.cn。SDK 提供的库是 FAT Image,包含 32/64 位模拟器、32/64 位真机版本。
-
在 Xcode 中,进入 File > Swift Packages > Add Package Dependencies...,粘贴如下 URL:
HTTPhttps://github.com/AgoraIO/AgoraRtcEngine_macOS.git
-
在 Choose Package Options 中指定你想集成的 SDK 版本。你也可以参考 Apple 官方文档进行设置。
自 4.5.0 起,RTC SDK 和 RTM SDK (2.2.0 及以上版本) 都包含 aosl.xcframework
库。如果你通过 CDN 手动集成 RTC SDK 且同时集成了 RTM SDK,为避免冲突,请手动删除版本较低的 aosl.xcframework
库。4.5.0 RTC SDK aosl.xcframework
库版本为 1.2.13。你可以通过查看 aosl.xcframework
文件的属性来得知库的版本信息。
实现步骤
下图展示了使用声网 RTC SDK 实现纯语音互动的基本流程。
下面列出了一段实现纯语音互动基本流程的完整代码以供参考。复制以下代码到 ViewController.swift
文件中替换原有内容即可。
在 appId
、token
和 channelName
字段中传入你在控制台获取到的 App ID、临时 Token,以及生成临时 Token 时填入的频道名。
// ViewController.swift
import AgoraRtcKit
import Cocoa
class ViewController: NSViewController {
// RTC 引擎
var agoraKit: AgoraRtcEngineKit!
func initView(){
// 初始化 RTC 实例
agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: <#Your App ID#>, delegate: self)
}
}
deinit {
agoraKit.leaveChannel(nil)
AgoraRtcEngineKit.destroy()
}
func joinChannel(){
let options = AgoraRtcChannelMediaOptions()
options.channelProfile = .liveBroadcasting
// 设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
options.clientRoleType = .broadcaster
// 发布麦克风采集的音频
options.publishMicrophoneTrack = true
// 自动订阅所有音频流
options.autoSubscribeAudio = true
// 使用临时 Token 加入频道,在这里传入你的项目的 Token 和频道名
// uid 为 0 表示由引擎内部随机生成; 成功后会触发 didJoinChannel 回调
agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options)
}
override func viewDidLoad() {
super.viewDidLoad()
initView()
joinChannel()
}
}
extension ViewController: AgoraRtcEngineDelegate{
// 成功加入频道回调
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){
}
// 远端用户加入当前频道回调
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){
// 打印调试信息
print("User \(uid) joined after \(elapsed) milliseconds")
}
// 远端用户离开当前频道回调
func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
// 打印调试信息
print("User \(uid) went offline due to \(reason)")
}
}
导入声网组件
在 ViewController.swift
文件中引入 AgoraRtcKit
。
import AgoraRtcKit
初始化引擎
调用 sharedEngineWithConfig
方法,创建并初始化 AgoraRtcEngineKit
。
在初始化 SDK 前,需确保终端用户已经充分了解并同意相关的隐私政策。
agoraKit = AgoraRtcEngineKit.sharedEngine(with: config, delegate: self)
加入频道并发布音频流
调用 joinChannelByToken
[2/4] 方法、填入你在控制台获取的临时 Token,以及获取 Token 时填入的频道名加入频道,并设置用户角色。
let options = AgoraRtcChannelMediaOptions()
// 设置频道场景为直播
options.channelProfile = .liveBroadcasting
// 设置用户角色为主播
// 如果要将用户角色设置为观众,则修改下一行代码为 options.clientRoleType = .audience
options.clientRoleType = .broadcaster
// 发布麦克风采集的音频
options.publishMicrophoneTrack = true
// 自动订阅所有音频流
options.autoSubscribeAudio = true
// 使用临时 Token 加入频道,在这里传入你的项目的 Token 和频道名
// uid 为 0 表示由引擎内部随机生成; 成功后会触发 didJoinChannel 回调
agoraKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options)
实现常用回调
根据使用场景,定义你所需的回调。以下示例代码展示了如何实现 didJoinChannel
和 didOfflineOfUid
回调。
// 成功加入频道回调
func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
print("didJoinChannel: \(channel), uid: \(uid)")
}
// 远端用户离开当前频道回调
func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
// 打印调试信息
print("User \(uid) went offline due to \(reason)")
}
开始纯语音互动
当视图加载完成后,在 viewDidLoad
中调用一系列方法加入频道,开始音视频互动。
override func viewDidLoad() {
super.viewDidLoad()
// 当加载视图后,你可以进行其他其他设置
// 当调用声网 API 时,以下函数会被调用
joinChannel()
}
结束纯语音互动
-
调用
leaveChannel
方法离开频道,与会话相关的资源也会被释放。SwiftagoraKit.leaveChannel(nil)
-
调用
destroy
销毁引擎,并释放声网 SDK 中使用的所有资源。SwiftAgoraRtcEngineKit.destroy()
警告- 调用该方法后,你将无法再使用 SDK 的所有方法和回调。如需再次使用实时音视频互动功能,你必须重新创建一个新的引擎。详见初始化引擎。
- 该方法为同步调用。需要等待引擎资源释放后才能执行其他操作,因此建议在子线程中调用该方法,避免主线程阻塞。
调试 App
参考以下步骤来测试你的 App:
- 将 macOS 设备连接至计算机。
- 点击 Build 来运行你的项目,需等待几秒至 App 安装完成。
- 允许 App 访问设备的麦克风和摄像头权限。
- 使用第二台 macOS 设备,重复以上步骤,在该设备上安装 App,并打开 App 加入频道,观察测试结果:双方可以听到对方的声音。
后续步骤
本文的示例使用了临时 Token 加入频道。在测试或生产环境中,为确保通信安全,声网推荐使用 Token 服务器来生成 Token,详见使用 Token 鉴权。
参考信息
示例项目
声网提供了开源的纯语音互动示例项目供你参考,你可以前往下载或查看其中的源代码。
常见问题
- 直播场景下,如何监听远端观众角色用户加入/离开频道的事件?
- 如何处理 CocoaPods 常见问题?
- 如何处理频道相关常见问题?
- 编译 Xcode 项目时遇到 “无法打开 framework” 的弹窗警告怎么办?
- 如何判断一个通话是语音通话还是视频通话?
- 如何设置日志文件?