腾讯云 TRTC UniApp SDK 从入门到上线

我们项目需要实现康复师和患者之间的视频问诊功能。技术栈是 uni-app(Vue 3 模式),在评估了腾讯云 TUICallKit 后,发现它无法满足我们的需求,uniapp客户端开发使用限制太多,官方现成的SDK用不了,于是选择直接接入 TRTC SDK。

然后问题来了。

TRTC 的官方文档分散在好几个地方:有腾讯云官网的通用文档、有 DCloud 插件市场的简要说明、有 GitHub 上的 Demo README......。API 有 50 多个、事件有 30 多种、iOS 和 Android 的差异藏在源码的各个角落。

这篇文章就是我在项目里完整走了一遍 TRTC 集成后整理的一站式参考手册。从架构到 API 到踩坑,全部覆盖。

SDK 版本:v1.2.0 | 基于 TRTC_UniApp/Api-Example 工程分析 | 官方文档:web.sdk.qcloud.com/trtc/uniapp...


一、4 层架构:一个 API 调用到底经历了什么

理解架构是排查问题的前提。TRTC UniApp SDK 分为清晰的 4 层:

scss 复制代码
┌─────────────────────────────────────────────────────┐
│  业务页面 (.nvue)                                     │
│  调用 this.trtcCloud.enterRoom / startLocalPreview   │
├─────────────────────────────────────────────────────┤
│  TrtcCloud (lib/index.js)                            │
│  公开 API 封装层,单例模式,EventEmitter 风格          │
├─────────────────────────────────────────────────────┤
│  TrtcCloudImpl (lib/TrtcCloudImpl.js)                │
│  单例管理、参数校验、事件回调转换、原生模块桥接          │
├─────────────────────────────────────────────────────┤
│  原生插件 (uni.requireNativePlugin)                  │
│  - TRTCCloudUniPlugin-TRTCCloudImpl                  │
│  - TXAudioEffectManagerModule                        │
│  - TRTCCloudUniPlugin-TXLocalViewComponent           │
│  - TRTCCloudUniPlugin-TXRemoteViewComponent           │
├─────────────────────────────────────────────────────┤
│  腾讯云 TRTC 原生 SDK (Android/iOS)                   │
└─────────────────────────────────────────────────────┘

工程结构:

bash 复制代码
Api-Example/
├── TrtcCloud/                      # 🔴 核心 SDK 封装层
│   ├── lib/
│   │   ├── index.js                # TrtcCloud 主类(公开 API)
│   │   ├── TrtcCloudImpl.js        # 原生桥接实现
│   │   ├── TrtcDefines.js          # 所有枚举/类型定义
│   │   ├── TrtcCode.js             # 完整错误码/警告码
│   │   └── constants.js            # 平台常量
│   ├── view/
│   │   ├── TrtcLocalView.nvue      # 本地视频渲染组件
│   │   └── TrtcRemoteView.nvue     # 远端视频渲染组件
│   └── permission.js               # iOS/Android 权限工具
├── debug/
│   └── GenerateTestUserSig.js      # UserSig 生成(⚠️ 仅调试用)
└── pages/examples/                 # 13 个示例页面

二、核心 API 全景

2.1 生命周期

javascript 复制代码
import TrtcCloud from '@/TrtcCloud/lib/index';

// 创建单例(只能通过工厂方法)
const trtcCloud = TrtcCloud.createInstance();

// 销毁实例
TrtcCloud.destroyInstance();

2.2 事件系统

javascript 复制代码
// 注册事件(类 EventEmitter)
trtcCloud.on('onEnterRoom', (result) => {
  if (result > 0) console.log(`进房成功,耗时 ${result}ms`);
  else console.error(`进房失败,错误码 ${result}`);
});

trtcCloud.on('onRemoteUserEnterRoom', (userId) => {
  console.log(`用户 ${userId} 进入了房间`);
});

