Skip to content

Android API 说明

Android SDK com.tange.ai:tirtc 提供客户端 Kotlin / Java API,适用于用 Android 原生应用接入 TiRTC。如果你还没有完成 AAR 接入、工程配置或连接流程准备,先看 Android SDK 接入

生命周期与调用顺序

典型客户端流程是:连接一个设备端,播放设备端音视频,并按需收发命令或发起语音对讲。主干从 TiRtc.initialize(...) 开始,以 disconnect()dispose() 收尾。

  1. 初始化:传入 AppId,启动 SDK 运行时。

    kotlin
    TiRtc.initialize(applicationContext, TiRtcInitOptions(appId = appId))
  2. 创建连接:创建 TiRtcConn,并在连接前设置状态、命令和流消息 listener。

    kotlin
    val conn = TiRtcConn().apply {
        onStateChanged = TiRtcConnStateListener { state, errorCode ->
            handleConnStateChanged(state, errorCode)
        }
        onCommand = TiRtcConnCommandListener { commandId, data ->
            handleCommand(commandId, data)
        }
        onStreamMessage = TiRtcConnStreamMessageListener { streamId, timestampMs, data ->
            handleStreamMessage(streamId, timestampMs, data)
        }
    }
  3. 准备播放:在发起连接前创建音频输出和视频输出,并指定要播放的 streamId

    kotlin
    val audioOutput = TiRtcAudioOutput()
    audioOutput.attach(conn, audioStreamId)
    
    val videoOutput = TiRtcVideoOutput()
    videoOutput.attach(conn, videoStreamId)
  4. 渲染视频:在主线程把视频输出挂到 Android 容器中,让视频输出有对应的显示位置。

    kotlin
    videoOutput.attachView(container)
  5. 发起连接:传入目标设备的 device_id 和业务服务端签发的 token

    kotlin
    conn.connect(remoteId, token)
  6. 请求媒体:连接进入 CONNECTED 后,按需请求设备端发送音频流和视频流。

    kotlin
    conn.subscribeAudio(audioStreamId) // 连接成功后订阅音频
    conn.subscribeVideo(videoStreamId) // 连接成功后订阅视频
  7. 命令交互:连接进入 CONNECTED 后,按需通过命令通道和设备端交换业务数据。

    kotlin
    conn.sendCommand(commandId, data) // 需要命令交互时调用
    // 收到设备端命令时,在 handleCommand(commandId, data) 中处理。
  8. 语音对讲(按需):应用获得 RECORD_AUDIO 权限后,创建音频输入,绑定到同一条连接,并启动采集发送。

    kotlin
    val talkbackInput = TiRtcAudioInput()
    talkbackInput.setOptions(talkbackOptions)
    talkbackInput.attach(conn, talkbackStreamId)
    talkbackInput.start()
  9. 收尾释放:业务结束时先释放按需创建的输入对象,再按订阅、输出、连接的顺序收尾。

    kotlin
    talkbackInput.stop() // 创建了 talkbackInput 时调用
    talkbackInput.detach(conn)
    talkbackInput.dispose()
    
    conn.unsubscribeAudio(audioStreamId) // 停止播放时取消音频订阅
    conn.unsubscribeVideo(videoStreamId) // 停止播放时取消视频订阅
    
    audioOutput.detach()
    videoOutput.detach()
    videoOutput.detachView()
    audioOutput.dispose()
    videoOutput.dispose()
    
    conn.disconnect()
    conn.dispose()

TiRtcInitOptions

TiRtcInitOptionsTiRtc.initialize(...) 的参数对象。

初始化时必须传 appId,取值为你的 AppId

kotlin
class TiRtcInitOptions @JvmOverloads constructor(
    val appId: String = "", // 必填:你的 AppId
    val endpoint: String = "", // 切换自部署云端实例或测试、联调环境时设置,例如 "https://ep-tirtc.my-domain.com";其他情况保持空字符串
    val consoleLogEnabled: Boolean = false, // true 时同时把 SDK 日志打印到控制台
)

TiRtc

TiRtc 提供初始化和错误码名称转换入口。

