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(基于轨道) 架构:
开发者需要显式创建
LocalAudioTrack、LocalVideoTrack。通过
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
// 创建 TRTCCloud 单例实例TRTCCloud mCloud = TRTCCloud.sharedInstance(getApplicationContext());
// 创建 TRTCCloud 单例实例val mCloud = TRTCCloud.sharedInstance(applicationContext)
步骤5. 设置事件监听器
Twilio Video
Room.Listener roomListener = new Room.Listener() {@Overridepublic void onConnected(Room room) {Log.i("Twilio", "Connected to " + room.getName());}@Overridepublic void onConnectFailure(Room room, TwilioException twilioException) {Log.e("Twilio", "Connect failure: " + twilioException.getMessage());}@Overridepublic void onDisconnected(Room room, TwilioException twilioException) {Log.i("Twilio", "Disconnected from " + room.getName());}@Overridepublic void onParticipantConnected(Room room, RemoteParticipant remoteParticipant) {Log.i("Twilio", "Participant connected: " + remoteParticipant.getIdentity());}@Overridepublic void onParticipantDisconnected(Room room, RemoteParticipant remoteParticipant) {Log.i("Twilio", "Participant disconnected: " + remoteParticipant.getIdentity());}@Overridepublic void onReconnecting(Room room, TwilioException twilioException) {Log.i("Twilio", "Reconnecting...");}@Overridepublic void onReconnected(Room room) {Log.i("Twilio", "Reconnected");}};
Tencent RTC Engine
TRTCCloudListener trtcListener = new TRTCCloudListener() {@Overridepublic void onEnterRoom(long result) {if (result > 0) {Log.i("TRTC", "进房成功,耗时 " + result + "ms");} else {Log.e("TRTC", "进房失败,错误码 " + result);}}@Overridepublic void onExitRoom(int reason) {// reason: 0-主动退出 1-被踢出房间 2-房间解散Log.i("TRTC", "已退出房间,原因: " + reason);}@Overridepublic void onRemoteUserEnterRoom(String userId) {Log.i("TRTC", "远端用户进入房间: " + userId);}@Overridepublic void onRemoteUserLeaveRoom(String userId, int reason) {Log.i("TRTC", "远端用户离开房间: " + userId);}@Overridepublic void onError(int errCode, String errMsg, Bundle extraInfo) {Log.e("TRTC", "错误: " + errCode + " - " + errMsg);}@Overridepublic void onConnectionLost() {Log.w("TRTC", "与服务器连接断开");}@Overridepublic void onTryToReconnect() {Log.i("TRTC", "正在尝试重新连接...");}@Overridepublic 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
// 配置进房参数TRTCCloudDef.TRTCParams trtcParams = new TRTCCloudDef.TRTCParams();trtcParams.sdkAppId = 2000000000; // 您的 SDKAppIDtrtcParams.userId = "user_id"; // 用户 IDtrtcParams.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 // 您的 SDKAppIDuserId = "user_id" // 用户 IDuserSig = "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
// --- 本地视频 ---// 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_FILLmirrorType = 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() {@Overridepublic void onVideoTrackSubscribed(RemoteParticipant remoteParticipant,RemoteVideoTrackPublication remoteVideoTrackPublication,RemoteVideoTrack remoteVideoTrack) {// 远端视频轨道已订阅,添加渲染器VideoView remoteVideoView = findViewById(R.id.remote_video_view);remoteVideoTrack.addSink(remoteVideoView);}@Overridepublic void onVideoTrackUnsubscribed(RemoteParticipant remoteParticipant,RemoteVideoTrackPublication remoteVideoTrackPublication,RemoteVideoTrack remoteVideoTrack) {// 远端视频轨道取消订阅,移除渲染器remoteVideoTrack.removeSink(remoteVideoView);}@Overridepublic void onAudioTrackSubscribed(RemoteParticipant remoteParticipant,RemoteAudioTrackPublication remoteAudioTrackPublication,RemoteAudioTrack remoteAudioTrack) {// 远端音频轨道已订阅(自动播放)}// ... 其他回调方法});
Tencent RTC Engine
@Overridepublic 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);}}@Overridepublic 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
// 静音/取消静音本地音频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
// 静音/取消静音指定远端用户的音频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
// 停止本地音视频采集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() {@Overridepublic void onScreenCaptureError(String errorDescription) {Log.e("Twilio", "Screen capture error: " + errorDescription);}@Overridepublic void onFirstFrameAvailable() {Log.i("Twilio", "First frame available");}});// 创建本地视频轨道用于屏幕分享LocalVideoTrack screenTrack = LocalVideoTrack.create(context, true, screenCapturer);// 发布屏幕分享轨道room.getLocalParticipant().publishTrack(screenTrack);
Tencent RTC Engine
// 设置屏幕分享的编码参数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_720videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAITvideoFps = 10videoBitrate = 1200enableAdjustRes = 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
// 设置视频编码参数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_360videoResolutionMode = TRTCCloudDef.TRTC_VIDEO_RESOLUTION_MODE_PORTRAITvideoFps = 15videoBitrate = 800minVideoBitrate = 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
// 获取设备管理器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 启用网络质量 APIConnectOptions connectOptions = new ConnectOptions.Builder(accessToken).roomName("my-room").enableNetworkQuality(true).build();// 获取网络质量等级NetworkQualityLevel level = localParticipant.getNetworkQualityLevel();
Tencent RTC Engine
// 网络质量回调@Overridepublic 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);}}// 音视频统计信息回调@Overridepublic 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 {@Overridepublic void initialize(SurfaceTextureHelper surfaceTextureHelper,Context context, CapturerObserver observer) {// 初始化}@Overridepublic void startCapture(int width, int height, int framerate) {// 开始采集}@Overridepublic void stopCapture() {// 停止采集}@Overridepublic boolean isScreencast() {return false;}}// 使用自定义采集器LocalVideoTrack customTrack = LocalVideoTrack.create(context, true, customCapturer);
Tencent RTC Engine
// 启用自定义视频采集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_2DbufferType = TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_TEXTUREtexture = TRTCCloudDef.TRTCTexture().apply {textureId = textureIdeglContext14 = eglContext}width = widthheight = heighttimestamp = 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() {@Overridepublic void onMessage(RemoteDataTrack remoteDataTrack, String message) {Log.i("Twilio", "Received: " + message);}@Overridepublic void onMessage(RemoteDataTrack remoteDataTrack, ByteBuffer message) {Log.i("Twilio", "Received binary data");}});
Tencent RTC Engine
// 方式一:使用 UDP 通道发送自定义命令消息// cmdID: 1-10 之间的自定义命令 ID// data: 消息内容(最大 1KB)// reliable: 是否可靠发送// ordered: 是否按序发送boolean success = mCloud.sendCustomCmdMsg(1, "Hello, World!".getBytes(), true, true);// 方式二:使用 SEI 通道发送消息(嵌入视频帧中)// 参数2: repeatCount - 发送数据次数,推荐设为 1mCloud.sendSEIMsg("Hello via SEI".getBytes(), 1);// 接收自定义消息@Overridepublic void onRecvCustomCmdMsg(String userId, int cmdID, int seq, byte[] message) {String msg = new String(message);Log.i("TRTC", "收到来自 " + userId + " 的消息: " + msg);}@Overridepublic 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 - 发送数据次数,推荐设为 1mCloud.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 应用中,不可混用
roomId 和 strRoomId,两者互不互通。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 中的
onReconnecting 和 onReconnected 回调。更多问题