// 移除监听
trtcCloud.off('onEnterRoom');
trtcCloud.off('*');  // 移除所有

2.3 房间管理

方法 说明
enterRoom(params, scene) 进入房间
exitRoom() 退出房间
switchRole(role) 切换角色(主播 ↔ 观众)

进房参数 TRTCParams

javascript 复制代码
const params = {
  sdkAppId: 1400000000,      // 腾讯云应用 ID(必填)
  userId: 'user_123',        // 用户标识(必填)
  userSig: 'xxx',            // 用户签名(必填,服务端生成)
  roomId: 12345,             // 房间号(数字),与 strRoomId 二选一
  // strRoomId: 'room_abc',  // 字符串房间号(选填)
  role: TRTCRoleAnchor,      // 直播场景角色(选填)
};
trtcCloud.enterRoom(params, TRTCAppSceneVideoCall);

4 种应用场景:

场景 特点 适用
TRTCAppSceneVideoCall 0 720P/1080P,300人在线,50人同时发言 视频通话
TRTCAppSceneLIVE 1 主播<300ms延迟,十万人级别 互动直播
TRTCAppSceneAudioCall 2 48kHz 双声道 语音通话
TRTCAppSceneVoiceChatRoom 3 K歌房、FM 电台 语音聊天室

⚠️ LIVE 和 VoiceChatRoom 场景必须通过 TRTCParams.role 指定角色。

角色类型:

角色 说明
TRTCRoleAnchor(20) 主播,可上行音视频,最多 50 人
TRTCRoleAudience(21) 观众,只能观看,无人数上限

2.4 本地视频

方法 说明
startLocalPreview(front, viewId) 开启本地预览(front=true 前置摄像头)
stopLocalPreview() 停止本地预览
switchCamera(front) 切换前后摄像头

2.5 本地视频控制

方法 说明
muteLocalVideo(streamType, mute) 静音/恢复本地视频
setVideoEncoderParam(param) 设置视频编码参数
setLocalRenderParams(params) 设置本地渲染参数(旋转、填充、镜像)

视频分辨率选择:

分辨率 VideoCall 建议码率 LIVE 建议码率
480×360 400kbps 600kbps
640×360 500kbps 900kbps
960×540 850kbps 1300kbps
1280×720 1200kbps 1800kbps
1920×1080 2000kbps 3000kbps

2.6 远端视频

方法 说明
startRemoteView(userId, streamType, viewId) 开始渲染远端画面
stopRemoteView(userId, streamType) 停止渲染远端画面
setRemoteRenderParams(userId, streamType, params) 设置远端渲染参数

视频流类型:

类型 说明
TRTCVideoStreamTypeBig(0) 高清大画面(摄像头主画面)
TRTCVideoStreamTypeSmall(1) 低清小画面
TRTCVideoStreamTypeSub(2) 辅流(屏幕分享)

2.7 本地音频

方法 说明
startLocalAudio(quality) 开启本地音频采集
stopLocalAudio() 停止本地音频采集
muteLocalAudio(mute) 静音/恢复本地音频
setAudioRoute(route) 切换听筒(1) / 扬声器(0)

2.8 远端音频

方法 说明
muteRemoteAudio(userId, mute) 静音/恢复指定远端用户
muteAllRemoteAudio(mute) 静音/恢复全部远端用户
enableAudioVolumeEvaluation(interval) 开启音量回调(每 interval ms)

⚠️ enableAudioVolumeEvaluation 必须在 startLocalAudio 之前调用才生效。

2.9 屏幕分享(iOS 13+ / Android 5.0+)

方法 说明
startScreenCapture(streamType, encParams) 开始屏幕分享
stopScreenCapture() 停止屏幕分享
pauseScreenCapture() 暂停
resumeScreenCapture() 恢复

⚠️ iOS 端仅支持应用内 屏幕分享(startScreenCaptureInApp),不支持全系统分享(ReplayKit 方式)。