kotlin
// 初始化 SDK。返回 0 表示成功,非 0 为错误码。
// context 可以传 Activity 或 Application;SDK 会使用 applicationContext。
// 重复调用成功时返回 0,不会替换已生效的配置。
fun initialize(context: Context, config: TiRtcInitOptions): Int

// 把错误码转成错误名称。
fun errorToString(code: Int): String

示例:

kotlin
val code = TiRtc.initialize(
    applicationContext,
    TiRtcInitOptions(appId = "your-app-id"),
)
if (code != 0) {
    Log.e("tirtc", "initialize failed: ${TiRtc.errorToString(code)} ($code)")
}

TiRtcConn

TiRtcConn 表示客户端到远端设备的一条连接。创建对象不会立即发起连接;通常先设置 listener,再调用 connect(...)。连接建立后,可以通过它发送命令、发送流消息、发起媒体订阅和请求视频关键帧。

音频播放和视频显示由 TiRtcAudioOutput / TiRtcVideoOutput 负责,TiRtcConn 本身不播放也不显示媒体。

状态

  • TiRtcConnState.IDLE:连接对象已创建,但还没有开始连接。
  • TiRtcConnState.CONNECTING:连接请求已提交,正在等待结果。
  • TiRtcConnState.CONNECTED:连接已经建立,可收发命令、流消息,发起媒体订阅和关键帧请求。
  • TiRtcConnState.DISCONNECTED:连接失败、对端断开或调用 disconnect() 后进入该状态。

属性和 listener

kotlin
// 当前连接状态。
val state: TiRtcConnState

// 连接状态变化时触发。errorCode 为 0 表示本次状态变化没有错误;非 0 为错误码。
// 设置后会通过 Android 主线程立即回调一次当前状态。
var onStateChanged: TiRtcConnStateListener?

// 收到设备端命令时触发。
var onCommand: TiRtcConnCommandListener?

// 收到设备端的流消息时触发。
var onStreamMessage: TiRtcConnStreamMessageListener?

相关类型:

kotlin
fun interface TiRtcConnStateListener {
    fun onStateChanged(state: TiRtcConnState, errorCode: Int)
}

fun interface TiRtcConnCommandListener {
    fun onCommand(command: Long, data: ByteArray)
}

fun interface TiRtcConnStreamMessageListener {
    fun onStreamMessage(streamId: Int, timestampMs: Long, data: ByteArray)
}

方法

kotlin
// 创建连接对象;构造函数本身不会发起连接。通常先设置 listener,再调用 connect。
TiRtcConn()

// 发起连接;初始化完成并拿到连接凭证后调用。
// remoteId 是连接目标;连接设备端时传目标设备的 device_id,例如 "PRODFENGXXXX"。
// token 是业务服务端为本次连接签发的 token,二者不能为空。
// 返回 0 只表示请求已提交,最终连接结果看 onStateChanged;非 0 为错误码。
fun connect(remoteId: String, token: String): Int

// 断开当前连接;业务结束、切换设备或重新连接前调用。对象仍可重新 connect。
fun disconnect(): Int

// 释放连接对象;确认不再使用这条连接后调用。调用后不要再使用这个实例。
fun dispose(): Int

// 在命令通道上发送自定义命令;连接进入 CONNECTED 后调用。
fun sendCommand(commandId: Long, data: ByteArray = byteArrayOf()): Int

// 发送流消息;连接进入 CONNECTED 后调用。
// streamId 按 stream_id 约定使用 0..15,两端需要提前约定消息语义。
fun sendStreamMessage(streamId: Int, timestampMs: Long, data: ByteArray): Int

// 请求远端开始发送指定 streamId 的音频流;连接进入 CONNECTED 后调用。
// streamId 按 stream_id 约定使用 0..15。
// 这个方法只请求远端发送音频,不会自动播放。
// 播放远端音频前,先调用 TiRtcAudioOutput.attach(...) 指定要播放的 connection 和 streamId;然后调用 connect(...) 建立连接。
// 连接成功后,再调用 subscribeAudio(...) 请求远端发送这路音频。
fun subscribeAudio(streamId: Int): Int

