iOS API 说明
Darwin SDK TiRTC 提供 iOS Swift / Objective-C 客户端 API,适用于在 iOS 原生应用中接入 TiRTC。
如果你还没有完成 SDK 引入、工程配置或连接流程准备,先看 iOS SDK 接入。
生命周期与调用顺序
典型客户端流程是:连接一个设备端,播放设备端音视频,并按需收发命令或发起语音对讲。主干从 TiRtc.initialize(...) 开始,以 disconnect() 和 dispose() 收尾。
初始化:传入
AppId,启动 SDK 运行时。swiftlet options = TiRtcInitOptions(appId: appId) _ = TiRtc.initialize(options)创建连接:创建
TiRtcConn,并在连接前设置连接回调 delegate;业务侧需要自己持有 delegate 对象。swiftlet conn = TiRtcConn() conn.delegate = connDelegate准备播放:在发起连接前创建音频输出和视频输出,并指定要播放的
streamId。swiftlet audioOutput = TiRtcAudioOutput() _ = audioOutput.attach(connection: conn, streamId: audioStreamId) let videoOutput = TiRtcVideoOutput() _ = videoOutput.attach(connection: conn, streamId: videoStreamId)渲染视频:在主线程把视频输出挂到 iOS 视图中,让视频输出有对应的显示位置。
swift_ = videoOutput.attachView(videoView)发起连接:传入目标设备的
device_id和业务服务端签发的token。swift_ = conn.connect(remoteId: remoteId, token: token)请求媒体:连接进入
connected后,按需请求设备端发送音频流和视频流。swift_ = conn.subscribeAudio(streamId: audioStreamId) // 连接成功后订阅音频 _ = conn.subscribeVideo(streamId: videoStreamId) // 连接成功后订阅视频命令交互:连接进入
connected后,按需通过命令通道和设备端交换业务数据。swift_ = conn.sendCommand(commandId: commandId, data: data) // 需要命令交互时调用 // 收到设备端命令时,在 conn(_:didReceiveCommand:data:) 中处理。语音对讲(按需):应用获得系统麦克风权限后,创建音频输入,绑定到同一条连接,并启动采集发送。
swiftlet talkbackInput = TiRtcAudioInput() _ = talkbackInput.setOptions(talkbackOptions) _ = talkbackInput.attach(connection: conn, streamId: talkbackStreamId) _ = talkbackInput.start()收尾释放:业务结束时先释放按需创建的输入对象,再按订阅、输出、连接的顺序收尾。
swift_ = talkbackInput.stop() // 创建了 talkbackInput 时调用 _ = talkbackInput.detach(connection: conn) talkbackInput.dispose() _ = conn.unsubscribeAudio(streamId: audioStreamId) // 停止播放时取消音频订阅 _ = conn.unsubscribeVideo(streamId: videoStreamId) // 停止播放时取消视频订阅 _ = audioOutput.detach() _ = videoOutput.detach() _ = videoOutput.detachView() audioOutput.dispose() videoOutput.dispose() _ = conn.disconnect() conn.dispose()
TiRtcInitOptions
TiRtcInitOptions 是 TiRtc.initialize(_:) 的参数对象。
初始化时必须传 appId,取值为你的 AppId。
// 创建初始化参数;appId 必填。
let options = TiRtcInitOptions(appId: "your-app-id")
// 切换自部署云端实例或测试、联调环境时设置,例如 "https://ep-tirtc.my-domain.com";其他情况保持空字符串。
options.endpoint = ""
// true 时同时把 SDK 日志打印到控制台。
options.consoleLogEnabled = falseTiRtc
TiRtc 提供初始化和错误码名称转换入口。
// 初始化 SDK。返回 0 表示成功,非 0 为错误码。
static func initialize(_ config: TiRtcInitOptions) -> Int32
// 把错误码转成错误名称。
static func errorToString(_ code: Int32) -> String示例:
let options = TiRtcInitOptions(appId: "your-app-id")
let code = TiRtc.initialize(options)
if code != 0 {
print("initialize failed: \(TiRtc.errorToString(code)) (\(code))")
}TiRtcConn
TiRtcConn 表示客户端到远端设备的一条连接。创建对象不会立即发起连接;通常先设置 delegate,再调用 connect(...)。连接建立后,可以通过它发送命令、发送流消息、发起媒体订阅和请求视频关键帧。
音频播放和视频显示由 TiRtcAudioOutput / TiRtcVideoOutput 负责,TiRtcConn 本身不播放也不显示媒体。
状态
TiRtcConnState.idle:连接对象已创建,但还没有开始连接。TiRtcConnState.connecting:连接请求已提交,正在等待结果。TiRtcConnState.connected:连接已经建立,可收发命令、流消息,发起媒体订阅和关键帧请求。TiRtcConnState.disconnected:连接失败、对端断开或调用disconnect()后进入该状态。
属性和 delegate
// 当前连接状态。
var state: TiRtcConnState { get }
// 连接回调入口,SDK 弱引用持有;调用方需要自己持有 delegate 对象。
weak var delegate: TiRtcConnDelegate?相关类型:
@objc public protocol TiRtcConnDelegate: NSObjectProtocol {
// 连接状态变化时触发。errorCode 为 0 表示本次状态变化没有错误;非 0 为错误码。
@objc optional func conn(
_ conn: TiRtcConn,
didChangeState state: TiRtcConnState,
errorCode: Int32
)
// 收到设备端命令时触发。
@objc optional func conn(
_ conn: TiRtcConn,
didReceiveCommand commandId: UInt32,
data: Data
)
// 收到设备端的流消息时触发。
@objc optional func conn(
_ conn: TiRtcConn,
didReceiveStreamMessage streamId: UInt8,
timestampMs: UInt32,
data: Data
)
}delegate 回调会切回主线程分发。
方法
// 创建连接对象;构造函数本身不会发起连接。通常先设置 delegate,再调用 connect。
init(delegate: TiRtcConnDelegate? = nil)
// 发起连接;初始化完成并拿到连接凭证后调用。
// remoteId 是连接目标;连接设备端时传目标设备的 device_id,例如 "PRODFENGXXXX"。
// token 是业务服务端为本次连接签发的 token,二者不能为空。
// 返回 0 只表示请求已提交,最终连接结果看 delegate;非 0 为错误码。
func connect(remoteId: String, token: String) -> Int32
// 断开当前连接;业务结束、切换设备或重新连接前调用。对象仍可重新 connect。
func disconnect() -> Int32
// 释放连接对象;确认不再使用这条连接后调用。调用后不要再使用这个实例。
func dispose()
// 在命令通道上发送自定义命令;连接进入 connected 后调用。
func sendCommand(commandId: UInt32, data: Data) -> Int32
// 发送流消息;连接进入 connected 后调用。
// streamId 按 stream_id 约定使用 0..15,两端需要提前约定消息语义。
func sendStreamMessage(streamId: UInt8, timestampMs: UInt32, data: Data) -> Int32
// 请求远端开始发送指定 streamId 的音频流;连接进入 connected 后调用。
// streamId 按 stream_id 约定使用 0..15。
// 这个方法只请求远端发送音频,不会自动播放。
// 播放远端音频前,先调用 TiRtcAudioOutput.attach(...) 指定要播放的 connection 和 streamId;然后调用 connect(...) 建立连接。
// 连接成功后,再调用 subscribeAudio(...) 请求远端发送这路音频。
func subscribeAudio(streamId: UInt8) -> Int32
// 请求远端停止发送指定 streamId 的音频流;streamId 按 stream_id 约定使用 0..15。
// 不会停止已经创建的 TiRtcAudioOutput。停止播放时再调用 TiRtcAudioOutput.detach()。
func unsubscribeAudio(streamId: UInt8) -> Int32
// 请求远端开始发送指定 streamId 的视频流;连接进入 connected 后调用。
// streamId 按 stream_id 约定使用 0..15。
// 这个方法只请求远端发送视频,不会自动显示。
// 显示远端视频前,先调用 TiRtcVideoOutput.attach(...) 指定要显示的 connection 和 streamId;然后调用 connect(...) 建立连接。
// 连接成功后,再调用 subscribeVideo(...) 请求远端发送这路视频。
func subscribeVideo(streamId: UInt8) -> Int32
// 请求远端停止发送指定 streamId 的视频流;streamId 按 stream_id 约定使用 0..15。
// 不会停止已经创建的 TiRtcVideoOutput。停止显示时再调用 TiRtcVideoOutput.detach()。
func unsubscribeVideo(streamId: UInt8) -> Int32
// 向远端请求指定视频流的关键帧;连接已建立且远端正在发送该视频流时调用。
// streamId 按 stream_id 约定使用 0..15。
func requestKeyFrame(streamId: UInt8) -> Int32示例:
let conn = TiRtcConn()
let code = conn.connect(remoteId: remoteId, token: token)
if code != 0 {
print("connect failed: \(TiRtc.errorToString(code)) (\(code))")
}
// 结束时:
_ = conn.disconnect()
conn.dispose()TiRtcAudioOutputOptions
TiRtcAudioOutputOptions 配置 TiRtcAudioOutput 的音频输出参数。只需要填写要覆盖默认值的字段。
let options = TiRtcAudioOutputOptions()
options.agcLevel = 0 // 自动增益等级:0 关闭,1 低,2 中,3 高
options.ansLevel = 0 // 自动噪声抑制等级:0 关闭,1 低,2 中,3 高
options.bufferStrategy = .automatic // 输出缓冲策略
// 最大输出缓冲水位,单位为毫秒;仅 .automatic 有效。
// nil 表示由 SDK 自动决定。
options.maxBufferWatermarkMs = nil相关枚举:
// 输出缓冲策略。
enum TiRtcOutputBufferStrategy {
case automatic // SDK 根据当前平台和链路状态决定缓冲策略
case noBuffer // 不使用输出缓冲;不要同时设置 maxBufferWatermarkMs
}TiRtcAudioOutput
TiRtcAudioOutput 用来播放某条远端音频流。 播放远端音频前,先创建 TiRtcAudioOutput,调用 attach(...) 指定要播放的 connection 和 streamId,再调用 connect(...) 建立连接;连接成功后,调用 TiRtcConn.subscribeAudio(...) 请求远端发送这路音频。 attach(...) 成功只表示播放对象已经知道要播放哪路音频。如果远端还没有发送这路音频,用户仍然听不到声音。 attach(...) 只选择这路音频由哪个 TiRtcAudioOutput 播放;subscribeAudio(...) 才会请求远端发送。
状态
TiRtcAudioOutputState.idle:还没有选择要播放的远端音频流,或已经detach()。TiRtcAudioOutputState.buffering:已经选择要播放的远端音频流,正在等待可播放数据。TiRtcAudioOutputState.playing:正在播放远端音频。TiRtcAudioOutputState.failed:播放路径发生错误。
属性和 delegate
// 当前音频播放状态。
var state: TiRtcAudioOutputState { get }
// 音频输出回调入口,SDK 弱引用持有;调用方需要自己持有 delegate 对象。
weak var delegate: TiRtcAudioOutputDelegate?相关类型:
@objc public protocol TiRtcAudioOutputDelegate: NSObjectProtocol {
// 播放状态变化时触发。
@objc optional func audioOutput(
_ output: TiRtcAudioOutput,
didChangeState state: TiRtcAudioOutputState
)
// 音频输出对象发生错误时触发。message 可能为空。
@objc optional func audioOutput(
_ output: TiRtcAudioOutput,
didFailWithCode code: Int32,
message: String?
)
}delegate 回调会切回主线程分发。
方法
// 创建音频输出对象。
TiRtcAudioOutput()
// 配置音频输出参数;创建对象后、attach 前调用。
// 返回 0 表示成功,非 0 为错误码;已绑定后调用会返回错误码。
func configure(_ options: TiRtcAudioOutputOptions) -> Int32
// 指定这个输出对象要播放的远端音频流。通常在 connect 前调用;如果输出对象晚创建,也可以在连接建立后调用。
// 远端发送这路音频后,用户才会听到声音。
func attach(connection: TiRtcConn, streamId: UInt8) -> Int32
// 停止使用这个输出对象播放当前音频流;切换流或释放对象前调用。成功后状态回到 idle。
func detach() -> Int32
// 释放音频输出对象;通常在 detach 后调用。调用后不要再使用这个实例。
func dispose()示例:
let audioOutput = TiRtcAudioOutput()
let code = audioOutput.attach(connection: conn, streamId: 10)
if code != 0 {
print("audio attach failed: \(TiRtc.errorToString(code)) (\(code))")
}
// 结束时:
_ = audioOutput.detach()
audioOutput.dispose()TiRtcVideoOutputOptions
TiRtcVideoOutputOptions 配置 TiRtcVideoOutput 的解码和缓冲参数。只需要填写要覆盖默认值的字段。
let options = TiRtcVideoOutputOptions()
// 解码偏好:0 自动,1 软件解码,2 硬件解码。
// 这只是请求偏好,实际选择取决于设备、系统和视频编码格式。
options.decoderPreference = 0
options.bufferStrategy = .automatic // 输出缓冲策略
// 最大输出缓冲水位,单位为毫秒;仅 .automatic 有效。
// nil 表示由 SDK 自动决定。
options.maxBufferWatermarkMs = nil相关枚举:
// 输出缓冲策略。
enum TiRtcOutputBufferStrategy {
case automatic // SDK 根据当前平台和链路状态决定缓冲策略
case noBuffer // 不使用输出缓冲;不要同时设置 maxBufferWatermarkMs
}TiRtcVideoOutput
TiRtcVideoOutput 用来显示某条远端视频流。 显示远端视频前,先创建 TiRtcVideoOutput,调用 attach(...) 指定要显示的 connection 和 streamId,并调用 attachView(...) 选择画面显示到哪个 iOS 视图,再调用 connect(...) 建立连接;连接成功后,调用 TiRtcConn.subscribeVideo(...) 请求远端发送这路视频。 attach(...) 成功只表示输出对象已经知道要显示哪路视频。如果远端还没有发送这路视频,视图不会出画面。 attach(...) 只选择这路视频由哪个 TiRtcVideoOutput 显示;subscribeVideo(...) 才会请求远端发送。
状态
TiRtcVideoOutputState.idle:还没有选择要显示的远端视频流,或已经detach()。TiRtcVideoOutputState.buffering:已经选择要显示的远端视频流,正在等待可渲染数据或渲染视图准备。TiRtcVideoOutputState.rendering:正在渲染远端视频。TiRtcVideoOutputState.failed:视频输出路径发生错误。
属性和 delegate
// 当前视频播放状态。
var state: TiRtcVideoOutputState { get }
// 最近一次远端画面渲染尺寸。还没有画面时为 .zero。
var renderSize: CGSize { get }
// 视频输出回调入口,SDK 弱引用持有;调用方需要自己持有 delegate 对象。
weak var delegate: TiRtcVideoOutputDelegate?相关类型:
// iOS 下 TiRtcPlatformView 是 UIView。
typealias TiRtcPlatformView = UIView
@objc public protocol TiRtcVideoOutputDelegate: NSObjectProtocol {
// 播放状态变化时触发。
@objc optional func videoOutput(
_ output: TiRtcVideoOutput,
didChangeState state: TiRtcVideoOutputState
)
// 远端画面尺寸变化时触发。
@objc optional func videoOutput(
_ output: TiRtcVideoOutput,
didChangeRenderSize size: CGSize
)
// 视频输出对象发生错误时触发。message 可能为空。
@objc optional func videoOutput(
_ output: TiRtcVideoOutput,
didFailWithCode code: Int32,
message: String?
)
}delegate 回调会切回主线程分发。
方法
// 创建视频输出对象。
TiRtcVideoOutput()
// 设置视频输出参数;创建对象后、attach 前调用。
// 返回 0 表示成功,非 0 为错误码;需要修改参数时先 detach,再重新 setOptions 和 attach。
func setOptions(_ options: TiRtcVideoOutputOptions) -> Int32
// 指定这个输出对象要显示的远端视频流。通常在 connect 前调用;如果输出对象晚创建,也可以在连接建立后调用。
// 远端发送这路视频后,页面才会出画面。
func attach(connection: TiRtcConn, streamId: UInt8) -> Int32
// 停止使用这个输出对象显示当前视频流;切换流或释放对象前调用。成功后状态回到 idle。
func detach() -> Int32
// 指定远端视频显示到哪个 iOS 视图;需要显示远端视频时调用。必须在主线程调用。
func attachView(_ view: TiRtcPlatformView) -> Int32
// 停止把画面显示到当前视图,但不改变 attach(...) 选择的远端视频流;隐藏或销毁视图前调用。
func detachView() -> Int32
// 释放视频输出对象和相关系统资源;通常在 detach 和 detachView 后调用。调用后不要再使用这个实例。
func dispose()示例:
let videoOutput = TiRtcVideoOutput()
_ = videoOutput.attachView(videoView)
let code = videoOutput.attach(connection: conn, streamId: 11)
if code != 0 {
print("video attach failed: \(TiRtc.errorToString(code)) (\(code))")
}
// 结束时:
_ = videoOutput.detach()
_ = videoOutput.detachView()
videoOutput.dispose()TiRtcAudioInputOptions
TiRtcAudioInputOptions 配置 TiRtcAudioInput 的麦克风采集和本地音频发送参数。配置会在下一次采集启动时生效;运行中调用 setOptions(...) 会返回错误码。
let options = TiRtcAudioInputOptions()
options.codec = .g711a // 本地音频传输编码
options.sampleRate = .rate16k // 麦克风采样率
options.channels = .mono // 声道数;公开能力只支持单声道
options.aecMode = 0 // 回声消除模式:0 关闭,1 开启
options.agcLevel = 0 // 自动增益等级:0 关闭,1 低,2 中,3 高
options.ansLevel = 0 // 自动噪声抑制等级:0 关闭,1 低,2 中,3 高相关枚举:
// 本地音频传输编码。
enum TiRtcAudioCodec {
case g711a
case aac
case pcm
}
// 麦克风采样率。
enum TiRtcAudioSampleRate {
case rate8k
case rate16k
}
// 声道数。公开能力只支持单声道。
enum TiRtcAudioChannelCount {
case mono
}TiRtcAudioInput
TiRtcAudioInput 采集本地麦克风声音,并通过已建立的连接发送给远端设备。常见用途是语音对讲或语音回复。
应用需要自己申请麦克风权限;SDK 不会替应用弹出系统权限申请框。
状态
TiRtcInputState.idle:输入对象已创建,但还没有开始采集。TiRtcInputState.running:正在采集并传输本地音频。TiRtcInputState.stopped:已停止采集;当前绑定仍可保留给后续start()复用。TiRtcInputState.failed:采集或传输路径发生错误。
属性和 delegate
// 当前本地音频输入状态。
var state: TiRtcInputState { get }
// 本地音频输入回调入口,SDK 弱引用持有;调用方需要自己持有 delegate 对象。
weak var delegate: TiRtcAudioInputDelegate?相关类型:
@objc public protocol TiRtcAudioInputDelegate: AnyObject {
// 输入状态变化时触发。
@objc optional func audioInput(
_ input: TiRtcAudioInput,
didChangeState state: TiRtcInputState
)
// 本地音频输入发生错误时触发。message 可能为空。
@objc optional func audioInput(
_ input: TiRtcAudioInput,
didFailWithCode code: Int32,
message: String?
)
}delegate 回调会切回主线程分发。
方法
// 创建本地音频输入对象。
TiRtcAudioInput()
// 设置下次采集使用的参数;创建对象后、start 前调用。
// 返回 0 表示成功,非 0 为错误码;正在采集时调用会返回错误码。
func setOptions(_ options: TiRtcAudioInputOptions) -> Int32
// 把本地麦克风音频通过指定连接和 streamId 发送给远端设备。
// 连接必须已进入 connected;在 start 前调用,streamId 使用 0..15。
func attach(connection: TiRtcConn, streamId: UInt8) -> Int32
// 开始麦克风采集和传输;返回 0 表示成功,非 0 为错误码。
// 调用 start 前,应用必须确保已经获得系统麦克风权限;SDK 不负责申请该权限。
// 还没有 attach 时会返回错误码。
func start() -> Int32
// 停止采集和传输,但保留当前绑定;暂停对讲或 detach 前调用。
func stop() -> Int32
// 移除当前连接上的本地音频绑定;停止发送、切换连接或切换 streamId 前调用。
// 运行中先 stop 再 detach。
func detach(connection: TiRtcConn) -> Int32
// 释放本地音频输入对象并清理绑定;通常在 stop 和 detach 后调用。调用后不要再使用这个实例。
func dispose()示例:
let input = TiRtcAudioInput()
let attachCode = input.attach(connection: conn, streamId: 14)
if attachCode == 0 {
_ = input.start()
}
// 结束时:
_ = input.stop()
_ = input.detach(connection: conn)
input.dispose()TiRtcLogging
TiRtcLogging 用于上传当前 SDK 日志。排查问题时,把上传成功返回的 logId 提供给支持人员。
// 异步上传当前 SDK 日志。
// 返回 0 只表示上传任务已经开始,结果通过 completion 返回。
static func upload(completion: @escaping (TiRtcLogUploadResult) -> Void) -> Int32相关类型:
final class TiRtcLogUploadResult {
let code: Int32
let logId: String?
// true 表示上传成功并拿到可用 logId。
var succeeded: Bool { get }
}示例:
TiRtcLogging.upload { result in
if result.succeeded, let logId = result.logId {
print("TiRTC logId=\(logId)")
}
}