Android

欢迎阅读 Tencent RTC Engine SDK 迁移指南。本文旨在协助开发者将基于 Twilio Video SDK 的实施方案高效迁移到 Tencent RTC Engine SDK。我们将通过详细的技术架构差异分析、迁移准备指引、核心功能迁移示例以及进阶功能对比,帮助您实现快速且无缝的迁移。如果您计划为新项目接入 Tencent RTC Engine SDK,我们建议您从 接入指南 开始学习;如果您想了解 Tencent RTC Engine 的更多信息,我们建议您访问 产品概述

基本概念与技术架构差异

基本概念对比

本节对 Tencent RTC Engine 和 Twilio Video 服务过程中可能涉及到的一些基本概念进行了对比。要了解更多关于 Tencent RTC Engine 概念信息,请访问 基本概念
概念
Tencent RTC Engine
Twilio Video
说明
房间
Room
Room
将 RTC 参与者联系在一起的会话空间。Tencent RTC 使用 roomId(数字)
或 strRoomId(字符串),Twilio 使用 roomName(字符串)。
用户
User
Participant
参与音视频通话的用户。
主播
Anchor
-
拥有推流权限的用户类型,可向服务端推送和接收音视频流。
观众
Audience
-
只能接收音视频流的用户类型。
应用标识
SDKAppID
Account SID
应用唯一标识。
鉴权凭证
UserSig
Access Token
客户端鉴权凭证。
用户标识
userId
Identity
用户唯一标识。
核心入口类
TRTCCloud
Video (类)
SDK 核心入口类。

技术架构差异

Twilio Video 架构

Twilio Video 采用 Track-based(基于轨道) 架构:
开发者需要显式创建 LocalAudioTrackLocalVideoTrack
通过 ConnectOptions.Builder 传入轨道列表来发布。
远端轨道通过 RemoteParticipant.Listener 的回调来订阅。
使用 VideoSink / VideoView 来渲染视频。

Tencent RTC Engine 架构

Tencent RTC Engine 采用 API-driven(API 驱动) 架构:
通过 TRTCCloud 单例直接调用 startLocalPreview()startLocalAudio() 来采集发布。
远端流的订阅通过 TRTCCloudListener 的回调 + startRemoteView() 来完成。
使用 TXCloudVideoView 来渲染视频。
不需要显式创建和管理轨道对象。
这意味着 Tencent RTC Engine 的 API 更加简洁,减少了对象管理的复杂性。

迁移准备

步骤1. 开通服务

要访问 Tencent RTC Engine 服务,需要创建一个 Tencent RTC Engine 应用程序及其凭据。您可以按照以下步骤在 Tencent RTC 控制台中创建新的 Tencent RTC Engine 应用程序:
1. 注册或登录您的 Tencent RTC 账号,并登录到 Tencent RTC 控制台
2. 点击 Create Application
3. 在创建弹窗中,输入您的应用程序名称,选择 RTC Engine,点击 Create

4. 应用程序创建后,可在 Basic Information 获取以下凭证:
SDKAppID:自动生成的应用 ID,用于唯一标识您的 Tencent RTC 应用程序。
SDKSecretKey:用于生成安全签名 UserSig 的关键参数,用于保障 Tencent RTC 服务的安全访问。



说明:
关于鉴权对比:Twilio Video 使用 Access Token 进行身份验证,而 Tencent RTC 使用 UserSig。两者都是由服务端生成的时效性签名凭证,但生成方式不同。详见 UserSig 鉴权文档

步骤2. 导入 SDK

Twilio Video SDK (原依赖)

dependencies {
implementation 'com.twilio:video-android:7.10.2'
}

Tencent RTC Engine SDK (新依赖)

app/build.gradle 的 dependencies 中添加对 TRTC SDK 的依赖。
dependencies {
implementation 'com.tencent.liteav:LiteAVSDK_TRTC:latest.release'
}

步骤3. 配置工程

指定 CPU 架构