// 请求远端停止发送指定 streamId 的音频流;streamId 按 stream_id 约定使用 0..15。
// 不会停止已经创建的 TiRtcAudioOutput。停止播放时再调用 TiRtcAudioOutput.detach()。
fun unsubscribeAudio(streamId: Int): Int

// 请求远端开始发送指定 streamId 的视频流;连接进入 CONNECTED 后调用。
// streamId 按 stream_id 约定使用 0..15。
// 这个方法只请求远端发送视频,不会自动显示。
// 显示远端视频前,先调用 TiRtcVideoOutput.attach(...) 指定要显示的 connection 和 streamId;然后调用 connect(...) 建立连接。
// 连接成功后,再调用 subscribeVideo(...) 请求远端发送这路视频。
fun subscribeVideo(streamId: Int): Int

// 请求远端停止发送指定 streamId 的视频流;streamId 按 stream_id 约定使用 0..15。
// 不会停止已经创建的 TiRtcVideoOutput。停止显示时再调用 TiRtcVideoOutput.detach()。
fun unsubscribeVideo(streamId: Int): Int

// 向远端请求指定视频流的关键帧;连接已建立且远端正在发送该视频流时调用。
// streamId 按 stream_id 约定使用 0..15。
fun requestKeyFrame(streamId: Int): Int

示例:

kotlin
val conn = TiRtcConn().apply {
    onStateChanged = TiRtcConnStateListener { state, errorCode ->
        if (errorCode == 0) {
            Log.d("tirtc", "conn state=$state")
            return@TiRtcConnStateListener
        }
        Log.d("tirtc", "conn state=$state error=${TiRtc.errorToString(errorCode)} ($errorCode)")
    }
    onCommand = TiRtcConnCommandListener { commandId, data ->
        Log.d("tirtc", "command=$commandId bytes=${data.size}")
    }
}

val code = conn.connect(remoteId, token)
if (code != 0) {
    Log.e("tirtc", "connect failed: ${TiRtc.errorToString(code)} ($code)")
}

// 结束时:
conn.disconnect()
conn.dispose()

TiRtcAudioOutputOptions

TiRtcAudioOutputOptions 配置 TiRtcAudioOutput 的音频输出参数。只需要填写要覆盖默认值的字段。

kotlin
class TiRtcAudioOutputOptions @JvmOverloads constructor(
    val agcLevel: Int = 0, // 自动增益等级:0 关闭,1 低,2 中,3 高
    val ansLevel: Int = 0, // 自动噪声抑制等级:0 关闭,1 低,2 中,3 高
    val bufferStrategy: TiRtcOutputBufferStrategy = TiRtcOutputBufferStrategy.AUTOMATIC, // 输出缓冲策略
    // 最大输出缓冲水位,单位为毫秒;仅 AUTOMATIC 有效。
    // null 表示由 SDK 自动决定。
    val maxBufferWatermarkMs: Int? = null,
)

相关枚举:

kotlin
// 输出缓冲策略。
enum class TiRtcOutputBufferStrategy {
    AUTOMATIC, // SDK 根据当前平台和链路状态决定缓冲策略
    NO_BUFFER, // 不使用输出缓冲;不要同时设置 maxBufferWatermarkMs
}

TiRtcAudioOutput

TiRtcAudioOutput 用来播放某条远端音频流。 播放远端音频前,先创建 TiRtcAudioOutput,调用 attach(...) 指定要播放的 connectionstreamId,再调用 connect(...) 建立连接;连接成功后,调用 TiRtcConn.subscribeAudio(...) 请求远端发送这路音频。 attach(...) 成功只表示播放对象已经知道要播放哪路音频。如果远端还没有发送这路音频,用户仍然听不到声音。 attach(...) 只选择这路音频由哪个 TiRtcAudioOutput 播放;subscribeAudio(...) 才会请求远端发送。

状态

  • TiRtcAudioOutputState.IDLE:还没有选择要播放的远端音频流,或已经 detach()
  • TiRtcAudioOutputState.BUFFERING:已经选择要播放的远端音频流,正在等待可播放数据。
  • TiRtcAudioOutputState.PLAYING:正在播放远端音频。
  • TiRtcAudioOutputState.FAILED:播放路径发生错误。