2.10 美颜、音效、截图、消息

方法 说明
setBeautyStyle(style) 美颜风格:光滑/自然/优图
setBeautyLevel(0-9) 美颜级别,0=关闭
startPlayMusic(musicParam) 播放背景音乐(支持本地/远端)
stopPlayMusic(id) 停止播放
snapshotVideo(userId, streamType) 视频截图(返回 base64)
sendCustomCmdMsg({cmdID, data, reliable, ordered}) 发送自定义 UDP 消息

⚠️ setBeautyLevel 必须在 setBeautyStyle 之前调用。


三、事件系统完全指南

所有事件通过 trtcCloud.on(eventName, callback) 注册。以下是完整事件列表:

3.1 核心事件

事件 参数 触发时机
onError {code, message, extraInfo} SDK 不可恢复错误
onWarning {code, message, extraInfo} 非严重警告(卡顿等)
onEnterRoom result(>0=耗时ms, <0=错误码) 进房完成
onExitRoom reason(0=主动退出, 1=被踢, 2=房间解散) 退房完成

3.2 远端用户事件

事件 参数 触发时机
onRemoteUserEnterRoom userId 远端用户进房
onRemoteUserLeaveRoom {userId, reason} 远端用户退房
onUserVideoAvailable {userId, available} 远端视频开关 ⭐
onUserAudioAvailable {userId, available} 远端音频开关
onUserSubStreamAvailable {userId, available} 辅流(屏幕分享)开关

3.3 音视频状态事件

事件 参数 触发时机
onFirstVideoFrame {userId, streamType, width, height} 首帧画面开始渲染
onFirstAudioFrame userId 首帧音频开始播放
onMicDidReady --- 麦克风就绪
onCameraDidReady --- 摄像头就绪
onUserVideoSizeChanged data[] 视频分辨率变化
onUserVoiceVolume {userVolumes[], totalVolume} 音量回调(每 interval ms)

3.4 网络与统计

事件 参数 触发时机
onNetworkQuality {localQuality, remoteQuality} 网络质量(每 2s)
onStatistics statics 对象 技术指标统计(每 2s)

3.5 屏幕分享事件

事件 参数
onScreenCaptureStarted {code, message}
onScreenCaptureStopped {code, message}
onScreenCapturePaused {code, message}
onScreenCaptureResumed {code, message}

3.6 其他事件

事件 参数 说明
onSnapshotComplete {base64Data, message} 截图完成
onRecvCustomCmdMsg {userId, cmdID, seq, message} 收到自定义消息
onStart / onPlayProgress / onComplete {id, ...} 背景音乐播放回调

四、iOS 端配置

4.1 manifest.json

json 复制代码
{
  "app-plus": {
    "distribute": {
      "ios": {
        "privacyDescription": {
          "NSCameraUsageDescription": "需要访问你的摄像头进行视频通话",
          "NSMicrophoneUsageDescription": "需要访问你的麦克风进行语音通话",
          "NSPhotoLibraryUsageDescription": "需要访问你的相册",
          "NSPhotoLibraryAddUsageDescription": "需要访问你的相册"
        }
      }
    },
    "nativePlugins": {
      "TRTCCloudUniPlugin-TRTCCloudImpl": {
        "__plugin_info__": {
          "name": "TRTCCloudUniPlugin-TRTCCloudImpl",
          "platforms": "Android,iOS"
        }
      }
    }
  }
}

4.2 iOS 权限检查

TRTC 示例提供了 5 种 iOS 权限的检测方法:

方法 检查权限 调用原生 API
judgeIosPermissionCamera() 相机 AVCaptureDevice.authorizationStatusForMediaType('vide')
judgeIosPermissionRecord() 麦克风 AVAudioSession.sharedInstance().recordPermission()
judgeIosPermissionPush() 推送通知 UIApplication.sharedApplication().currentUserNotificationSettings
judgeIosPermissionLocation() 定位 CLLocationManager.authorizationStatus()
judgeIosPermissionPhotoLibrary() 相册 PHPhotoLibrary.authorizationStatus()
javascript 复制代码
import permission from '@/TrtcCloud/permission.js';