app/build.gradle 的 defaultConfig 中指定项目的 CPU 架构,支持 armeabi-v7a/arm64-v8a 架构的设备。
android {
defaultConfig {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}

配置权限

进入 AndroidManifest.xml 文件,添加 TRTC SDK 所需权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-feature android:name="android.hardware.camera.autofocus" />
注意:
请勿设置 android:hardwareAccelerated="false",关闭硬件加速导致视频流无法渲染。

配置混淆规则

进入 proguard-rules.pro 文件, 将 TRTC SDK 相关类及其成员加入不混淆名单。
-keep class com.tencent.** { *; }

迁移指引

步骤4. 初始化 SDK 实例

Twilio Video

// Twilio Video 不需要显式初始化 SDK 实例
// 直接通过 Video.connect() 静态方法连接房间
// 可选:设置日志级别
Video.setLogLevel(LogLevel.DEBUG);

Tencent RTC Engine

Java
Kotlin
// 创建 TRTCCloud 单例实例
TRTCCloud mCloud = TRTCCloud.sharedInstance(getApplicationContext());
// 创建 TRTCCloud 单例实例
val mCloud = TRTCCloud.sharedInstance(applicationContext)

步骤5. 设置事件监听器

Twilio Video

Room.Listener roomListener = new Room.Listener() {
@Override
public void onConnected(Room room) {
Log.i("Twilio", "Connected to " + room.getName());
}

@Override
public void onConnectFailure(Room room, TwilioException twilioException) {
Log.e("Twilio", "Connect failure: " + twilioException.getMessage());
}

@Override
public void onDisconnected(Room room, TwilioException twilioException) {
Log.i("Twilio", "Disconnected from " + room.getName());
}

@Override
public void onParticipantConnected(Room room, RemoteParticipant remoteParticipant) {
Log.i("Twilio", "Participant connected: " + remoteParticipant.getIdentity());
}

@Override
public void onParticipantDisconnected(Room room, RemoteParticipant remoteParticipant) {
Log.i("Twilio", "Participant disconnected: " + remoteParticipant.getIdentity());
}

@Override
public void onReconnecting(Room room, TwilioException twilioException) {
Log.i("Twilio", "Reconnecting...");
}

@Override
public void onReconnected(Room room) {
Log.i("Twilio", "Reconnected");
}
};

Tencent RTC Engine

Java
Kotlin
TRTCCloudListener trtcListener = new TRTCCloudListener() {
@Override
public void onEnterRoom(long result) {
if (result > 0) {
Log.i("TRTC", "进房成功,耗时 " + result + "ms");
} else {
Log.e("TRTC", "进房失败,错误码 " + result);
}
}

@Override
public void onExitRoom(int reason) {
// reason: 0-主动退出 1-被踢出房间 2-房间解散
Log.i("TRTC", "已退出房间,原因: " + reason);
}

@Override
public void onRemoteUserEnterRoom(String userId) {
Log.i("TRTC", "远端用户进入房间: " + userId);
}

@Override
public void onRemoteUserLeaveRoom(String userId, int reason) {
Log.i("TRTC", "远端用户离开房间: " + userId);
}

@Override
public void onError(int errCode, String errMsg, Bundle extraInfo) {
Log.e("TRTC", "错误: " + errCode + " - " + errMsg);
}

@Override
public void onConnectionLost() {
Log.w("TRTC", "与服务器连接断开");
}

@Override
public void onTryToReconnect() {
Log.i("TRTC", "正在尝试重新连接...");
}

@Override
public void onConnectionRecovery() {
Log.i("TRTC", "连接已恢复");
}
};

mCloud.addListener(trtcListener);
val trtcListener = object : TRTCCloudListener() {
override fun onEnterRoom(result: Long) {
if (result > 0) {
Log.i("TRTC", "进房成功,耗时 ${result}ms")
} else {
Log.e("TRTC", "进房失败,错误码 $result")
}
}

override fun onExitRoom(reason: Int) {
// reason: 0-主动退出 1-被踢出房间 2-房间解散
Log.i("TRTC", "已退出房间,原因: $reason")
}

override fun onRemoteUserEnterRoom(userId: String?) {
Log.i("TRTC", "远端用户进入房间: $userId")
}

override fun onRemoteUserLeaveRoom(userId: String?, reason: Int) {
Log.i("TRTC", "远端用户离开房间: $userId")
}

override fun onError(errCode: Int, errMsg: String?, extraInfo: Bundle?) {
Log.e("TRTC", "错误: $errCode - $errMsg")
}

override fun onConnectionLost() {
Log.w("TRTC", "与服务器连接断开")
}

override fun onTryToReconnect() {
Log.i("TRTC", "正在尝试重新连接...")
}

override fun onConnectionRecovery() {
Log.i("TRTC", "连接已恢复")
}
}

mCloud.addListener(trtcListener)
回调事件映射表
Twilio Video 回调
Tencent RTC Engine 回调
说明
onConnected
onEnterRoom (result > 0)
成功连接/进入房间。
onConnectFailure
onEnterRoom (result < 0) 或 onError
连接失败。
onDisconnected
onExitRoom
断开连接/退出房间。
onParticipantConnected
onRemoteUserEnterRoom
远端用户进入。
onParticipantDisconnected
onRemoteUserLeaveRoom
远端用户离开。
onReconnecting
onConnectionLost + onTryToReconnect
正在重连。
onReconnected
onConnectionRecovery
重连成功。

步骤6. 进入房间/连接到房间

Twilio Video

// 构建连接选项(不携带本地轨道,后续动态发布)
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
.roomName("my-room")
.build();

// 连接到房间(传入已定义好的 roomListener)
Room room = Video.connect(context, connectOptions, roomListener);

Tencent RTC Engine

Java
Kotlin
// 配置进房参数
TRTCCloudDef.TRTCParams trtcParams = new TRTCCloudDef.TRTCParams();
trtcParams.sdkAppId = 2000000000; // 您的 SDKAppID
trtcParams.userId = "user_id"; // 用户 ID
trtcParams.userSig = "user_sig"; // 用户签名
trtcParams.role = TRTCCloudDef.TRTCRoleAudience; // 用户进房角色
trtcParams.strRoomId = "my-room"; // 房间 ID(字符串类型)
// 如果使用数字类型房间 ID:
// trtcParams.roomId = 123456;

// 进入房间
// TRTC_APP_SCENE_VIDEOCALL: 视频通话场景(类似 Twilio P2P Room)
// TRTC_APP_SCENE_LIVE: 直播场景(类似 Twilio Group Room)
mCloud.enterRoom(trtcParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE);
// 配置进房参数
val trtcParams = TRTCCloudDef.TRTCParams().apply {
sdkAppId = 2000000000 // 您的 SDKAppID
userId = "user_id" // 用户 ID
userSig = "user_sig" // 用户签名
role = TRTCCloudDef.TRTCRoleAudience // 用户进房角色
strRoomId = "my-room" // 房间 ID(字符串类型)
// 如果使用数字类型房间 ID:
// roomId = 123456
}

// 进入房间
// TRTC_APP_SCENE_VIDEOCALL: 视频通话场景(类似 Twilio P2P Room)
// TRTC_APP_SCENE_LIVE: 直播场景(类似 Twilio Group Room)
mCloud.enterRoom(trtcParams, TRTCCloudDef.TRTC_APP_SCENE_LIVE)
说明:
Twilio Peer-to-Peer Room:TRTC TRTC_APP_SCENE_VIDEOCALL (视频通话) 或 TRTC_APP_SCENE_AUDIOCALL (语音通话)
Twilio Group Room:TRTC TRTC_APP_SCENE_LIVE (互动直播) 或 TRTC_APP_SCENE_VOICE_CHATROOM (语音聊天室)

步骤7. 采集发布本地音视频流

Twilio Video

// --- 本地视频 ---
// 创建摄像头采集器
CameraCapturer cameraCapturer = new CameraCapturer(context,
CameraCapturer.CameraSource.FRONT_CAMERA);
// 创建本地视频轨道
LocalVideoTrack localVideoTrack = LocalVideoTrack.create(context, true, cameraCapturer);
// 渲染到视图
VideoView localVideoView = findViewById(R.id.local_video_view);
localVideoTrack.addSink(localVideoView);

// --- 本地音频 ---
LocalAudioTrack localAudioTrack = LocalAudioTrack.create(context, true);

// --- 发布轨道(方式一:连接时发布)---
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
.roomName("my-room")
.audioTracks(Collections.singletonList(localAudioTrack))
.videoTracks(Collections.singletonList(localVideoTrack))
.build();
Room room = Video.connect(context, connectOptions, roomListener);

// --- 发布轨道(方式二:连接后动态发布)---
room.getLocalParticipant().publishTrack(localVideoTrack);
room.getLocalParticipant().publishTrack(localAudioTrack);

Tencent RTC Engine

Java
Kotlin
// --- 本地视频 ---
// XML 布局中使用 TXCloudVideoView
// <com.tencent.rtmp.ui.TXCloudVideoView
// android:id="@+id/local_video_view"
// android:layout_width="match_parent"
// android:layout_height="match_parent" />

TXCloudVideoView localVideoView = findViewById(R.id.local_video_view);

// 设置本地渲染参数
TRTCCloudDef.TRTCRenderParams renderParams = new TRTCCloudDef.TRTCRenderParams();
renderParams.fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL;
renderParams.mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_AUTO;
mCloud.setLocalRenderParams(renderParams);

// 开启本地摄像头预览(true = 前置摄像头)
mCloud.startLocalPreview(true, localVideoView);

// --- 本地音频 ---
// 开启本地音频采集和发布
// TRTC_AUDIO_QUALITY_SPEECH: 语音模式
// TRTC_AUDIO_QUALITY_DEFAULT: 默认模式
// TRTC_AUDIO_QUALITY_MUSIC: 音乐模式
mCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT);
// --- 本地视频 ---
val localVideoView: TXCloudVideoView = findViewById(R.id.local_video_view)