属性和 listener

kotlin
// 当前音频播放状态。
val state: TiRtcAudioOutputState

// 播放状态变化时触发;设置后会通过 Android 主线程立即回调一次当前状态。
var onStateChanged: TiRtcAudioOutputStateListener?

// 音频输出对象发生错误时触发。
var onError: TiRtcAudioOutputErrorListener?

相关类型:

kotlin
fun interface TiRtcAudioOutputStateListener {
    fun onStateChanged(state: TiRtcAudioOutputState)
}

fun interface TiRtcAudioOutputErrorListener {
    fun onError(code: Int)
}

方法

kotlin
// 创建音频输出对象。
TiRtcAudioOutput()

// 配置音频输出参数;创建对象后、attach 前调用。
// 返回 0 表示成功,非 0 为错误码;已绑定后调用会返回错误码。
fun configure(options: TiRtcAudioOutputOptions): Int

// 指定这个输出对象要播放的远端音频流。通常在 connect 前调用;如果输出对象晚创建,也可以在连接建立后调用。
// 远端发送这路音频后,用户才会听到声音。
fun attach(connection: TiRtcConn, streamId: Int): Int

// 停止使用这个输出对象播放当前音频流;切换流或释放对象前调用。成功后状态回到 IDLE。
fun detach(): Int

// 释放音频输出对象;通常在 detach 后调用。调用后不要再使用这个实例。
fun dispose(): Int

示例:

kotlin
val audioOutput = TiRtcAudioOutput().apply {
    onError = TiRtcAudioOutputErrorListener { code ->
        Log.e("tirtc", "audio output error: ${TiRtc.errorToString(code)} ($code)")
    }
}

val code = audioOutput.attach(conn, 10)
if (code != 0) {
    Log.e("tirtc", "audio attach failed: ${TiRtc.errorToString(code)} ($code)")
}

// 结束时:
audioOutput.detach()
audioOutput.dispose()

TiRtcVideoOutputOptions

TiRtcVideoOutputOptions 配置 TiRtcVideoOutput 的解码和缓冲参数。只需要填写要覆盖默认值的字段。

kotlin
class TiRtcVideoOutputOptions @JvmOverloads constructor(
    // 解码偏好:0 自动,1 软件解码,2 硬件解码。
    // 这只是请求偏好,实际选择取决于设备、系统和视频编码格式。
    val decoderPreference: Int = 0,
    val bufferStrategy: TiRtcOutputBufferStrategy = TiRtcOutputBufferStrategy.AUTOMATIC, // 输出缓冲策略
    // 最大输出缓冲水位,单位为毫秒;仅 AUTOMATIC 有效。
    // null 表示由 SDK 自动决定。
    val maxBufferWatermarkMs: Int? = null,
)

相关枚举:

kotlin
// 输出缓冲策略。
enum class TiRtcOutputBufferStrategy {
    AUTOMATIC, // SDK 根据当前平台和链路状态决定缓冲策略
    NO_BUFFER, // 不使用输出缓冲;不要同时设置 maxBufferWatermarkMs
}

TiRtcVideoOutput

TiRtcVideoOutput 用来显示某条远端视频流。 显示远端视频前,先创建 TiRtcVideoOutput,调用 attach(...) 指定要显示的 connectionstreamId,并调用 attachView(...) 选择画面显示到哪个 ViewGroup,再调用 connect(...) 建立连接;连接成功后,调用 TiRtcConn.subscribeVideo(...) 请求远端发送这路视频。 attach(...) 成功只表示输出对象已经知道要显示哪路视频。如果远端还没有发送这路视频,容器不会出画面。 attach(...) 只选择这路视频由哪个 TiRtcVideoOutput 显示;subscribeVideo(...) 才会请求远端发送。

状态

  • TiRtcVideoOutputState.IDLE:还没有选择要显示的远端视频流,或已经 detach()
  • TiRtcVideoOutputState.BUFFERING:已经选择要显示的远端视频流,正在等待可渲染数据或渲染容器准备。
  • TiRtcVideoOutputState.RENDERING:正在渲染远端视频。
  • TiRtcVideoOutputState.FAILED:视频输出路径发生错误。