// 使用示例
const hasCamera = permission.judgeIosPermission('camera');

// 跳转系统设置
permission.gotoAppPermissionSetting();

4.3 iOS 特别注意事项

  1. iOS 切换到后台时 硬编码器可能被系统释放,回到前台时可能短暂抛 ERR_VIDEO_ENCODE_FAIL(-1303)
  2. 屏幕分享仅支持应用内(iOS 13.0+),不支持全系统级别
  3. 视频渲染必须用 nvue 的原生组件 <trtc-local-view><trtc-remote-view>

五、Android 端配置

5.1 manifest.json 权限

json 复制代码
"android": {
  "permissions": [
    "android.permission.CAMERA",
    "android.permission.RECORD_AUDIO",
    "android.permission.INTERNET",
    "android.permission.ACCESS_NETWORK_STATE",
    "android.permission.WRITE_EXTERNAL_STORAGE",
    "android.permission.READ_EXTERNAL_STORAGE",
    "android.permission.MODIFY_AUDIO_SETTINGS"
  ],
  "autoSdkPermissions": true
}

5.2 运行时权限

javascript 复制代码
if (uni.getSystemInfoSync().platform === 'android') {
  permission.requestAndroidPermission('android.permission.RECORD_AUDIO');
  permission.requestAndroidPermission('android.permission.CAMERA');
}

5.3 注意

打自定义基座时必须勾选音频相关权限,否则音频路由切换会失效


六、标准集成流程(6 步代码模板)

javascript 复制代码
import TrtcCloud from '@/TrtcCloud/lib/index';
import { TRTCAppScene, TRTCVideoStreamType, TRTCAudioQuality } from '@/TrtcCloud/lib/TrtcDefines';
import permission from '@/TrtcCloud/permission.js';

export default {
  data() {
    return {
      trtcCloud: null,
      userId: 'user_' + Math.random().toString(36).substr(2, 9),
      remoteUserId: null,
    };
  },

  mounted() {
    // ① 创建实例
    this.trtcCloud = TrtcCloud.createInstance();

    // ② 注册事件
    this.trtcCloud.on('onEnterRoom', (result) => {
      if (result > 0) {
        console.log(`进房成功,耗时 ${result}ms`);
      } else {
        uni.showToast({ title: `进房失败: ${result}`, icon: 'none' });
      }
    });

    this.trtcCloud.on('onRemoteUserEnterRoom', (userId) => {
      this.remoteUserId = userId;
    });

    this.trtcCloud.on('onUserVideoAvailable', ({ userId, available }) => {
      if (available) {
        // 有远端视频流 → 开始渲染
        this.trtcCloud.startRemoteView(userId, TRTCVideoStreamTypeBig, userId);
      } else {
        this.trtcCloud.stopRemoteView(userId, TRTCVideoStreamTypeBig);
      }
    });

    // ③ 请求权限
    if (uni.getSystemInfoSync().platform === 'android') {
      permission.requestAndroidPermission('android.permission.RECORD_AUDIO');
      permission.requestAndroidPermission('android.permission.CAMERA');
    }
  },

  methods: {
    async startCall() {
      // ④ 进房
      const params = {
        sdkAppId: YOUR_SDK_APP_ID,
        userId: this.userId,
        roomId: 12345,
        userSig: await this.getUserSig(),   // ⚠️ 服务端获取!
      };
      this.trtcCloud.enterRoom(params, TRTCAppSceneVideoCall);
    },

    onJoinRoom() {
      // ⑤ 开启本地音视频(建议在进房成功后调用)
      this.trtcCloud.startLocalPreview(true, this.userId);
      this.trtcCloud.startLocalAudio(TRTCAudioQualityDefault);
    },

    onLeaveRoom() {
      // ⑥ 退房清理
      this.trtcCloud.stopLocalPreview();
      this.trtcCloud.stopLocalAudio();
      this.trtcCloud.exitRoom();
    },
  },

  onUnload() {
    this.trtcCloud?.off('*');
    TrtcCloud.destroyInstance();
    this.trtcCloud = null;
  },
};