// 设置本地渲染参数
val renderParams = TRTCCloudDef.TRTCRenderParams().apply {
fillMode = TRTCCloudDef.TRTC_VIDEO_RENDER_MODE_FILL
mirrorType = TRTCCloudDef.TRTC_VIDEO_MIRROR_TYPE_AUTO
}
mCloud.setLocalRenderParams(renderParams)

// 开启本地摄像头预览(true = 前置摄像头)
mCloud.startLocalPreview(true, localVideoView)

// --- 本地音频 ---
// 开启本地音频采集和发布
mCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_DEFAULT)
说明:
Twilio Video 在创建本地 Track 时需要权限,Tencent RTC Engine 在调用 startLocalPreview / startLocalAudio 时需要权限,Android 平台下均需提前手动申请运行时权限(CAMERA、RECORD_AUDIO)。

步骤8. 订阅并播放远端音视频流

Twilio Video

// 为远端参与者设置监听器
remoteParticipant.setListener(new RemoteParticipant.Listener() {
@Override
public void onVideoTrackSubscribed(RemoteParticipant remoteParticipant,
RemoteVideoTrackPublication remoteVideoTrackPublication,
RemoteVideoTrack remoteVideoTrack) {
// 远端视频轨道已订阅,添加渲染器
VideoView remoteVideoView = findViewById(R.id.remote_video_view);
remoteVideoTrack.addSink(remoteVideoView);
}

@Override
public void onVideoTrackUnsubscribed(RemoteParticipant remoteParticipant,
RemoteVideoTrackPublication remoteVideoTrackPublication,
RemoteVideoTrack remoteVideoTrack) {
// 远端视频轨道取消订阅,移除渲染器
remoteVideoTrack.removeSink(remoteVideoView);
}

@Override
public void onAudioTrackSubscribed(RemoteParticipant remoteParticipant,
RemoteAudioTrackPublication remoteAudioTrackPublication,
RemoteAudioTrack remoteAudioTrack) {
// 远端音频轨道已订阅(自动播放)
}

// ... 其他回调方法
});