属性和 listener

kotlin
// 当前视频播放状态。
val state: TiRtcVideoOutputState

// 最近一次远端画面渲染尺寸。还没有画面或已经 detach 时可能为 null。
val renderSize: Size?

// 播放状态变化时触发;设置后会通过 Android 主线程立即回调一次当前状态。
var onStateChanged: TiRtcVideoOutputStateListener?

// 远端画面尺寸变化时触发。
var onRenderSizeChanged: TiRtcVideoOutputRenderSizeListener?

// 视频输出对象发生错误时触发。
var onError: TiRtcVideoOutputErrorListener?

相关类型:

kotlin
fun interface TiRtcVideoOutputStateListener {
    fun onStateChanged(state: TiRtcVideoOutputState)
}

fun interface TiRtcVideoOutputRenderSizeListener {
    fun onRenderSizeChanged(size: Size)
}

fun interface TiRtcVideoOutputErrorListener {
    fun onError(code: Int)
}

方法

kotlin
// 创建视频输出对象。
TiRtcVideoOutput()

// 设置视频输出参数;创建对象后、attach 前调用。
// 返回 0 表示成功,非 0 为错误码;需要修改参数时先 detach,再重新 setOptions 和 attach。
fun setOptions(options: TiRtcVideoOutputOptions): Int

// 指定这个输出对象要显示的远端视频流。通常在 connect 前调用;如果输出对象晚创建,也可以在连接建立后调用。
// 远端发送这路视频后,页面才会出画面。
fun attach(connection: TiRtcConn, streamId: Int): Int

// 停止使用这个输出对象显示当前视频流;切换流或释放对象前调用。成功后状态回到 IDLE,并清空 renderSize。
fun detach(): Int

// 指定远端视频显示到哪个 Android 容器;需要显示远端视频时调用。必须在主线程调用。
// SDK 会在容器内创建并管理自己的 TextureView。
fun attachView(container: ViewGroup): Int

// 停止把画面显示到当前容器,但不改变 attach(...) 选择的远端视频流;隐藏或销毁容器前调用。必须在主线程调用。
fun detachView(): Int

// 释放视频输出对象和相关系统资源;通常在 detach 和 detachView 后调用。调用后不要再使用这个实例。
// 如果还在使用 Android 容器,也需要在主线程调用。
fun dispose(): Int

示例:

kotlin
val videoOutput = TiRtcVideoOutput().apply {
    onRenderSizeChanged = TiRtcVideoOutputRenderSizeListener { size ->
        Log.d("tirtc", "remote video size=${size.width}x${size.height}")
    }
}

videoOutput.attachView(container)

val code = videoOutput.attach(conn, 11)
if (code != 0) {
    Log.e("tirtc", "video attach failed: ${TiRtc.errorToString(code)} ($code)")
}

// 结束时:
videoOutput.detach()
videoOutput.detachView()
videoOutput.dispose()

TiRtcAudioInputOptions

TiRtcAudioInputOptions 配置 TiRtcAudioInput 的麦克风采集和本地音频发送参数。配置会在下一次采集启动时生效;运行中调用 setOptions(...) 会返回错误码。

kotlin
class TiRtcAudioInputOptions @JvmOverloads constructor(
    var codec: TiRtcAudioCodec = TiRtcAudioCodec.G711A, // 本地音频传输编码
    var sampleRate: TiRtcAudioSampleRate = TiRtcAudioSampleRate.RATE_16K, // 麦克风采样率
    var channels: TiRtcAudioChannelCount = TiRtcAudioChannelCount.MONO, // 声道数;公开能力只支持单声道
    var aecMode: Int = 0, // 回声消除模式:0 关闭,1 开启
    var agcLevel: Int = 0, // 自动增益等级:0 关闭,1 低,2 中,3 高
    var ansLevel: Int = 0, // 自动噪声抑制等级:0 关闭,1 低,2 中,3 高
)

相关枚举:

