业务流程
本节汇总了1V1音视频通话中一些常见的业务流程,帮助您更好地理解整个场景的实现过程。
下图展示了1V1语音通话的序列图,其中包含呼叫、接听、通话、挂断等流程。


下图展示了1V1视频通话的序列图,其中包含呼叫、接听、通话、挂断等流程。


接入准备
步骤1:开通服务
1. 首先您需要登录 实时音视频 TRTC 控制台 创建应用,此时在 即时通信 IM 控制台 会同步自动创建一个与当前 TRTC 应用相同 SDKAppID 的 IM 体验版应用,二者账号与鉴权体系可复用。后续您可根据需要选择升级 TRTC 或 IM 应用版本,例如旗舰版可解锁更多增值功能服务。

说明:
建议创建两个应用分别用于测试环境和生产环境,首次开通 TRTC 服务可前往 试用中心 免费领取10000分钟试用时长包。
TRTC 包月套餐(入门版、基础版、尊享版、旗舰版)可以解锁不同的增值功能服务,详情可见 包月套餐说明。
2. 创建应用完毕之后,您可以在应用管理 > 应用概览栏目看到该应用的基本信息,其中需要您保管好 SDKAppID、SDK 密钥便于后续使用,同时应避免密钥泄露造成流量盗刷。