Tencent RTC Engine

Java
Kotlin
@Override
public void onUserVideoAvailable(String userId, boolean available) {
if (available) {
// 远端用户开始发布视频,开始渲染
TXCloudVideoView remoteVideoView = findViewById(R.id.remote_video_view);
mCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG,
remoteVideoView);
} else {
// 远端用户停止发布视频,停止渲染
mCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
}
}

@Override
public void onUserAudioAvailable(String userId, boolean available) {
// 远端音频默认自动播放,无需手动处理
// 如需静音某远端用户:
// mCloud.muteRemoteAudio(userId, true);
}
override fun onUserVideoAvailable(userId: String?, available: Boolean) {
if (available) {
// 远端用户开始发布视频,开始渲染
val remoteVideoView: TXCloudVideoView = findViewById(R.id.remote_video_view)
mCloud.startRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG,
remoteVideoView)
} else {
// 远端用户停止发布视频,停止渲染
mCloud.stopRemoteView(userId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG)
}
}

override fun onUserAudioAvailable(userId: String?, available: Boolean) {
// 远端音频默认自动播放,无需手动处理
// 如需静音某远端用户:
// mCloud.muteRemoteAudio(userId, true)
}

步骤9. 静音/取消静音本地音视频

Twilio Video

// 静音/取消静音本地音频
localAudioTrack.enable(false); // 静音
localAudioTrack.enable(true); // 取消静音

// 暂停/恢复本地视频
localVideoTrack.enable(false); // 暂停视频
localVideoTrack.enable(true); // 恢复视频

Tencent RTC Engine

Java
Kotlin
// 静音/取消静音本地音频
mCloud.muteLocalAudio(true); // 静音
mCloud.muteLocalAudio(false); // 取消静音

// 暂停/恢复本地视频
mCloud.muteLocalVideo(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, true); // 暂停
mCloud.muteLocalVideo(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, false); // 恢复

// 通过 stopLocalPreview/startLocalPreview 完全停止/重启摄像头
mCloud.stopLocalPreview(); // 完全停止摄像头
// 静音/取消静音本地音频
mCloud.muteLocalAudio(true) // 静音
mCloud.muteLocalAudio(false) // 取消静音

// 暂停/恢复本地视频
mCloud.muteLocalVideo(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, true) // 暂停
mCloud.muteLocalVideo(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, false) // 恢复

// 通过 stopLocalPreview/startLocalPreview 完全停止/重启摄像头
mCloud.stopLocalPreview() // 完全停止摄像头

步骤10. 静音/取消静音远端音视频

Twilio Video