kotlin
// 本地音频传输编码。
enum class TiRtcAudioCodec {
    G711A,
    AAC,
    PCM,
}

// 麦克风采样率。
enum class TiRtcAudioSampleRate {
    RATE_8K,
    RATE_16K,
}

// 声道数。公开能力只支持单声道。
enum class TiRtcAudioChannelCount {
    MONO,
}

TiRtcAudioInput

TiRtcAudioInput 采集本地麦克风声音,并通过已建立的连接发送给远端设备。常见用途是语音对讲或语音回复。

应用需要自己申请 RECORD_AUDIO 权限;SDK 不会替应用弹出系统权限申请框。

状态

  • TiRtcInputState.IDLE:输入对象已创建,但还没有开始采集。
  • TiRtcInputState.RUNNING:正在采集并传输本地音频。
  • TiRtcInputState.STOPPED:已停止采集;当前绑定仍可保留给后续 start() 复用。
  • TiRtcInputState.FAILED:采集或传输路径发生错误。

属性和 listener

kotlin
// 当前本地音频输入状态。
val state: TiRtcInputState

// 输入状态变化时触发;设置后会通过 Android 主线程立即回调一次当前状态。
var onStateChanged: TiRtcInputStateListener?

// 本地音频输入发生错误时触发。message 可能为空。
var onError: TiRtcInputErrorListener?

相关类型:

kotlin
fun interface TiRtcInputStateListener {
    fun onStateChanged(state: TiRtcInputState)
}

fun interface TiRtcInputErrorListener {
    fun onError(code: Int, message: String?)
}

方法

kotlin
// 创建本地音频输入对象。
TiRtcAudioInput()

// 设置下次采集使用的参数;创建对象后、start 前调用。
// 返回 0 表示成功,非 0 为错误码;正在采集时调用会返回错误码。
fun setOptions(options: TiRtcAudioInputOptions): Int

// 把本地麦克风音频通过指定连接和 streamId 发送给远端设备。
// 连接必须已进入 CONNECTED;在 start 前调用,streamId 使用 0..15。
// 重复相同绑定返回 0;更换连接或 streamId 前先 detach。
fun attach(connection: TiRtcConn, streamId: Int): Int

// 开始麦克风采集和传输;返回 0 表示成功,非 0 为错误码。
// 调用 start 前,应用必须确保已经获得系统麦克风权限;SDK 不负责申请该权限。
// 还没有 attach 时会返回错误码。
fun start(): Int

// 停止采集和传输,但保留当前绑定;已经停止时调用也返回 0。
fun stop(): Int

// 移除当前连接上的本地音频绑定;停止发送、切换连接或切换 streamId 前调用。
// 运行中先 stop 再 detach。
fun detach(connection: TiRtcConn): Int

// 释放本地音频输入对象并清理绑定;通常在 stop 和 detach 后调用。调用后不要再使用这个实例。
fun dispose(): Int

示例:

kotlin
val input = TiRtcAudioInput().apply {
    onError = TiRtcInputErrorListener { code, message ->
        Log.e("tirtc", "audio input error: ${TiRtc.errorToString(code)} ($code) ${message.orEmpty()}")
    }
}

val attachCode = input.attach(conn, 14)
if (attachCode == 0) {
    input.start()
}

// 结束时:
input.stop()
input.detach(conn)
input.dispose()

TiRtcLogging

TiRtcLogging 用于上传当前 SDK 日志。排查问题时,把上传成功返回的 logId 提供给支持人员。

kotlin
// 异步上传当前 SDK 日志。
// 返回 0 只表示上传任务已经开始,结果通过 callback 返回。
fun upload(callback: TiRtcLogUploadCallback): Int

相关类型:

kotlin
fun interface TiRtcLogUploadCallback {
    fun onCompleted(code: Int, logId: String?)
}

示例:

kotlin
TiRtcLogging.upload(
    TiRtcLogUploadCallback { code, logId ->
        if (code == 0 && !logId.isNullOrEmpty()) {
            Log.d("tirtc", "TiRTC logId=$logId")
        }
    },
)

TiRTC 开发文档