七、13 个场景示例速览

官方 Demo 提供了 13 个示例页面,覆盖常见使用场景:

页面 关键 API
1v1 音视频通话 enterRoom, startLocalPreview, startRemoteView, switchCamera
多人音视频 同上 + 动态远端 View 管理
视频通话 纯视频模式
语音通话 startLocalAudio, muteLocalAudio, setAudioRoute
本地画面渲染 setLocalRenderParams(rotation, fillMode, mirrorType)
远端画面渲染 setRemoteRenderParams
本地编码设置 setVideoEncoderParam
角色切换 switchRole(Anchor/Audience)
悬浮窗本地预览 startLocalPreview + 悬浮窗布局
屏幕分享 startScreenCapture, pause/resume
视频截图 snapshotVideo → onSnapshotComplete
背景音效 startPlayMusic → onPlayProgress → onComplete
自定义消息 sendCustomCmdMsg → onRecvCustomCmdMsg

八、常见错误码速查

进房相关

错误码 含义
-3301 进入房间失败
-3316 进房参数为空
-3317 sdkAppId 错误
-3318 roomId 错误
-3319 userId 不正确
-3320 userSig 不正确
-3308 请求进房超时
-100013 服务不可用(套餐包用完/欠费)

设备相关

错误码 含义
-1301 打开摄像头失败
-1314 摄像头未授权
-1316 摄像头被占用
-1302 打开麦克风失败
-1317 麦克风未授权
-1319 麦克风被占用
-1308 开始录屏失败

UserSig 相关

错误码 含义
-70001 userSig 已过期
-70013 userId 与 userSig 不匹配
-70014 sdkAppId 与 userSig 不匹配
-70020 sdkAppId 未找到
-70052 userSig 已失效

九、踩坑记录 ⭐

这些注意事项每一条都是实战中踩出来的坑。

1. 必须用自定义基座运行

TRTC 依赖原生插件,不能直接在 HBuilder 标准基座中运行。必须打包自定义调试基座,且在真机上运行(模拟器不支持)。

2. 必须用 nvue 页面

所有视频页面必须是 .nvue 格式,<trtc-local-view><trtc-remote-view> 是原生组件,只在 nvue 中可用。

3. startLocalPreview 报 -2 错误?

原因:没有实例化本地预览的 view。解决方案:

  • 确认页面是 .nvue 文件
  • 页面必须包含 <trtc-local-view> 并绑定 viewId
  • startLocalPreview 的 viewId 参数需与组件 viewId 一致

4. 退房后必须等 onExitRoom 回调

调用 exitRoom() 后需要等待 onExitRoom 回调完成,才能再次 enterRoom,否则会出现设备被占用等异常。

5. muteLocalAudio vs stopLocalAudio

  • muteLocalAudio:发送极低码率静音包,录制兼容性好
  • stopLocalAudio:完全停止采集和发送,录制出的 MP4 可能不完整
  • 推荐用 muteLocalAudio,除非你确实不需要录制

6. setBeautyLevel 必须在 setBeautyStyle 之前

美颜级别为 0 表示关闭美颜。先设级别再设风格,顺序不能反。

7. enableAudioVolumeEvaluation 必须在 startLocalAudio 之前

否则音量回调不会生效。

8. UserSig 安全警告 ⚠️

javascript 复制代码
// ⚠️ Demo 中的 GenerateTestUserSig.js 仅用于本地调试!
// 生产环境必须在服务端生成 UserSig
// 绝对不要把 SecretKey 放在客户端代码中