// Twilio 不提供直接静音远端用户的 API
// 需要通过取消订阅远端轨道来实现
// 取消订阅远端音频
remoteAudioTrackPublication.getRemoteAudioTrack().setPlaybackEnabled(false);
// 取消订阅远端视频
remoteVideoTrack.removeSink(remoteVideoView);

Tencent RTC Engine

Java
Kotlin
// 静音/取消静音指定远端用户的音频
mCloud.muteRemoteAudio("remote_user_id", true); // 静音远端用户
mCloud.muteRemoteAudio("remote_user_id", false); // 取消静音远端用户

// 静音/取消静音所有远端用户的音频
mCloud.muteAllRemoteAudio(true); // 静音所有远端用户
mCloud.muteAllRemoteAudio(false); // 取消静音所有远端用户

// 暂停/恢复指定远端用户的视频
mCloud.muteRemoteVideoStream("remote_user_id",
TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, true); // 暂停远端视频
mCloud.muteRemoteVideoStream("remote_user_id",
TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, false); // 恢复远端视频

// 暂停/恢复所有远端用户的视频
mCloud.muteAllRemoteVideoStreams(true); // 暂停所有远端视频
mCloud.muteAllRemoteVideoStreams(false); // 恢复所有远端视频
// 静音/取消静音指定远端用户的音频
mCloud.muteRemoteAudio("remote_user_id", true) // 静音远端用户
mCloud.muteRemoteAudio("remote_user_id", false) // 取消静音远端用户

// 静音/取消静音所有远端用户的音频
mCloud.muteAllRemoteAudio(true) // 静音所有远端用户
mCloud.muteAllRemoteAudio(false) // 取消静音所有远端用户

// 暂停/恢复指定远端用户的视频
mCloud.muteRemoteVideoStream("remote_user_id",
TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, true) // 暂停远端视频
mCloud.muteRemoteVideoStream("remote_user_id",
TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, false) // 恢复远端视频

// 暂停/恢复所有远端用户的视频
mCloud.muteAllRemoteVideoStreams(true) // 暂停所有远端视频
mCloud.muteAllRemoteVideoStreams(false) // 恢复所有远端视频

步骤11. 退出房间

Twilio Video

// 断开房间连接
room.disconnect();

// 释放本地轨道资源
if (localAudioTrack != null) {
localAudioTrack.release();
localAudioTrack = null;
}
if (localVideoTrack != null) {
localVideoTrack.release();
localVideoTrack = null;
}

Tencent RTC Engine

Java
Kotlin
// 停止本地音视频采集
mCloud.stopLocalAudio();
mCloud.stopLocalPreview();

// 退出房间
mCloud.exitRoom();

// 如果确定不再使用 SDK,可以销毁实例
TRTCCloud.destroySharedInstance();
// 停止本地音视频采集
mCloud.stopLocalAudio()
mCloud.stopLocalPreview()

// 退出房间
mCloud.exitRoom()

// 如果确定不再使用 SDK,可以销毁实例
TRTCCloud.destroySharedInstance()

进阶功能

屏幕分享

Twilio Video

// 创建屏幕采集器(需要 MediaProjection 权限)
ScreenCapturer screenCapturer = new ScreenCapturer(context, resultCode, data,
new ScreenCapturer.Listener() {
@Override
public void onScreenCaptureError(String errorDescription) {
Log.e("Twilio", "Screen capture error: " + errorDescription);
}

@Override
public void onFirstFrameAvailable() {
Log.i("Twilio", "First frame available");
}
});

// 创建本地视频轨道用于屏幕分享
LocalVideoTrack screenTrack = LocalVideoTrack.create(context, true, screenCapturer);

// 发布屏幕分享轨道
room.getLocalParticipant().publishTrack(screenTrack);

Tencent RTC Engine

Java
Kotlin
// 设置屏幕分享的编码参数
TRTCCloudDef.TRTCVideoEncParam encParam = new TRTCCloudDef.TRTCVideoEncParam();
encParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_1280_720;
encParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;
encParam.videoFps = 10;
encParam.videoBitrate = 1200;
encParam.enableAdjustRes = false;

// 启动屏幕分享(需要悬浮窗权限和 MediaProjection 权限)
TRTCCloudDef.TRTCScreenShareParams screenShareParams =
new TRTCCloudDef.TRTCScreenShareParams();
// 使用辅路(Sub Stream)发送屏幕分享流,不占用摄像头主路
mCloud.startScreenCapture(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB, encParam,
screenShareParams);

// 停止屏幕分享
mCloud.stopScreenCapture();
// 设置屏幕分享的编码参数
val encParam = TRTCCloudDef.TRTCVideoEncParam().apply {
videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_1280_720
videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT
videoFps = 10
videoBitrate = 1200
enableAdjustRes = false
}

