Skip to content

Android

这页只覆盖客户端单端视角,目标是尽快跑通“引用 SDK -> 初始化 -> 连接并播放”。

前置条件

环境要求

项目要求
Android 版本Android 5.0(API Level 21)及以上
支持架构arm64-v8a
compileSdk35

1. 引用 SDK

先在 settings.gradle.kts 配置 Maven 仓库:

kotlin
dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
    google()
    mavenCentral()
    maven {
      url = uri("http://repo-sdk.tange-ai.com/repository/maven-public/")
      isAllowInsecureProtocol = true
      credentials {
        username = providers.gradleProperty("TIRTC_PUBLIC_MAVEN_USERNAME").orElse("tange_user").get()
        password = providers.gradleProperty("TIRTC_PUBLIC_MAVEN_PASSWORD").orElse("tange_user").get()
      }
    }
  }
}

再在 app 模块加入依赖:

kotlin
dependencies {
  implementation("com.tange.ai:tirtc-av:<latest-version>")
}

版本号从Android SDK 发布说明获取。

2. 初始化 SDK

在创建 TiRtcConnTiRtcAudioOutputTiRtcVideoOutput 之前,先初始化一次:

kotlin
class DemoApp : Application() {
  override fun onCreate() {
    super.onCreate()
    TiRtc.initialize(applicationContext)
  }
}

3. 连接并播放

这份 quick start 按“连上就发”策略保持最短路径。如果你的设备端采用“收到订阅再发”,连接进入 CONNECTED 后再调用 conn.subscribeAudio(streamId = audioStreamId)conn.subscribeVideo(streamId = videoStreamId),页面离开前再调用 conn.unsubscribeAudio(streamId = audioStreamId)conn.unsubscribeVideo(streamId = videoStreamId)

先准备一个视频容器:

xml
<FrameLayout
  android:id="@+id/remote_video_container"
  android:layout_width="match_parent"
  android:layout_height="240dp" />

然后按 Activity 生命周期处理播放。

kotlin
class PlayerActivity : AppCompatActivity() {
  private companion object {
    const val TAG = "TiRtcQuickStart"
  }

  private val remoteId = "your-remote-id"
  private val token = "v1.xxxxxx" // got from backend
  private val audioStreamId = yourAudioStreamId
  private val videoStreamId = yourVideoStreamId

  // 打印基础状态,便于先定位黑屏、无声或断连。
  private val conn = TiRtcConn().apply {
    onStateChanged = { state ->
      Log.i(TAG, "conn state=$state")
    }
    onDisconnected = { code ->
      Log.i(TAG, "conn disconnected code=$code")
    }
    onError = { code ->
      Log.e(TAG, "conn error code=$code")
    }
  }
  private val audioOutput = TiRtcAudioOutput().apply {
    onStateChanged = { state ->
      Log.i(TAG, "audio state=$state")
    }
    onError = { code ->
      Log.e(TAG, "audio error code=$code")
    }
  }
  private val videoOutput = TiRtcVideoOutput().apply {
    onStateChanged = { state ->
      Log.i(TAG, "video state=$state")
    }
    onRenderSizeChanged = { size ->
      Log.i(TAG, "video size=${size.width}x${size.height}")
    }
    onError = { code ->
      Log.e(TAG, "video error code=$code")
    }
  }

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_player)

    // 绑定画面渲染容器。
    videoOutput.attachView(findViewById(R.id.remote_video_container))
  }

  override fun onResume() {
    super.onResume()
    // 绑定要播放的远端音视频流,再发起连接。
    audioOutput.attach(conn, audioStreamId)
    videoOutput.attach(conn, videoStreamId)
    val code = conn.connect(remoteId = remoteId, token = token)
    if (code != 0) {
      Log.e(TAG, "connect request failed code=$code")
    }
  }

  override fun onPause() {
    super.onPause()
    // 页面不可见时先停播断连。
    audioOutput.detach()
    videoOutput.detach()
    conn.disconnect()
  }

  override fun onDestroy() {
    super.onDestroy()
    // 页面销毁时释放对象。
    videoOutput.detachView()
    audioOutput.release()
    videoOutput.release()
    conn.release()
  }
}

Ti RTC 开发文档