步骤2:导入 SDK
您可以通过 pub add 的方式直接集成腾讯云 IM SDK 和 TRTC SDK,或者在 pubspec.yaml 中写入的方式来集成。
flutter pub add 安装:
在终端窗口中输入如下命令(需要提前安装 Flutter 环境):
flutter pub add tencent_rtc_sdk #安装 TRTC SDKflutter pub add tencent_cloud_chat_sdk #安装 IM SDK
在 pubspec.yaml 中写入:
# 在 pubspec.yaml 中找到 dependencies 添加以下依赖dependencies:# 可在 https://pub.dev/packages/tencent_rtc_sdk 上查看 trtc sdk 的最新版本并使用tencent_rtc_sdk: "最新版本"# 可在 https://pub.dev/packages/tencent_cloud_chat_sdk 上查看 im sdk 的最新版本并使用tencent_cloud_chat_sdk: "最新版本"
此时您的 editor 或许会自动执行 flutter pub get,如果没有请您在命令行中手动输入
flutter pub get
。步骤3:工程配置
1. 需要在
/ios/Runner/Info.plist
的第一级<dict>目录下加入对相机和麦克风的权限申请:<key>NSCameraUsageDescription</key><string>授权摄像头权限才能正常视频通话</string><key>NSMicrophoneUsageDescription</key><string>授权麦克风权限才能正常语音通话</string>
2. 接着在第一级<dict>目录下添加字段
io.flutter.embedded_views_preview
,并设定值为 true。<key>io.flutter.embedded_views_preview</key><true/>
1. 在
/android/app/src/main/AndroidManifest.xml
的<manifest>目录下添加如下权限。<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.RECORD_AUDIO" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.CAMERA" /><uses-feature android:name="android.hardware.camera.autofocus" />
2. 如果您需要编译运行在 Android 平台,您还需要进行如下配置。
2.1 需要在工程的
android/app/build.gradle
文件中对应位置添加如下配置。android {.....packagingOptions {pickFirst 'lib/**/libliteavsdk.so'}buildTypes {release {......minifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}}
2.2 在工程的
android/app
目录下创建 proguard-rules.pro 文件,并在 proguard-rules.pro 文件中添加如下代码:-keep class com.tencent.** { *; }
1. 打开 .xcworkspace 工程文件后,在 Xcode 的导航栏中点击左侧的 Project Navigator,点击 Runner 并确保在编辑区域选择正确的 TARGETS。
2. 在 General 选项卡的 Frameworks, Libraries, and Embedded Content 部分添加 ScreenCaptureKit.framework。

说明:
步骤4:鉴权凭证
UserSig 是腾讯云设计的一种安全保护签名,目的是为了阻止恶意攻击者盗用您的云服务使用权。腾讯云实时音视频(TRTC)、即时通信(IM)服务都采用了该套安全保护机制,TRTC 在进房时鉴权,IM 在登录时鉴权。
正式运行阶段:推荐安全等级更高的服务端计算 UserSig 方案,防止客户端被逆向破解泄露密钥。
具体实现流程如下:
1. 您的 App 在调用 SDK 的初始化函数之前,首先要向您的服务器请求 UserSig。
2. 您的服务器根据 SDKAppID 和 UserID 计算 UserSig。
3. 服务器将计算好的 UserSig 返回给您的 App。
4. 您的 App 将获得的 UserSig 通过特定 API 传递给 SDK。
5. SDK 将 SDKAppID + UserID + UserSig 提交给腾讯云服务器进行校验。
6. 腾讯云校验 UserSig,确认合法性。
7. 校验通过后,会向 IM SDK 提供即时通信服务、TRTC SDK 提供实时音视频服务。


注意:
调试跑通阶段的本地 UserSig 计算方式不推荐应用到线上环境,容易被逆向破解导致密钥泄露。
我们提供了多个语言版本(Java/GO/PHP/Nodejs/Python/C#/C++)的 UserSig 服务端计算源代码,详见 UserSig 计算源码。
步骤5:初始化 SDK
1. IM SDK 初始化与添加事件监听器。
// 从即时通信 IM 控制台获取应用 SDKAppID。int sdkAppID = 0;// 添加 V2TimSDKListener 的事件监听器V2TimSDKListener sdkListener = V2TimSDKListener(// SDK 初始化后会抛出一些事件,例如连接状态、登录票据过期等onConnecting: () {debugPrint("IM SDK 正在连接到腾讯云服务器");},onConnectSuccess: () {debugPrint("IM SDK 已经成功连接到腾讯云服务器");},);// 初始化 IM SDK,调用这个接口后,可以立即调用登录接口V2TimValueCallback<bool> initSDKRes =await TencentImSDKPlugin.v2TIMManager.initSDK(sdkAppID: sdkAppID, // SDKAppIDloglevel: LogLevelEnum.V2TIM_LOG_ALL, // 日志登记等级listener: sdkListener, // 事件监听器);if (initSDKRes.code == 0) {//初始化成功}// 反初始化 IM SDKV2TimCallback uninitSDKRes = await TencentImSDKPlugin.v2TIMManager.unInitSDK();if(uninitSDKRes.code == 0) {//反初始化成功}
说明:
如果您的应用生命周期跟 SDK 生命周期一致,退出应用前可以不进行反初始化。若您只在进入特定界面后才初始化 SDK,退出界面后不再使用,可以对 SDK 进行反初始化。
2. TRTC SDK 创建实例与设置事件监听器。
// 创建 TRTC 实例TRTCCloud trtcCloud = await TRTCCloud.sharedInstance();// 来自 SDK 的各类事件通知(例如:错误码、警告码、音视频状态参数等)TRTCCloudListener listener = TRTCCloudListener(// 根据需要实现对应的回调onError: (errCode, errMsg) {debugPrint("TRTC Error: $errCode, $errMsg");},onWarning: (int warningCode, String warningMsg){debugPrint("TRTC Warning: $warningCode, $warningMsg");});// 添加 TRTC 事件监听器trtcCloud.registerListener(listener);// 移除 TRTC 事件监听器trtcCloud.unRegisterListener(listener);// 销毁 TRTC 实例TRTCCloud.destroySharedInstance();
说明:
接入过程
步骤1:登录
初始化 IM SDK 后,您需要调用 SDK 登录接口验证账号身份,获得账号的功能使用权限。因此在使用其他功能之前,请务必确保登录成功,否则可能导致功能异常或不可用。如您仅需使用 TRTC 音视频服务,可忽略此步骤。
时序图

登录操作
// 登录:userID 可自定义,userSig 参考步骤1生成获取String userID = "your user id";String userSig = "userSig from your server";V2TimCallback loginRes = await TencentImSDKPlugin.v2TIMManager.login(userID: userID, userSig: userSig);if(loginRes.code == 0){// 登录成功逻辑} else {// 登出失败逻辑// 如果返回以下错误码,表示使用 UserSig 已过期,请您使用新签发的 UserSig 进行再次登录。// 1. ERR_USER_SIG_EXPIRED(6206)// 2. ERR_SVR_ACCOUNT_USERSIG_EXPIRED(70001)// 注意:其他的错误码,请不要在这里调用登录接口,避免 IM SDK 登录进入死循环。debugPrint("IM Login Error: ${loginRes.code}, ${loginRes.desc}");}
登出操作
V2TimCallback logoutRes = await TencentImSDKPlugin.v2TIMManager.logout();if(logoutRes.code == 0){// 登出成功逻辑} else {// 登出失败逻辑debugPrint("IM Login Error: ${logoutRes.code}, ${logoutRes.desc}");}
注意:
如果您想尽可能简单地接入离线推送插件,您需要使用 TIMUIKitCore 提供的 login/logout 接口登录/登出,并使用 setOfflinePushStatus 设置离线推送状态。如果您不想使用 TIMUIKitCore 提供的接口,您需要在完成登录/登出操作后,手动调用 TencentCloudChatPush 的接口 registerPush/unRegisterPush。
步骤2:呼叫
时序图

发起呼叫
1. 主叫端本地画面预览(仅视频通话,语音通话忽略此步骤)。
// 设置视频编码参数,决定远端用户看到的画面质量trtcCloud.setVideoEncoderParam(TRTCVideoEncParam(videoResolution: TRTCVideoResolution.res_960_540,videoFps: 15,videoBitrate: 850,videoResolutionMode: TRTCVideoResolutionMode.portrait));// 开启本地摄像头预览(可指定使用前置/后置摄像头进行视频采集)// viewId 用于在 Flutter 中唯一标识一个平台视图TRTCCloudVideoView(key: valueKey,onViewCreated: (viewId) {trtcCloud.startLocalPreview(isFrontCamera, viewId);},),
注意:
您可根据业务需求自行设置视频编码参数 TRTCVideoEncParam,各档位最佳分辨率、码率搭配详见 TRTCVideoResolution。
2. 主叫端发送呼叫邀请信令。
// 构造自定义数据Map<String, dynamic> jsonObject = {"cmd": "av_call","msg": {"callType": "videoCall", // 指定通话类型"roomId": generateRoomId(), // 指定 TRTC 房间号(主叫端可随机生成)}};String data = jsonEncode(jsonObject);// 发送呼叫邀请信令late String inviteId;V2TimValueCallback<String> inviteRes =await TencentImSDKPlugin.v2TIMManager.getSignalingManager().invite(invitee: invitee, data: data, timeout: timeout, onlineUserOnly: false, offlinePushInfo: offlinePushInfo);if(inviteRes.code == 0){// 发送呼叫邀请信令成功// 渲染呼叫页面,播放呼叫铃声inviteId = inviteRes.data!;} else {// 发送呼叫邀请信令失败// 提示呼叫失败,可以尝试重试}
注意:
音视频通话场景中,通常需要在邀请信令中配置离线推送信息
OfflinePushInfo
,详情请参见 离线推送消息。建议在邀请信令中设置合理的超时时间参数
timeout
,单位为秒,SDK 会进行超时检测,从而实现呼叫超时自动挂断,默认值为30秒。建议呼叫端本地保存 invite 接口返回的
V2TimValueCallback<String>
中的data(即 inviteId),便于后续针对该条邀请进行 cancel 或 modifyInvitation 等操作。3. 被叫端收到呼叫邀请通知。
// 被叫端添加信令事件监听器,收到呼叫请求, inviteID 为该条请求 ID,inviter 为主叫用户 IDTencentImSDKPlugin.v2TIMManager.getSignalingManager().addSignalingListener(listener: V2TimSignalingListener(onReceiveNewInvitation: (String inviteID, String inviter,String groupID, List<String> inviteeList, String data) {if (data.isNotEmpty) {try {dynamic jsonObject = json.decode(data);String command = jsonObject['cmd'];dynamic messageJsonObject = jsonObject['msg'];if (command == 'av_call') {String callType = messageJsonObject['callType'];String roomId = messageJsonObject['roomId'];// 渲染呼叫页面,播放呼叫铃声}} catch (e) {debugPrint(e.toString());}}}));
注意:
主叫端发起呼叫请求、被叫端收到呼叫请求时,业务侧需要自行实现呼叫页面的渲染,以及呼叫铃声的播放。
建议被叫端本地保存 onReceiveNewInvitation 回调的 inviteID,便于后续针对该条邀请进行 accept 或 reject 等操作。
4. 被叫端本地画面预览(仅视频通话,语音通话忽略此步骤)。
if (callType.equals("videoCall")) {// 设置视频编码参数,决定远端用户看到的画面质量TRTCVideoEncParam encParam = TRTCVideoEncParam(videoResolution: TRTCVideoResolution.res_960_540,videoFps: 15,videoBitrate: 850,videoResolutionMode: TRTCVideoResolutionMode.portrait);trtcCloud.setVideoEncoderParam(encParam);// 开启本地摄像头预览(可指定使用前置/后置摄像头进行视频采集)// viewId 用于在 Flutter 中唯一标识一个平台视图TRTCCloudVideoView(key: valueKey,onViewCreated: (viewId) {trtcCloud.startLocalPreview(isFrontCamera, viewId);},),}
取消呼叫
1. 主叫端取消呼叫请求。
V2TimCallback cancelRes =await TencentImSDKPlugin.v2TIMManager.getSignalingManager().cancel(inviteID: inviteID, data: data);if(cancelRes.code == 0){// 取消呼叫请求成功// 销毁呼叫页面,停止播放呼叫铃声} else {// 取消呼叫请求失败// 提示取消失败,可以尝试重试}
2. 被叫端收到取消通知。
// 被叫端信令事件监听器收到邀请取消通知V2TimSignalingListener(onInvitationCancelled: (String inviteID, String inviter, String data) {// 销毁呼叫页面,停止播放呼叫铃声});
呼叫超时
主叫端和被叫端均会收到超时通知,同时销毁呼叫页面并停止播放呼叫铃声。
// 主/被叫端信令事件监听器收到超时通知V2TimSignalingListener(onInvitationTimeout: (String inviteID, List<String> inviteeList) {// 提示呼叫超时,销毁呼叫页面,停止播放呼叫铃声});
步骤3:接听
接听信令
1. 被叫端发送同意接听信令。
V2TimCallback acceptRes = await TencentImSDKPlugin.v2TIMManager.getSignalingManager().accept(inviteID: inviteID, data: data);if(acceptRes.code == 0){// 接听成功,渲染通话页面,停止播放呼叫铃声if (callType.equals("videoCall")) {// 开始视频通话startVideoCall();} else {// 开始语音通话startAudioCall();}} else {// 接听失败,提示异常或重试}
2. 主叫端收到同意接听通知。
// 主叫端信令事件监听器收到同意接听通知V2TimSignalingListener(onInviteeAccepted: (String inviteID, String invitee, String data) {if (callType.equals("videoCall")) {// 开始视频通话startVideoCall();} else {// 开始语音通话startAudioCall();}});
语音通话
1. 主叫端和被叫端均进入同一个 TRTC 房间,开始语音通话。
void startAudioCall() {TRTCParams params = TRTCParams(sdkAppId: SDKAPPID, // TRTC应用标识, 在控制台获取userSig: USERSIG, // TRTC鉴权凭证, 在服务端生成strRoomId: roomId, // 房间号, 以字符串房间号为例userId: userId, // 用户名, 建议和IM保持同步);trtcCloud.startLocalAudio(TRTCAudioQuality.speech);trtcCloud.enterRoom(params, TRTCAppScene.audioCall);}
注意:
语音通话模式下,TRTC 进房场景需选用 TRTCAppScene.audioCall,同时无需指定进房角色 TRTCRoleType。
开始音频采集
startLocalAudio
可同时设置音质参数,语音通话模式建议采用 TRTCAudioQuality.speech。SDK 默认的自动订阅模式下,用户进入房间后,会立刻接收到该房间中的音频流,音频会自动解码播放,无需手动拉流。
2. 进房结果通知,标识通话状态。
// 标记是否正在通话中bool isOnCalling = false;// 进房结果事件回调TRTCCloudListener(onEnterRoom: (int result) {if(result > 0){isOnCalling = true;} else {isOnCalling = false;}},);
视频通话
1. 主叫端和被叫端均进入同一个 TRTC 房间,开始视频通话。
void startVideoCall() {TRTCParams params = TRTCParams(sdkAppId: SDKAPPID, // TRTC应用标识, 在控制台获取userSig: USERSIG, // TRTC鉴权凭证, 在服务端生成strRoomId: roomId, // 房间号, 以字符串房间号为例userId: userId, // 用户名, 建议和IM保持同步);trtcCloud.startLocalAudio(TRTCAudioQuality.speech);trtcCloud.enterRoom(params, TRTCAppScene.videoCall);}
注意:
视频通话模式下,TRTC 进房场景需选用 TRTCAppScene.videoCall,同时无需指定进房角色 TRTCRoleType。
开始音频采集
startLocalAudio
可同时设置音质参数,视频通话模式建议采用 TRTCAudioQuality.speech。SDK 默认的自动订阅模式下,音频会自动解码播放,视频需要手动调用
startRemoteView
拉取远端视频流渲染播放。2. 进房结果通知,标识通话状态,拉取远端视频流。
// 标记是否正在通话中bool isOnCalling = false;TRTCCloudListener(// 进房结果事件回调onEnterRoom: (int result) {if(result > 0){isOnCalling = true;} else {isOnCalling = false;}},// 拉取远端视频流onUserVideoAvailable: (String userId, bool available ) {// 远端用户发布/取消了主路视频画面if(available){// 订阅远端用户的视频流,并绑定视频渲染控件trtcCloud.startRemoteView(userId, TRTCVideoStreamType.big, viewId);} else {// 停止订阅远端用户的视频流,并释放渲染控件trtcCloud.stopRemoteView(userId, TRTCVideoStreamType.big);}},);
步骤4:拒接
时序图

主动拒接
1. 被叫端发送拒绝接听信令。
Map<String, dynamic> jsonObject = {"cmd": "av_call","msg": {"callType": "videoCall", // 指定通话类型(视频通话、语音通话)"reason": "active", // 指定拒接类型(主动拒接、忙线拒接)}};String data = jsonEncode(jsonObject);V2TimCallback rejectRes =await TencentImSDKPlugin.v2TIMManager.getSignalingManager().reject(inviteID: inviteId, data: data);if (rejectRes.code == 0) {// 拒接成功,销毁呼叫页面,停止播放呼叫铃声} else {// 拒接失败,提示异常或重试}
2. 主叫端收到拒绝接听通知。
V2TimSignalingListener(onInviteeRejected: (String inviteID, String invitee, String data) {if(data.isNotEmpty){try{dynamic jsonObject = json.decode(data);String command = jsonObject['cmd'];dynamic messageJsonObject = jsonObject['msg'];if (command == 'av_call') {String reason = messageJsonObject['reason'];if(reason == "active") {// 提示对方拒绝接听} else if (reason == "busy") {// 提示对方忙线中}// 销毁呼叫页面,停止播放呼叫铃声}} catch (e) {debugPrint(e.toString());}}});
忙线拒接
被叫端收到新的呼叫邀请,若判断本地通话状态为正在通话中,则自动忙线拒接。
V2TimSignalingListener(onReceiveNewInvitation: (String inviteID, String inviter,String groupID, List<String> inviteeList, String data) async {if(data.isNotEmpty) {try{dynamic jsonObject = json.decode(data);String command = jsonObject['cmd'];dynamic messageJsonObject = jsonObject['msg'];if (command == 'av_call' && isOnCalling) {Map<String, dynamic> jsonObject = {"cmd": "av_call","msg": {"callType": "videoCall", // 指定通话类型(视频通话、语音通话)"reason": "busy", // 指定拒接类型(主动拒接、忙线拒接)},};V2TimCallback rejectRes =await TencentImSDKPlugin.v2TIMManager.getSignalingManager().reject(inviteID: inviteId, data: data);if (rejectRes.code == 0) {// 忙线拒接成功} else {// 忙线拒接失败}}} catch (e) {print(e);}}});
注意:
步骤5:挂断
时序图

挂断通话
1. 任一端退出房间,重置本地通话状态。
void hangup() {trtcCloud.stopLocalAudio();trtcCloud.stopLocalPreview();trtcCloud.exitRoom();}TRTCCloudListener(onExitRoom: (int reason) {// 已成功退出房间并挂断通话isOncalling = false;});
2. 另一端收到远端退房通知,本地执行退房并重置通话状态。
TRTCCloudListener(// 远端退房回调onRemoteUserLeaveRoom: (String userId, int reason) {hangup();});TRTCCloudListener(onExitRoom: (int reason) {// 已成功退出房间并挂断通话isOncalling = false;});
步骤6:功能控制
打开关闭麦克风
// 打开麦克风trtcCloud.muteLocalAudio(false);// 关闭麦克风trtcCloud.muteLocalAudio(true);
打开关闭远端音频流
// 打开所有远端音频流trtcCloud.muteAllRemoteAudio(false);// 打开指定用户音频流trtcCloud.muteRemoteAudio(userId, false);// 关闭所有远端音频流trtcCloud.muteAllRemoteAudio(true);// 关闭指定用户音频流trtcCloud.muteRemoteAudio(userId, true);
打开关闭摄像头
// 打开摄像头, 指定前置或后置摄像头及渲染控件trtcCloud.startLocalPreview(frontCamera, viewId);// 关闭摄像头trtcCloud.stopLocalPreview();
听筒免提切换
// 切换听筒trtcCloud.getDeviceManager().setAudioRoute(TXAudioRoute.earpiece);// 切换免提trtcCloud.getDeviceManager().setAudioRoute(TXAudioRoute.speakerPhone);
摄像头切换
// 判断当前是否为前置摄像头bool isFrontCamera = trtcCloud.getDeviceManager().isFrontCamera();// 切换前置或后置摄像头, true: 切换为前置; false: 切换为后置trtcCloud.getDeviceManager().switchCamera(frontCamera);
高级功能
网络状态提示
音视频通话过程中,通常需要在对方网络状态较差时给予提示,从而会有通话卡顿的心理预期。
TRTCCloudListener(onNetworkQuality: (TRTCQualityInfo localQuality, List<TRTCQualityInfo> remoteQuality) {if (remoteQuality.isNotEmpty) {for (TRTCQualityInfo remoteInfo in remoteQuality) {switch (remoteInfo.quality) {case TRTCQuality.excellent:debugPrint("对方网络非常好");break;case TRTCQuality.good:debugPrint("对方网络比较好");break;case TRTCQuality.poor:debugPrint("对方网络一般");break;case TRTCQuality.bad:debugPrint("对方网络较差");break;case TRTCQuality.vBad:debugPrint("对方网络极差");break;default:debugPrint("未定义");break;}}}});
注意:
localQuality
代表本地用户网络质量评估结果,其 userId 字段为空。remoteQuality
代表远端用户网络质量评估结果,其结果受远端和本地共同影响。通话时长统计
推荐使用 TRTC 远端用户进房时间作为统计通话时长的开始时间,本地用户退房时间作为统计通话时长的结束时间。
// 开始通话时间int callStartTime = 0;// 结束通话时间int callFinishTime = 0;// 通话持续时长(秒)int callDuration = 0;// 远端用户进房回调TRTCCloudListener(onRemoteUserEnterRoom: (String userId) {callStartTime = DateTime.now().millisecondsSinceEpoch;});// 本地用户退房回调TRTCCloudListener(onExitRoom: (int reason) {callFinishTime = DateTime.now().millisecondsSinceEpoch;callDuration = ((callFinishTime - callStartTime) / 1000) as int;});
注意:
视频美颜特效
TRTC 支持接入第三方美颜特效产品,下面以腾讯特效为例,展示第三方美颜接入流程。
1. 美颜资源初始化与授权。
// 设置美颜资源存放的本地路径,使用美颜前必须先调用此方法。TencentEffectApi.getApi()?.setResourcePath(xmagicResDir);// 初始化美颜数据TencentEffectApi.getApi()?.initXmagic((result) {if (rsult == 0) {// 初始化成功}});// 美颜授权TencentEffectApi.getApi()?.setLicense(licenseKey, licenseUrl, (errorCode, msg) {if (errorCode == 0) {// 授权成功}});
2. 完成上述操作后,您可以通过 TRTC 的隐藏接口来开启/关闭美颜。
_enableCustomBeautyByNative(bool open) {trtcCloud.callExperimentalAPI("{\\"api\\": \\"enableVideoProcessByNative\\", \\"params\\": {\\"enable\\": $open}}");}
注意:
大小窗口切换
TRTC 中有很多需要操控视频画面的接口,这些接口都需要您指定视频渲染控件。在 Flutter 中,提供了
TRTCCloudVideoView
作为渲染控件,在视图创建后通过 onViewCreated
回调返回 viewId
用于标识一个视图。如果您业务涉及到切换显示区域的交互场景,可以使用 TRTC SDK 更新本地预览画面、更新远端用户视频渲染控件功能实现。
TRTCCloudVideoView(onViewCreated: (viewId) {// 保存 viewId,用来更新渲染控件localViewId = viewId;},),// 更新本地预览画面渲染控件trtcCloud.updateLocalView(localViewId);// 更新远端用户视频渲染控件trtcCloud.updateRemoteView(userId, streamType, localViewId);
注意:
streamType
仅支持 TRTCVideoStreamType.big
和 TRTCVideoStreamType.sub
。离线推送消息
发送离线推送消息
调用 invite 发送通话邀请时,您可通过 OfflinePushInfo 设置离线推送参数。在 OfflinePushInfo 中设置自定义 ext 数据(通知栏透传信息),当用户收到离线推送启动 App 的时候,可以在单击通知跳转的回调中获取到 ext 字段,然后根据 ext 字段内容跳转到指定的 UI 界面。
Map<String, dynamic> contentDetailObj = {"callType": "videoCall","roomId": generateRoomId(),};Map<String, dynamic> contentObj = {"cmd": "av_call","cmdInfo": contentDetailObj,};String jsonData = jsonEncode(contentObj);Map<String, dynamic> data = {"entity": {"content": jsonData,"sender": userId,"action": 1,"sendtime": DateTime.now().millisecondsSinceEpoch / 1000,"nickname": nickName,"faceUrl": faceUrl,}};String ext = jsonEncode(data);OfflinePushInfo offlinePushInfo = OfflinePushInfo(ext: ext,// OPPO 必须设置 ChannelID 才可以收到推送消息,这个 ChannelID 需要和控制台一致androidOPPOChannelID: "tuikit",androidHuaWeiCategory: "IM",androidVIVOCategory: "IM",title: nickName,desc: "You have a new call invitation",// 设置自定义铃声iOSSound: "phone_ringing.mp3",androidSound: "phone_ringing.mp3",);V2TimValueCallback<String> inviteRes =await TencentImSDKPlugin.v2TIMManager.getSignalingManager().invite(invitee: invitee,data: jsonData,timeout: 30,onlineUserOnly: false,offlinePushInfo: offlinePushInfo,);if(inviteRes.code == 0){// 发送呼叫邀请成功} else {// 发送呼叫邀请失败}
解析离线推送消息
当收到推送消息时,点击通知栏事件,组件会以回调的形式通知应用,应用在回调中配置 App 的跳转页面即可。注册回调时机建议放在程序入口 main() 函数中。
TIMPushListener timPushListener = TIMPushListener(onNotificationClicked: (String ext) {debugPrint("ext: $ext");// 获取 ext 自定义跳转});tencentCloudChatPush.addPushListener(listener: timPushListener);
注意:
自定义点击跳转需要在控制台添加厂商推送证书时,点击后续动作选项中选择打开应用内指定页面,插件用户会默认填写跳转参数。


异常处理
TRTC 异常错误处理
UserSig 相关
枚举 | 取值 | 描述 |
ERR_USER_SIG_INVALID | -3320 | 进房参数 userSig 不正确 |
ERR_SERVER_INFO_ECDH_GET_TINYID | -100018 | userSig 校验失败,请检查 userSig 是否正确 |
进退房相关
进房失败请先检查进房参数是否正确,且进退房接口必须成对调用,即便进房失败也需要调用退房接口。
枚举 | 取值 | 描述 |
ERR_ROOM_REQUEST_ENTER_ROOM_TIMEOUT | -3308 | 请求进房超时,请检查网络 |
ERR_SDK_APPID_INVALID | -3317 | 进房参数 sdkAppId 错误 |
ERR_ROOM_ID_INVALID | -3318 | 进房参数 roomId 错误 |
ERR_USER_ID_INVALID | -3319 | 进房参数 userID 不正确 |
设备相关
可监听设备相关错误,在出现相关错误时 UI 提示用户。
枚举 | 取值 | 描述 |
ERR_CAMERA_START_FAIL | -1301 | 打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 |
ERR_MIC_START_FAIL | -1302 | 打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 |
ERR_CAMERA_NOT_AUTHORIZED | -1314 | 摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 |
ERR_MIC_NOT_AUTHORIZED | -1317 | 麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 |
ERR_CAMERA_OCCUPY | -1316 | 摄像头正在被占用中,可尝试打开其他摄像头 |
ERR_MIC_OCCUPY | -1319 | 麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败 |
收不到离线推送排查
1. 特殊情况排查
OPPO 手机
OPPO 手机收不到推送一般有以下几种情况:
按照 OPPO 推送官网要求,在 Android 8.0及以上系统版本的 OPPO 手机上必须配置 ChannelID,否则推送消息无法展示。可以在 OfflinePushInfo 中设置
androidOPPOChannelID
字段。OPPO 安装应用通知栏显示默认关闭,需要确认下开关状态。
Google FCM
小米和 vivo
小米和 vivo:需要上架应用市场后,才可以通过厂商通道进行下发。一般会提示:应用在黑名单中,禁止发送消息。或者,该 App 已关闭 push 通道。
设备通知栏设置影响
离线推送的直观表现就是通知栏提示,所以同其他通知一样受设备通知相关设置的影响,以华为为例:
手机设置 > 通知 > 锁屏通知 > 隐藏或者不显示通知,会影响锁屏状态下离线推送通知显示。
手机设置 > 通知 > 更多通知设置 > 状态栏显示通知图标,会影响状态栏下离线推送通知的图标显示。
手机设置 > 通知 > 应用的通知管理 > 允许通知,打开关闭会直接影响离线推送通知显示。
手机设置 > 通知 > 应用的通知管理 > 通知铃声和手机设置 > 通知 > 应用的通知管理 > 静默通知,会影响离线推送通知铃音的效果。
消息分类
厂商特性
离线推送依赖厂商能力,一些简单的字符可能会被厂商过滤不能透传推送,建议使用有意义的内容进行推送。
2. 自助推送排查工具
设备推送插件接入是否正常
推送链路排查
普通消息为什么收不到离线推送?
1. 首先,请检查下 App 的运行环境和证书的环境是否一致,如果不一致,收不到离线推送。
2. 其次,检查下 App 和证书的环境是否为生产环境。如果是开发环境,向苹果申请 deviceToken 可能会失败,生产环境暂时没有发现这个问题,请切换到生产环境测试。
自定义消息为什么收不到离线推送?
自定义消息的离线推送和普通消息不太一样,自定义消息的内容我们无法解析,不能确定推送的内容,所以默认不推送,如果您有推送需求,需要您在 sendMessage 的时候设置 OfflinePushInfo 的
desc
字段,推送的时候会默认展示 desc
信息。收不到推送,且后台报错 bad devicetoken。
Apple 的 deviceToken 与当前编译环境有关,请检查:
1. 接入流程中 配置推送参数 的 businessID 是否是对应环境的证书 ID。
2. 控制台创建证书检查:
生产环境证书:上传的证书类型为 Apple Push Notification service SSL (Sandbox & Production),并在Archive 出Release 包后进行测试。注意:不可在Xcode 测试。
开发环境证书:您需要 Archive 出 release 包后进行测试,创建选择正确证书即可。
自定义跳转不成功排查
点击跳转配置检查
控制台配置点击后续动作按如下配置:选择打开应用内指定页面,插件用户会默认填写跳转参数,参数是否被修改。
注册和回调处理点击事件,注册时机建议放在应用 Application 的 onCreate() 函数中,需要放在应用生命周期的靠前位置。
点击回调处是否正确处理跳转逻辑。
设备系统权限限制
应用进程不存在,单击通知栏跳转到应用界面,需要将应用从后台拉取到前台,部分厂商系统会去检查 App 是否开启了后台自启动或悬浮窗权限,不开启系统侧会拦截处理导致失败。
不同厂商、同一厂商不同 Android 版本,其对于应用开放的权限以及权限名称会存在不一致。经测试,小米6只需要开启后台弹出界面权限,而红米需要同时打开后台弹出界面和显示悬浮窗权限,需要针对不同厂商不同处理。