// 启动屏幕分享(需要悬浮窗权限和 MediaProjection 权限)
val screenShareParams = TRTCCloudDef.TRTCScreenShareParams()
// 使用辅路(Sub Stream)发送屏幕分享流,不占用摄像头主路
mCloud.startScreenCapture(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_SUB, encParam,
screenShareParams)

// 停止屏幕分享
mCloud.stopScreenCapture()

音视频编码配置

Twilio Video

// 设置编码参数
EncodingParameters encodingParameters = new EncodingParameters(
16, // 音频最大比特率 (kbps)
800 // 视频最大比特率 (kbps)
);

ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
.roomName("my-room")
.encodingParameters(encodingParameters)
.preferVideoCodecs(Collections.singletonList(new H264Codec()))
.preferAudioCodecs(Collections.singletonList(new OpusCodec()))
.build();

Tencent RTC Engine

Java
Kotlin
// 设置视频编码参数
TRTCCloudDef.TRTCVideoEncParam videoEncParam = new TRTCCloudDef.TRTCVideoEncParam();
videoEncParam.videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_640_360;
videoEncParam.videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT;
videoEncParam.videoFps = 15;
videoEncParam.videoBitrate = 800;
videoEncParam.minVideoBitrate = 200;
mCloud.setVideoEncoderParam(videoEncParam);

// 设置网络质量控制参数
TRTCCloudDef.TRTCNetworkQosParam qosParam = new TRTCCloudDef.TRTCNetworkQosParam();
qosParam.preference = TRTCCloudDef.TRTC_VIDEO_QOS_PREFERENCE_SMOOTH; // 流畅优先
// 或 TRTCCloudDef.TRTC_VIDEO_QOS_PREFERENCE_CLEAR 清晰优先
mCloud.setNetworkQosParam(qosParam);
// 设置视频编码参数
val videoEncParam = TRTCCloudDef.TRTCVideoEncParam().apply {
videoResolution = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_640_360
videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAIT
videoFps = 15
videoBitrate = 800
minVideoBitrate = 200
}
mCloud.setVideoEncoderParam(videoEncParam)

// 设置网络质量控制参数
val qosParam = TRTCCloudDef.TRTCNetworkQosParam().apply {
preference = TRTCCloudDef.TRTC_VIDEO_QOS_PREFERENCE_SMOOTH // 流畅优先
// 或 TRTCCloudDef.TRTC_VIDEO_QOS_PREFERENCE_CLEAR 清晰优先
}
mCloud.setNetworkQosParam(qosParam)

设备管理

Twilio Video

// 切换前后摄像头
CameraCapturer cameraCapturer = (CameraCapturer) localVideoTrack.getVideoCapturer();
cameraCapturer.switchCamera();

Tencent RTC Engine

Java
Kotlin
// 获取设备管理器
TXDeviceManager deviceManager = mCloud.getDeviceManager();

// 切换前后摄像头
deviceManager.switchCamera(true);

// 判断当前是否为前置摄像头
boolean isFront = deviceManager.isFrontCamera();

// 设置摄像头缩放
deviceManager.setCameraZoomRatio(2.0f);

// 开启/关闭闪光灯
deviceManager.enableCameraTorch(true);

// 开启自动对焦
deviceManager.enableCameraAutoFocus(true);

// 设置音频路由(听筒/扬声器)
deviceManager.setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteSpeakerphone); // 扬声器
deviceManager.setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteEarpiece); // 听筒
// 获取设备管理器
val deviceManager = mCloud.deviceManager

// 切换前后摄像头
deviceManager.switchCamera(true)

// 判断当前是否为前置摄像头
val isFront = deviceManager.isFrontCamera

// 设置摄像头缩放
deviceManager.setCameraZoomRatio(2.0f)

// 开启/关闭闪光灯
deviceManager.enableCameraTorch(true)

// 开启自动对焦
deviceManager.enableCameraAutoFocus(true)

// 设置音频路由
deviceManager.setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteSpeakerphone) // 扬声器
deviceManager.setAudioRoute(TXDeviceManager.TXAudioRoute.TXAudioRouteEarpiece) // 听筒

网络质量监控

Twilio Video

// 通过 ConnectOptions 启用网络质量 API
ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken)
.roomName("my-room")
.enableNetworkQuality(true)
.build();

// 获取网络质量等级
NetworkQualityLevel level = localParticipant.getNetworkQualityLevel();

Tencent RTC Engine

