IosAv_zh - aopacloud/aopa-rtc GitHub Wiki
实现音视频互动
本文介绍如何集成奥帕实时互动 SDK,通过少量代码从 0 开始实现一个简单的实时互动 App,适用于互动直播和视频通话场景。
首先,你需要了解以下有关音视频实时互动的基础概念:
- 奥帕实时互动 SDK:由奥帕开发的、帮助开发者在 App 中实现实时音视频互动的 SDK。
- 频道:用于传输数据的通道,在同一个频道内的用户可以进行实时互动。
- 主播:可以在频道内发布音视频,同时也可以订阅其他主播发布的音视频。
- 观众:可以在频道内订阅音视频,不具备发布音视频权限。
下图展示在 App 中实现音视频互动的基本工作流程:
- 所有用户调用
joinChannel
方法加入频道,并根据需要设置用户角色:- 互动直播:如果用户需要在频道中发流,则设为主播;如果用户只需要收流,则设为观众。
- 视频通话:将所有的用户角色都为主播。
- 加入频道后,不同角色的用户具备不同的行为:
- 所有用户默认都可以接收频道中的音视频流。
- 主播可以在频道内发布音视频流。
- 观众如果需要发流,可在频道内调用
setClientRole
方法修改用户角色,使其具备发流权限。
前提条件在实现功能以前,请按照以下要求准备开发环境:
- Xcode 12.0 或以上版本。
- Apple 开发者账号。
- 如需使用 Cocoapods 集成 SDK,则确保已安装 Cocoapods,否则请参考 Getting Started with CocoaPods 进行安装。
- 两台 iOS 9.0 或以上版本的设备。
- 可以访问互联网的计算机。如果你的网络环境部署了防火墙,参考[应对防火墙限制]以正常使用奥帕服务。
- 一个有效的奥帕账号以及奥帕项目。请参考[开通服务]从奥帕控制台获得以下信息:
- App ID:奥帕随机生成的字符串,用于识别你的项目。
- 临时 Token:Token 也称为动态密钥,在客户端加入频道时对用户鉴权。临时 Token 的有效期为 24 小时。
创建项目按照以下步骤,在 Xcode 中创建一个项目:
-
参考 Create a project 创建一个新的项目。Application 选择 App,Interface 选择 Storyboard,Language 选择 Obk。
信息
如果你没有添加过开发团队信息,会看到 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。 Privacy - Camera Usage Description String 使用摄像头的目的,例如:for a call or live interactive streaming。
集成 SDK根据实际情况,在以下集成方式中任选一种,在你的项目中集成 SDK。
- 手动集成
-
前往[下载]页面,获取最新版的 SDK,然后解压。
-
将 SDK 包内
libs
路径下的文件,拷贝到你的项目路径下。 -
打开 Xcode,添加对应动态库,确保添加的动态库 Embed 属性设置为 Embed & Sign。
信息
奥帕 SDK 默认使用 libc++ (LLVM)。SDK 提供的库是 FAT Image,包含 32/64 位模拟器、32/64 位真机版本。
-
在 Xcode 中,进入 File > Swift Packages > Add Package Dependencies...,粘贴如下 URL:
HTTP
https://github.com/aopacloud/aopa-rtc
-
在 Choose Package Options 中指定你想集成的 SDK 版本。你也可以参考 Apple 官方文档进行设置。
创建用户界面根据使用场景,为你的项目创建一个用户界面,包括本地视频窗口和远端视频窗口。用以下代码替换 ViewController.swift
文件中的内容:
Swift
import UIKit
import AopaRtcKit
class ViewController: UIViewController {
// 本地视频视图
var localView: UIView!
// 远端视频视图
var remoteView: UIView!
// RTC 引擎
var AopaKit: AopaRtcEngineKit!
override func viewDidLoad() {
super.viewDidLoad()
localView = UIView(frame: UIScreen.main.bounds)
remoteView = UIView(
frame: CGRect(x: self.view.bounds.width - 135, y: 50, width: 135, height: 240))
self.view.addSubview(localView)
self.view.addSubview(remoteView)
}
}
实现流程下图展示了使用奥帕 RTC SDK 实现音视频互动的基本流程。
下面列出了一段实现实时互动基本流程的完整代码以供参考。复制以下代码到 ViewController.swift
文件中替换原有内容即可。
信息
在 appId
、token
和 channelName
字段中传入你在控制台获取到的 App ID、临时 Token,以及生成临时 Token 时填入的频道名。
实现音视频互动示例代码
Swift
// ViewController.swift
import UIKit
import AopaRtcKit
class ViewController: UIViewController {
// 本地视频视图
var localView: UIView!
// 远端视频视图
var remoteView: UIView!
// RTC 引擎
var AopaKit: AopaRtcEngineKit!
override func viewDidLoad() {
super.viewDidLoad()
localView = UIView(frame: UIScreen.main.bounds)
remoteView = UIView(frame: CGRect(x: self.view.bounds.width - 135, y: 50, width: 135, height: 240))
self.view.addSubview(localView)
self.view.addSubview(remoteView)
// 初始化 RTC 实例
AopaKit = AopaRtcEngineKit.sharedEngine(withAppId:<#Your App ID#>, delegate: self)
// 开启视频模块(音频模块默认开启)
AopaKit.enableVideo()
// 开启本地摄像头预览
startPreview()
// 加入频道
joinChannel()
}
deinit {
AopaKit.stopPreview()
AopaKit.leaveChannel(nil)
AopaRtcEngineKit.destroy()
}
func startPreview(){
let videoCanvas = AopaRtcVideoCanvas()
videoCanvas.view = localView
videoCanvas.renderMode = .hidden
AopaKit.setupLocalVideo(videoCanvas)
AopaKit.startPreview()
}
func joinChannel(){
let options = AopaRtcChannelMediaOptions()
// 设置频道场景为直播
options.channelProfile = .liveBroadcasting
// 设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
options.clientRoleType = .broadcaster
// 发布麦克风采集的音频
options.publishMicrophoneTrack = true
// 发布摄像头采集的视频
options.publishCameraTrack = true
// 自动订阅所有音频流
options.autoSubscribeAudio = true
// 自动订阅所有视频流
options.autoSubscribeVideo = true
// 使用临时 Token 加入频道,在这里传入你的项目的 Token 和频道名
// uid 为 0 表示由引擎内部随机生成; 成功后会触发 didJoinChannel 回调
AopaKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options)
}
}
extension ViewController: AopaRtcEngineDelegate{
// 成功加入频道回调
func rtcEngine(_ engine: AopaRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
print("didJoinChannel: \(channel), uid: \(uid)")
}
// 远端用户或主播加入当前频道回调
func rtcEngine(_ engine: AopaRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){
// 当远端用户加入频道后,显示指定 uid 的远端视频流
let videoCanvas = AopaRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.view = remoteView
videoCanvas.renderMode = .hidden
AopaKit.setupRemoteVideo(videoCanvas)
}
// 远端用户或主播离开当前频道回调
func rtcEngine(_ engine: AopaRtcEngineKit, didOfflineOfUid uid: UInt, reason: AopaUserOfflineReason) {
let videoCanvas = AopaRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.view = nil
AopaKit.setupRemoteVideo(videoCanvas)
}
}
导入奥帕组件在 ViewController.swift
文件中引入 AopaRtcKit
。
Swift
import AopaRtcKit
初始化引擎调用 sharedEngineWithConfig
方法,创建并初始化 AopaRtcEngineKit
。
注意
在初始化 SDK 前,需确保终端用户已经充分了解并同意相关的隐私政策。
Swift
// 在这里输入你在奥帕控制台中获取的 App ID
AopaKit = AopaRtcEngineKit.sharedEngine(withAppId:<#Your App ID#>, delegate: self)
启用视频模块按照以下步骤启用视频模块。
- 调用
enableVideo
方法,启用视频模块。 - 调用
setupLocalVideo
方法初始化本地视图,同时设置本地的视频显示属性。 - 调用
startPreview
方法,开启本地视频预览。
Swift
// 启用视频模块
AopaKit.enableVideo()
let videoCanvas = AopaRtcVideoCanvas()
videoCanvas.view = localView
videoCanvas.renderMode = .hidden
// 设置本地视图
AopaKit.setupLocalVideo(videoCanvas)
// 开始本地视频预览
AopaKit.startPreview()
加入频道并发布音视频流调用 joinChannelByToken
方法、填入你在控制台获取的临时 Token,以及获取 Token 时填入的频道名加入频道,并设置用户角色。
Swift
let options = AopaRtcChannelMediaOptions() // 设置频道场景为直播
options.channelProfile = .liveBroadcasting // 设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
options.clientRoleType = .broadcaster // 发布麦克风采集的音频
options.publishMicrophoneTrack = true // 发布摄像头采集的视频
options.publishCameraTrack = true // 自动订阅所有音频流
options.autoSubscribeAudio = true // 自动订阅所有视频流
options.autoSubscribeVideo = true // 使用临时 Token 加入频道,在这里传入你的项目的 Token 和频道名 // uid 为 0 表示由引擎内部随机生成; 成功后会触发 didJoinChannel 回调
AopaKit.joinChannel(byToken: <#Your Token#>, channelId: <#Your Channel Name#>, uid: 0, mediaOptions: options)
设置远端用户视图调用 setupRemoteVideo
方法初始化远端用户视图,同时设置远端用户的视图在本地显示属性。你可以通过 didJoinedOfUid
回调获取远端用户的 uid
。
Swift
func rtcEngine(_ engine: AopaRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int){
// 当远端用户加入频道后,显示指定 uid 的远端视频流
let videoCanvas = AopaRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.view = remoteView
videoCanvas.renderMode = .hidden
AopaKit.setupRemoteVideo(videoCanvas)}
实现常用回调根据使用场景,定义必要的回调。以下示例代码展示了如何实现 didJoinChannel
和 didOfflineOfUid
回调。
Swift
// 成功加入频道回调
func rtcEngine(_ engine: AopaRtcEngineKit, didJoinChannel channel: String, withUid uid: UInt, elapsed: Int) {
print("didJoinChannel: \(channel), uid: \(uid)")}
// 远端用户或主播离开当前频道回调
func rtcEngine(_ engine: AopaRtcEngineKit, didOfflineOfUid uid: UInt, reason: AopaUserOfflineReason) {
let videoCanvas = AopaRtcVideoCanvas()
videoCanvas.uid = uid
videoCanvas.view = nil
AopaKit.setupRemoteVideo(videoCanvas)}
开始音视频互动当视图加载完成后,在 viewDidLoad
中调用一系列方法加入频道,开始音视频互动。
Swift
override func viewDidLoad() {
super.viewDidLoad() // 当加载视图后,你可以进行其他其他设置
// 当调用奥帕 API 时,以下函数会被调用
AopaKit.enableVideo()
startPreview()
joinChannel()}
结束音视频互动-
调用
leaveChannel
方法离开频道,与会话相关的资源也会被释放。Swift
AopaKit.stopPreview() AopaKit.leaveChannel(nil)
-
调用
destroy
销毁引擎,并释放奥帕 SDK 中使用的所有资源。Swift
AopaRtcEngineKit.destroy()
警告
调用该方法后,你将无法再使用 SDK 的所有方法和回调。如需再次使用实时音视频互动功能,你必须重新创建一个新的引擎。详见初始化引擎。
测试 App参考以下步骤来测试你的 App:
- 将 iOS 设备连接至计算机。
- 点击 Build 来运行你的项目,需等待几秒至 App 安装完成。
- 允许 App 访问设备的麦克风和摄像头权限。
- (可选)如果设备上弹出不受信任的开发者提示,则首先点击取消关闭该提示,然后在 iOS 设备上打开设置 > 通用 > VPN 与设备管理,在开发者 APP 中选择信任该开发者。
- 使用第二台 iOS 设备,重复以上步骤,在该设备上安装 App,并打开 App 加入频道,观察测试结果:
- 如果两台设备均作为主播加入频道,则可以看到对方并且听到对方的声音。
- 如果两台设备分别作为主播和观众加入,则主播可以在本地视频窗口看到自己;观众可以在远端视频窗口看到主播、并听到主播的声音。
后续步骤- 本文的示例使用了临时 Token 加入频道。在测试或生产环境中,为确保通信安全,声网推荐使用 Token 服务器来生成 Token,详见[使用 Token 鉴权]
- 如果你想要实现极速直播场景,可以在互动直播的基础上,通过修改观众端的延时级别为低延时 (
AopaAudienceLatencyLevelLowLatency
)实现。详见[实现极速直播]
相关信息
示例项目奥帕提供了开源的实时互动示例项目供你参考,你可以前往下载或查看其中的源代码。
- Github:AopaRtcIos