产品动态
产品近期公告
关于 TRTC Live 正式上线的公告
关于TRTC Conference 正式版上线的公告
Conference 商业化版本即将推出
关于多人音视频 Conference 开启内测公告
关于音视频通话 Call 正式版上线的公告
关于腾讯云音视频终端 SDK 播放升级及新增授权校验的公告
关于 TRTC 应用订阅套餐服务上线的相关说明
概念 | 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 核心入口类。 |
LocalAudioTrack、LocalVideoTrack。ConnectOptions.Builder 传入轨道列表来发布。RemoteParticipant.Listener 的回调来订阅。VideoSink / VideoView 来渲染视频。TRTCCloud 单例直接调用 startLocalPreview()、startLocalAudio() 来采集发布。TRTCCloudListener 的回调 + startRemoteView() 来完成。TXCloudVideoView 来渲染视频。

dependencies {implementation 'com.twilio:video-android:7.10.2'}
app/build.gradle 的 dependencies 中添加对 TRTC SDK 的依赖。dependencies {implementation 'com.tencent.liteav:LiteAVSDK_TRTC:latest.release'}
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.** { *; }
// Twilio Video 不需要显式初始化 SDK 实例// 直接通过 Video.connect() 静态方法连接房间// 可选:设置日志级别Video.setLogLevel(LogLevel.DEBUG);
// 创建 TRTCCloud 单例实例TRTCCloud mCloud = TRTCCloud.sharedInstance(getApplicationContext());
// 创建 TRTCCloud 单例实例val mCloud = TRTCCloud.sharedInstance(applicationContext)
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");}};
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 | 重连成功。 |
// 构建连接选项(不携带本地轨道,后续动态发布)ConnectOptions connectOptions = new ConnectOptions.Builder(accessToken).roomName("my-room").build();// 连接到房间(传入已定义好的 roomListener)Room room = Video.connect(context, connectOptions, roomListener);
// 配置进房参数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)
TRTC_APP_SCENE_VIDEOCALL (视频通话) 或 TRTC_APP_SCENE_AUDIOCALL (语音通话)TRTC_APP_SCENE_LIVE (互动直播) 或 TRTC_APP_SCENE_VOICE_CHATROOM (语音聊天室)// --- 本地视频 ---// 创建摄像头采集器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);
// --- 本地视频 ---// 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)
startLocalPreview / startLocalAudio 时需要权限,Android 平台下均需提前手动申请运行时权限(CAMERA、RECORD_AUDIO)。// 为远端参与者设置监听器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) {// 远端音频轨道已订阅(自动播放)}// ... 其他回调方法});
@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)}
// 静音/取消静音本地音频localAudioTrack.enable(false); // 静音localAudioTrack.enable(true); // 取消静音// 暂停/恢复本地视频localVideoTrack.enable(false); // 暂停视频localVideoTrack.enable(true); // 恢复视频
// 静音/取消静音本地音频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() // 完全停止摄像头
// Twilio 不提供直接静音远端用户的 API// 需要通过取消订阅远端轨道来实现// 取消订阅远端音频remoteAudioTrackPublication.getRemoteAudioTrack().setPlaybackEnabled(false);// 取消订阅远端视频remoteVideoTrack.removeSink(remoteVideoView);
// 静音/取消静音指定远端用户的音频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) // 恢复所有远端视频
// 断开房间连接room.disconnect();// 释放本地轨道资源if (localAudioTrack != null) {localAudioTrack.release();localAudioTrack = null;}if (localVideoTrack != null) {localVideoTrack.release();localVideoTrack = null;}
// 停止本地音视频采集mCloud.stopLocalAudio();mCloud.stopLocalPreview();// 退出房间mCloud.exitRoom();// 如果确定不再使用 SDK,可以销毁实例TRTCCloud.destroySharedInstance();
// 停止本地音视频采集mCloud.stopLocalAudio()mCloud.stopLocalPreview()// 退出房间mCloud.exitRoom()// 如果确定不再使用 SDK,可以销毁实例TRTCCloud.destroySharedInstance()
// 创建屏幕采集器(需要 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);
// 设置屏幕分享的编码参数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()
// 设置编码参数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();
// 设置视频编码参数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)
// 切换前后摄像头CameraCapturer cameraCapturer = (CameraCapturer) localVideoTrack.getVideoCapturer();cameraCapturer.switchCamera();
// 获取设备管理器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) // 听筒
// 通过 ConnectOptions 启用网络质量 APIConnectOptions connectOptions = new ConnectOptions.Builder(accessToken).roomName("my-room").enableNetworkQuality(true).build();// 获取网络质量等级NetworkQualityLevel level = localParticipant.getNetworkQualityLevel();
// 网络质量回调@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")}
// 实现 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);
// 启用自定义视频采集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)
// 创建数据轨道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");}});
// 方式一:使用 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")}
roomId):范围为 1 ~ 4294967294 的整数,推荐使用。strRoomId):长度限制 64 字节,支持字母、数字和部分特殊字符。strRoomId 进行映射。roomId 和 strRoomId,两者互不互通。RemoteParticipant.Listener.onAudioTrackSubscribed 回调手动处理。而在 TRTC 中,远端音频在用户进入房间后会自动播放,无需任何额外操作。如需控制某个远端用户的音频播放,可以使用 muteRemoteAudio(userId, true/false) 进行静音/取消静音。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 | 语音聊天室。 |
onConnectionLost():与服务器的连接断开。onTryToReconnect():正在尝试重新连接。onConnectionRecovery():连接已恢复。onReconnecting 和 onReconnected 回调。文档反馈