Java
Kotlin
// 网络质量回调
@Override
public void onNetworkQuality(TRTCCloudDef.TRTCQuality localQuality,
ArrayList<TRTCCloudDef.TRTCQuality> remoteQuality) {
// localQuality.quality 取值:
// 0-未知 1-极好 2-好 3-一般 4-差 5-极差 6-断开
Log.i("TRTC", "本地网络质量: " + localQuality.quality);
for (TRTCCloudDef.TRTCQuality quality : remoteQuality) {
Log.i("TRTC", "用户 " + quality.userId + " 网络质量: " + quality.quality);
}
}

// 音视频统计信息回调
@Override
public void onStatistics(TRTCStatistics statistics) {
// 包含上行/下行码率、帧率、延迟等详细统计
Log.i("TRTC", "上行丢包率: " + statistics.upLoss + "%");
Log.i("TRTC", "下行丢包率: " + statistics.downLoss + "%");
Log.i("TRTC", "RTT: " + statistics.rtt + "ms");
}
// 网络质量回调
override fun onNetworkQuality(
localQuality: TRTCCloudDef.TRTCQuality?,
remoteQuality: ArrayList<TRTCCloudDef.TRTCQuality>?
) {
// localQuality.quality 取值:
// 0-未知 1-极好 2-好 3-一般 4-差 5-极差 6-断开
Log.i("TRTC", "本地网络质量: ${localQuality?.quality}")
remoteQuality?.forEach { quality ->
Log.i("TRTC", "用户 ${quality.userId} 网络质量: ${quality.quality}")
}
}

// 音视频统计信息回调
override fun onStatistics(statistics: TRTCStatistics?) {
// 包含上行/下行码率、帧率、延迟等详细统计
Log.i("TRTC", "上行丢包率: ${statistics?.upLoss}%")
Log.i("TRTC", "下行丢包率: ${statistics?.downLoss}%")
Log.i("TRTC", "RTT: ${statistics?.rtt}ms")
}

自定义视频采集

Twilio Video

// 实现 VideoCapturer 接口
public class CustomCapturer implements VideoCapturer {
@Override
public void initialize(SurfaceTextureHelper surfaceTextureHelper,
Context context, CapturerObserver observer) {
// 初始化
}

@Override
public void startCapture(int width, int height, int framerate) {
// 开始采集
}

@Override
public void stopCapture() {
// 停止采集
}

@Override
public boolean isScreencast() {
return false;
}
}

// 使用自定义采集器
LocalVideoTrack customTrack = LocalVideoTrack.create(context, true, customCapturer);

Tencent RTC Engine

Java
Kotlin
// 启用自定义视频采集
mCloud.enableCustomVideoCapture(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, true);

// 向 SDK 发送自定义采集的视频帧
// Android 平台有 Buffer 和 Texture 两种方案,此处以 Texture 方案为例,推荐!
TRTCCloudDef.TRTCVideoFrame frame = new TRTCCloudDef.TRTCVideoFrame();
frame.pixelFormat = TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_Texture_2D;
frame.bufferType = TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_TEXTURE;
frame.texture = new TRTCCloudDef.TRTCTexture();
frame.texture.textureId = textureId;
frame.texture.eglContext14 = eglContext;
frame.width = width;
frame.height = height;
frame.timestamp = timestamp;

mCloud.sendCustomVideoData(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, frame);
// 启用自定义视频采集
mCloud.enableCustomVideoCapture(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, true)

// 向 SDK 发送自定义采集的视频帧
// Android 平台有 Buffer 和 Texture 两种方案,此处以 Texture 方案为例,推荐!
val frame = TRTCCloudDef.TRTCVideoFrame().apply {
pixelFormat = TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_Texture_2D
bufferType = TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_TEXTURE
texture = TRTCCloudDef.TRTCTexture().apply {
textureId = textureId
eglContext14 = eglContext
}
width = width
height = height
timestamp = timestamp
}

mCloud.sendCustomVideoData(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG, frame)

数据通道/自定义消息

Twilio Video

// 创建数据轨道
LocalDataTrack localDataTrack = LocalDataTrack.create(context);

// 发布数据轨道
room.getLocalParticipant().publishTrack(localDataTrack);

// 发送消息
localDataTrack.send("Hello, World!");
localDataTrack.send(ByteBuffer.wrap(new byte[]{0x01, 0x02}));

// 接收消息(通过 RemoteDataTrack.Listener)
remoteDataTrack.setListener(new RemoteDataTrack.Listener() {
@Override
public void onMessage(RemoteDataTrack remoteDataTrack, String message) {
Log.i("Twilio", "Received: " + message);
}

@Override
public void onMessage(RemoteDataTrack remoteDataTrack, ByteBuffer message) {
Log.i("Twilio", "Received binary data");
}
});