9. 与 livepusher 模块冲突

uni-app 内置的 livepusher 使用 LiteAVSDK 推流版,TRTC 插件使用 LiteAVSDK_TRTC 版,两个 .aar 有类冲突。不能同时使用,必须二选一。

10. TRTC SDK vs TUICallKit

TRTC SDK TUICallKit
定位 音视频基础能力,无 UI 包含 UI 和通话逻辑
适用场景 复杂定制场景(在线问诊、视频指导) 1v1/多人标准通话
接入难度 需自行搭建业务逻辑 开箱即用

当 TUICallKit 无法满足需求时(如我们的视频问诊场景),使用 TRTC SDK 自行搭建。

11. 大小窗切换方案

同一用户使用两个 <trtc-remote-view> 绑定不同 viewId,通过 v-if 切换显示:

html 复制代码
<trtc-remote-view v-if="!isSmall" class="big-view"
  :userId="remoteUserId" viewId="remoteBigID" />
<trtc-remote-view v-if="isSmall" class="small-view"
  :userId="remoteUserId" viewId="remoteSmallID" />

12. 不支持离线 .aar 打包

仅支持 HBuilder 中通过「本地插件」或「云端插件」方式打包。


十、集成 Checklist

接入 TRTC 前,对照这个清单逐一确认:

  • 腾讯云已开通 TRTC 服务,获取 SDKAppID 和 SecretKey
  • DCloud 插件市场已导入腾讯云原生音视频插件
  • 页面使用 .nvue 格式
  • 已打包自定义调试基座
  • manifest.json 已配置 iOS 隐私描述和 Android 权限
  • 运行时权限请求已添加
  • UserSig 在生产环境由服务端生成(不在客户端拼接 SecretKey)
  • onUnload / onBackPress 中已处理实例销毁
  • 退房后等待 onExitRoom 回调再操作
  • 真机测试通过(模拟器不支持)

总结

TRTC UniApp SDK 的核心要点:

  1. 4 层架构:业务 .nvue → TrtcCloud → TrtcCloudImpl → 原生插件 → 原生 SDK
  2. 50+ API 覆盖房间管理、音视频控制、屏幕分享、美颜、截图、消息
  3. 30+ 事件 覆盖进房/退房、远端流状态、网络质量、屏幕分享、音频播放
  4. 必须 nvue + 自定义基座,标准基座和模拟器都不行
  5. UserSig 安全第一,SecretKey 永远不要出现在客户端
  6. 生命周期管理很重要,退房等回调、销毁清监听、前后台保护编码器

标签:uni-app TRTC 腾讯云 音视频 实时通信 nvue 原生插件

相关推荐
时光足迹1 小时前
uni-app 里把加密视频嵌入页面播放?我分析了 4 种方案,只有 1 种接近完美
前端·vue.js·uni-app
时光足迹1 小时前
JPush UniApp UTS 插件完全参考手册:API、事件与厂商通道一网打尽
vue.js·ios·uni-app
时光足迹2 小时前
极光推送全攻略(下):uni-app 代码实现与 iOS 排查实战
vue.js·ios·uni-app
To_OC2 小时前
万字解析《JS 语言精粹》之第五章:继承 5 大核心精髓(JS 原型核心)
前端·javascript·代码规范
时光足迹2 小时前
极光推送全攻略(上):被iOS证书折磨了三天,我写了一份前端也能看懂的避坑指南
前端·ios·uni-app
DyLatte2 小时前
AI 时代,最危险的不是被替代,而是努力不沉淀
前端·后端·程序员
mCell2 小时前
【锐评】桌面端技术营销:别拿跑分当工程判断
前端·rust·electron
柒和远方3 小时前
从一次工程审查看 AI 学习产品的边界兜底:RAG 资料链路一致性实战
前端·后端·架构
疯狂的魔鬼3 小时前
一个"懂分寸"的文本省略组件是怎样炼成的
前端·vue.js·设计