Tencent RTC Engine

Java
Kotlin
// 方式一:使用 UDP 通道发送自定义命令消息
// cmdID: 1-10 之间的自定义命令 ID
// data: 消息内容(最大 1KB)
// reliable: 是否可靠发送
// ordered: 是否按序发送
boolean success = mCloud.sendCustomCmdMsg(1, "Hello, World!".getBytes(), true, true);

// 方式二:使用 SEI 通道发送消息(嵌入视频帧中)
// 参数2: repeatCount - 发送数据次数,推荐设为 1
mCloud.sendSEIMsg("Hello via SEI".getBytes(), 1);

// 接收自定义消息
@Override
public void onRecvCustomCmdMsg(String userId, int cmdID, int seq, byte[] message) {
String msg = new String(message);
Log.i("TRTC", "收到来自 " + userId + " 的消息: " + msg);
}

@Override
public void onRecvSEIMsg(String userId, byte[] data) {
String msg = new String(data);
Log.i("TRTC", "收到来自 " + userId + " 的 SEI 消息: " + msg);
}
// 方式一:使用 UDP 通道发送自定义命令消息
// cmdID: 1-10 之间的自定义命令 ID
// data: 消息内容(最大 1KB)
// reliable: 是否可靠发送
// ordered: 是否按序发送
val success = mCloud.sendCustomCmdMsg(1, "Hello, World!".toByteArray(), true, true)

// 方式二:使用 SEI 通道发送消息(嵌入视频帧中)
// 参数2: repeatCount - 发送数据次数,推荐设为 1
mCloud.sendSEIMsg("Hello via SEI".toByteArray(), 1)

// 接收自定义消息
override fun onRecvCustomCmdMsg(userId: String?, cmdID: Int, seq: Int, message: ByteArray?) {
val msg = message?.let { String(it) }
Log.i("TRTC", "收到来自 $userId 的消息: $msg")
}

override fun onRecvSEIMsg(userId: String?, data: ByteArray?) {
val msg = data?.let { String(it) }
Log.i("TRTC", "收到来自 $userId 的 SEI 消息: $msg")
}

常见问题

Twilio Video 的 Access Token 和 TRTC 的 UserSig 有什么区别?

两者都是用于客户端鉴权的时效性签名凭证,但生成方式不同:
Twilio Access Token:使用 Account SID、API Key SID 和 API Key Secret,通过 Twilio 的 SDK helper libraries 在服务端生成。
TRTC UserSig:使用 SDKAppID 和 SDKSecretKey,通过 HMAC SHA256 算法在服务端生成。

Twilio 的 Room Name(字符串)如何映射到 TRTC 的 Room ID?

TRTC 支持两种房间标识方式:
数字类型 Room ID (roomId):范围为 1 ~ 4294967294 的整数,推荐使用。
字符串类型 Room ID (strRoomId):长度限制 64 字节,支持字母、数字和部分特殊字符。
如果您的 Twilio 项目使用的是字符串形式的房间名称,可以直接使用 strRoomId 进行映射。
注意:
同一个 TRTC 应用中,不可混用 roomIdstrRoomId,两者互不互通。

TRTC 中远端音频为什么不需要手动订阅?

在 Twilio Video 中,远端音频需要通过 RemoteParticipant.Listener.onAudioTrackSubscribed 回调手动处理。而在 TRTC 中,远端音频在用户进入房间后会自动播放,无需任何额外操作。如需控制某个远端用户的音频播放,可以使用 muteRemoteAudio(userId, true/false) 进行静音/取消静音。

Twilio 的 P2P Room 和 Group Room 对应 TRTC 的哪些场景?

Twilio Room 类型
TRTC 应用场景
适用场景
Peer-to-Peer Room
TRTC_APP_SCENE_VIDEOCALL
1v1 视频通话。
Peer-to-Peer Room (纯语音)
TRTC_APP_SCENE_AUDIOCALL
1v1 语音通话。
Group Room
TRTC_APP_SCENE_LIVE
互动直播、多人视频会议。
Group Room (纯语音)
TRTC_APP_SCENE_VOICE_CHATROOM
语音聊天室。

在 TRTC 中如何处理重连?

TRTC SDK 内置了自动重连机制,无需开发者手动处理。当网络断开时,SDK 会自动尝试重连。您可以通过以下回调监听重连状态:
onConnectionLost():与服务器的连接断开。
onTryToReconnect():正在尝试重新连接。
onConnectionRecovery():连接已恢复。
这对应 Twilio 中的 onReconnectingonReconnected 回调。

更多问题

您可以在 API 参考 查看所有函数列表及其描述。如果您的接入和使用中遇到更多问题,请参见 其他问题