Files
zyt/app/research/tencent_rtc.md
T
2026-08-10 17:29:05 +08:00

27 KiB
Raw Blame History

腾讯云 TRTC 接入 Python / PySide6 跨平台桌面视频面诊研究

调研日期:2026-08-10
范围:Windows / macOS 桌面端;Python / PySide6 业务程序;1 对 1 视频面诊,可扩展屏幕共享。
来源原则:仅使用腾讯云、Tencent RTC 官方文档与官方 SDK API 文档。文中标为“工程判断/建议”的内容是根据官方能力边界作出的架构推断,并非腾讯云对 Python 或 PySide6 的兼容性承诺。

结论摘要

  1. 腾讯云没有官方 Python 或 PySide6 TRTC 客户端 SDK。 用户指定的产品概述(文档 16788列出了 Windows、macOS、Web、Electron 等平台,没有 Python/PySide6。官方还提供了 Windows/macOS 的 C++ Qt 集成示例,但它不是 Python 绑定,也没有证明 PySide6 / Qt 6 ABI 兼容。
  2. 推荐生产架构:PySide6 保留为业务主程序,音视频做成独立 Electron RTC companion(伴随进程/独立面诊窗口),由后端签发进房票据,PySide6 与 companion 通过本机受认证 IPC 交互。 1 对 1 场景优先使用底层 trtc-electron-sdk;若要快速获得完整会议 UI、成员管理和会控,可选官方 TUIRoomKit Electron。官方明确将 TUIRoomKit Electron 用于“医疗问诊”等场景。
  3. 最快的业务 MVP 是从 PySide6 打开系统浏览器中的 HTTPS Web SDK 面诊页。 这是官方浏览器支持路径。把 Web SDK 嵌入 QWebEngineView 技术上有机会可行,但 QtWebEngine 不在腾讯的具名支持矩阵中;官方只说理论上支持 Chromium 56+,并要求对 WebView 等未列环境运行能力检测。因此,QWebEngineView 只能作为验证分支,不能在未完成双平台全量实测前作为生产承诺。
  4. 若“必须在同一 PySide6 窗口内原生渲染”是硬要求,才选择 Native C++ 桥接。 需要自行为 Windows/macOS 编译 C ABI/CPython 扩展,处理原生渲染句柄、回调线程、Qt 5/Qt 6 兼容、签名与打包;这是可落地但成本和维护风险最高的方案。
  5. 生产环境的 SDKSecretKey 只能放在服务端。 客户端仅获得短期 UserSig;需要面诊房间级与媒体权限控制时,开启 Advanced Permission Control 并由服务端签发 PrivateMapKey。房间 ID 不能视作访问控制。

方案对比

方案 官方支持边界 与 Python/PySide6 的关系 摄像头/麦克风/屏幕分享 主要风险 判断
Web SDK + 系统浏览器 官方支持 Windows/macOS 主流浏览器;生产要求 HTTPS PySide6 打开带一次性业务会话的 HTTPS 页面;无 Python SDK 绑定 官方均支持;屏幕分享受浏览器/OS 授权和用户选择器约束 独立浏览器窗口、业务 UI 一体化较弱 最快、风险低的 MVP/兜底
Web SDK + QWebEngineView 官方称理论支持 Chromium 56+,未列环境(含 WebView)需 TRTC.isSupported()/能力检测;未明确认证 QtWebEngine JS 运行在嵌入页,通过 WebChannel/IPC 与 Python 通信(工程自建) 需验证嵌入引擎的媒体权限、设备切换、屏幕选择与 macOS Screen Recording 腾讯支持边界、QtWebEngine 版本与权限行为不确定 仅作 POC;通过准入测试后才可采用
Electron SDK / TUIRoomKit Electron 官方支持 Windows/macOSSDK 是 Node 原生模块;官方提供设备权限、打包、屏幕分享和医疗问诊组件指引 Python 不能直接 import;作为独立伴随进程最清晰 完整支持,DOM 承载本地/远端画面;可用辅路同时保留摄像头与屏幕 包体较大、需维护本机 IPC、两平台分别构建签名 推荐生产方案
Native C++ SDK + 自研桥 官方全平台 C++ API、Windows/macOS SDK、C++ Qt 示例 自行写 C ABI/pybind11/CPython 桥;腾讯不提供 Python/PySide6 绑定 能力最完整,包含设备管理、测试、屏幕源枚举、原生渲染与私有加密 API C++ ABI、Qt 版本、线程、崩溃隔离、双平台构建维护 单窗口原生体验的二期方案

各方案适配判断

1. Web SDK

官方事实:

  • TRTC Web SDK 是 JavaScript SDK,视频渲染目标是 HTML 元素;通过 TRTC.create()enterRoom()startLocalAudio()startLocalVideo()startRemoteVideo()exitRoom()destroy() 完成生命周期,见Web & H5 快速接入
  • 官方平台页称理论上支持所有 Chromium 56+ 浏览器;对支持表之外的环境,建议用 TRTC.isSupported()能力检测页检测。快速 Demo 文档还特别提到 WebView 等环境应先检测,见Web Demo 准备工作Web API 概览/平台要求
  • 生产环境推流和屏幕分享要求 HTTPS;HTTP 生产页只能播放,不能上麦/屏幕分享。本地 localhost 可用于开发。
  • 设备名称和 deviceId 在获得摄像头/麦克风授权前可能为空;应先完成授权再展示设备详情。
  • 桌面 Web 支持 startScreenShare();用户可能从浏览器系统 UI 停止分享,业务必须监听分享停止事件并恢复 UI 状态,见Web 屏幕分享

对 PySide6 的工程判断:

  • 系统 Chrome/Edge/Safari 是具名支持路径,最适合快速验证服务端、UserSig、房间和媒体链路。
  • QWebEngineView 虽基于 Chromium,但不是腾讯文档具名认证平台。只有在目标 PySide6 随附的 QtWebEngine 上同时通过能力检测和真实设备测试,才能认为本项目可用。
  • 若验证嵌入方案,应把下列项目设为硬门槛:摄像头/麦克风首次授权及拒绝后恢复、设备插拔和切换、远端音频自动播放、窗口/整屏分享、从系统分享条停止、macOS Screen Recording 权限、窗口最小化/休眠恢复、打包后仍可用。
  • file:// 虽在官方表中可用,但生产仍建议加载受控 HTTPS 页面,以便版本发布、CSP、证书与安全响应集中管理。

2. Electron SDK / TUIRoomKit Electron

官方事实:

  • 当前Electron 快速接入要求 Electron 工程安装 trtc-electron-sdk,实际加载 trtc_electron_sdk.node 原生模块;支持 Windows 和 macOS,并给出了两平台不同的原生模块资源路径、摄像头/麦克风/屏幕权限检查及打包配置。
  • startLocalPreview() 的渲染目标是 HTMLElement,不是 PySide QWidgetstartLocalAudio() 可选 Speech 模式,官方说明其噪声抑制和弱网抗性更强,适合面诊语音。
  • 1 对 1 视频面诊应使用 TRTCAppSceneVideoCall,而不是直播场景。官方将 VideoCall 定位为 1 对 1 或 300 人以内实时通话。
  • TUIRoomKit Electron 接入明确列出“医疗问诊”场景,并内置房间管理、音视频控制、屏幕共享、成员管理和布局。
  • Electron 屏幕分享支持主路和辅路。辅路可在摄像头继续上行的同时分享屏幕;一个 TRTC 房间目前只能有一路屏幕分享,见Electron 屏幕分享
  • 官方 Electron API 还提供设备列表、设备切换、摄像头/麦克风/扬声器测试和网络测速;网络测速应在进房前进行,见Electron SDK API

对 PySide6 的工程判断:

  • Node 原生模块不能当作 Python 模块直接加载。把它塞进 PySide6 进程会引入 Node/Electron 运行时、DOM 渲染和 ABI 问题,不值得。
  • 独立 RTC companion 可将故障、升级和媒体权限与 Python 主进程隔离;PySide6 只负责预约、病历、支付等业务 UI,Electron 只持有当次短期票据并负责通话。
  • Windows 与 macOS 应各自在目标系统构建、签名并验证产物;不要把包含 .node/.dll/framework 的包当作纯 JS 跨平台包。
  • IPC 采用本机命名管道/Unix domain socket 或 loopback WebSocket,并以每次启动随机 nonce 双向认证;不要把 UserSig 放在命令行参数、URL 查询串或长期日志中。此为工程安全建议,不是腾讯 SDK 的内置保证。

3. Native C++ SDK 与 Qt 桥接

官方事实:

  • 全平台 C++ API 概览包含实例/回调、进退房、摄像头和远端渲染、音频、设备管理、屏幕分享、网络质量、连接恢复及私有加密等完整能力。
  • 腾讯提供Qt Windows/macOS 集成文档Windows 使用 C++ SDK 的 liteav.lib/DLLmacOS 引用 TXLiteAVSDK_TRTC_Mac.framework 的 C++ 接口。示例是 Qt Widgets/C++macOS 文档写的是 Qt 5.10+。
  • macOS 需要在 Info.plist 声明摄像头和麦克风权限;官方 Electron 指引另外检查 screen 权限。
  • C++ API 可枚举/切换设备并运行摄像头、麦克风和扬声器测试;屏幕分享可枚举窗口/屏幕、选择目标、设置辅路参数及包含/排除窗口。

对 PySide6 的工程判断:

  • PySide6 使用 Qt 6,而官方 Qt 示例仍以 Qt 5 为基线,不能把“支持 C++ Qt”直接等同于“支持 PySide6”。
  • 若采用,推荐制作很薄的 C ABI 桥,不要让 Python 直接调用 C++ ABI:桥内持有 ITRTCCloud、回调对象和 SDK 生命周期,只向 Python 暴露稳定的 opaque handle、进退房、设备、屏幕分享和事件队列。
  • 视频尽量由 SDK 绑定原生子窗口/视图句柄渲染;不要默认把每帧 YUV 回调到 Python,这会显著增加跨语言复制、GIL 和掉帧风险。
  • SDK 回调可能不在 Qt UI 线程,桥层必须投递到 PySide6 主线程;退出时顺序应固定为停止屏幕分享/本地采集/远端渲染、exitRoom、等待退房回调、移除回调、销毁实例。
  • 该路线必须先验证 Qt 版本和原生窗口句柄,且建议在正式承诺前向腾讯云提交工单确认目标 SDK 版本的 Qt 6/PySide 嵌入边界。

推荐生产架构

┌──────────────────────┐        HTTPS         ┌────────────────────────┐
│ PySide6 业务主程序    │ ───────────────────▶ │ 业务后端 / RTC Ticket   │
│ 预约、病历、面诊入口  │                      │ 鉴权、预约授权、UserSig  │
└──────────┬───────────┘                      │ PrivateMapKey、结束房间  │
           │ 本机受认证 IPC                    └────────────┬───────────┘
           ▼                                               │ TRTC REST / callback
┌──────────────────────┐                      ┌─────────────▼──────────┐
│ Electron RTC companion│ ◀──── RTC 媒体 ────▶ │ 腾讯云 TRTC             │
│ 设备、视频、屏幕分享  │                      └────────────────────────┘
└──────────────────────┘

组件职责

PySide6 主程序

  • 只传预约 ID/面诊动作,不生成或持久化 SDKSecretKey。
  • 调用业务后端获取本次短期进房票据,启动/聚焦 RTC companion。
  • 展示 companion 回传的 preflight / joining / connected / reconnecting / ended / error 状态。
  • 业务“面诊已结束”不能只依赖窗口关闭事件,应由客户端结果、TRTC 服务端回调和后端结束动作共同收敛。

业务后端 / RTC Ticket 服务

  • 验证当前登录用户确实是该预约的医生或患者,并验证允许进房的时间窗和预约状态。
  • 服务端派生 userIdroomId,生成 UserSig;启用高级权限控制时同时生成 PrivateMapKey
  • 返回最小票据:sdkAppIduserId、一种且仅一种 room ID、userSigexpiresAt、可选 privateMapKey、业务角色与 UI 权限。SDKSecretKey 永不返回。
  • 提供“结束面诊”接口;需要强制结束时调用官方 DismissRoom/DismissRoomByStrRoomId,见解散房间 API
  • 接收房间/媒体回调,校验签名并幂等处理。

Electron RTC companion

  • 使用底层 trtc-electron-sdk 完成 1 对 1 VideoCall;若需求接近完整会议产品,则用 TUIRoomKit Electron。
  • 不保存长期登录态或云密钥;窗口关闭、崩溃和正常退房均向 PySide6/后端报告。
  • 所有摄像头、麦克风和屏幕分享都由用户明确操作开启,并在界面持续显示状态。

UserSig 与房间权限

UserSig

  • 官方用户鉴权文档明确指出:客户端计算 UserSig 只适合 Demo。客户端代码,尤其 Web,容易被反编译;泄露 SDKSecretKey 会导致腾讯云资源被盗用。
  • 正式环境流程必须是:客户端先向业务服务器请求;服务器按 SDKAppID + UserID 生成 UserSig;客户端仅把结果交给 SDK。官方提供 Python HMAC-SHA256 服务端示例,因此 Python 后端生成完全可行。
  • 建议把 UserSig 有效期控制为“预约可加入窗口 + 最大面诊时长 + 合理重连缓冲”,并在每次重新进入房间前重新授权。腾讯官方云助手的Web 进房说明指出原始 TRTC 的 UserSig 在进房时校验、进房后到期不影响当前通话;若采用包含 IM 登录的 TUIRoomKit,还要监听 onUserSigExpired 并从后端续签。
  • SecretKey 放在服务端密钥管理系统/受限环境变量中;禁止进入桌面包、前端 JS、崩溃转储、遥测和调试日志。

PrivateMapKey(高级权限控制)

  • UserSig 证明某 UserID 有权使用该 SDKAppID不等于有权进入某个面诊房间。对视频面诊,建议评估开启高级权限控制
  • PrivateMapKey 绑定 room ID 与权限位,可分别控制创建房间、进房、收发音频、收发主路视频、收发辅路(屏幕分享)。必须由服务端计算。
  • 示例权限策略:
    • 医生:创建/进入、收发音频、收发视频、发送/接收辅路。
    • 患者:进入、收发音频、收发视频、接收辅路;若不允许患者分享,则不授予“发送辅路”。
    • 若不能保证医生先进入,需要给患者也授予创建房间,或由业务规则强制医生先创建。
  • 启用高级权限控制后,同一 SDKAppID 下所有用户都必须携带 PrivateMapKey;已有线上应用不能直接无迁移开启。建议新建独立 SDKAppID 做灰度验证。

房间与用户生命周期

官方基本概念给出的关键规则:

  • 不存在的房间在首个用户进入时自动创建。
  • 通话模式下,所有用户主动退房后房间立即解散;所有人异常掉线时,服务端约 90 秒后清理并解散。异常等待时间仍计入用量。
  • 数字 roomId 与字符串 strRoomId 是两套不同房间,不能混用;全端和服务端必须统一一种类型。
  • 同一 UserID 同时进入同一房间会互踢/干扰。UserID 应由后端稳定映射;若允许同一账号多设备同时加入,应给每个设备/会话分配唯一 UserID。
  • 原始 TRTC 的远端用户进出回调用于维护成员列表,不代表对方已有视频;显示远端画面必须监听 onUserVideoAvailable,屏幕分享监听 onUserSubStreamAvailable

建议客户端状态机:

idle
  → device-preflight
  → ticket-issued
  → joining
  → joined(media-off)
  → media-on / screen-sharing
  → exiting
  → idle

joined ↔ reconnecting
joining/connected → kicked | room-dismissed | fatal-error → cleanup → idle

实施要点:

  • 创建实例后先注册所有错误、进退房、远端媒体、设备变化和连接状态回调,再调用 enterRoom
  • onEnterRoom(result > 0) 作为真正进房成功,不以 enterRoom() 函数返回或窗口已打开代替。
  • 网络断开时 SDK 会自动重连;监听 onConnectionLostonTryToReconnectonConnectionRecovery。官方说明远端通常约 90 秒后才收到异常用户离开,因此业务后端不能把短时断网立即当成面诊结束,见断线重连说明
  • 正常结束必须成对调用 exitRoom;退出后停止本地媒体、停止远端渲染、移除监听并销毁实例。Web 端明确要求 exitRoom() 后不再使用时调用 destroy()
  • 服务端房间与媒体回调可能重试,且特殊网络/重进场景可能产生重复事件;回调处理必须幂等,不能只用“最后一条回调”做财务/医疗业务结论。

摄像头、麦克风与屏幕分享

通话前检查

  • 列出并选择摄像头、麦克风和扬声器;运行摄像头预览、麦克风电平和扬声器测试。
  • 网络测速只在进房前运行,避免影响通话质量。
  • 默认音频质量使用 Speech/语音模式;先以 640×360 的保守视频档位验证弱网和 CPU,再按质量监控数据决定是否提高到 720p。
  • 对权限拒绝、设备被占用、设备拔出、默认设备变化给出可恢复 UI,不应直接结束预约。

屏幕分享

  • 默认采用辅路,让医生摄像头与屏幕并存;远端根据辅路可用事件订阅。
  • 一个房间只允许一路屏幕分享,第二人发起前应在业务 UI 层仲裁。
  • 分享前必须让用户确认目标窗口/屏幕;分享中持续显示醒目标志;无论从应用按钮还是浏览器/系统指示条停止,都要收到事件并清理本地状态。
  • 医疗场景应默认不共享整个桌面,优先窗口分享。Native SDK 可用窗口排除/包含 API,避免将病历主窗口、通知或其他患者信息意外共享。
  • macOS 打包必须验证 Camera、Microphone 和 Screen Recording 权限的首次授权、拒绝、系统设置中撤销及升级安装后的行为。

生产安全与合规边界

  1. 应用隔离:开发、测试、生产使用不同 SDKAppID;正式环境不要复用 Demo 密钥或固定房间号。
  2. 最小化标识roomId/userId 使用无语义内部 ID,不包含姓名、手机号、身份证号、诊断或预约描述;映射只保存在业务后端。
  3. 后端授权:每次签票都校验预约参与者、角色、状态和时间窗;不能只靠“知道 roomId”。高安全场景使用 PrivateMapKey。
  4. 回调真实性:生产回调使用 HTTPS;按官方算法对原始请求体做 HMAC-SHA256 校验,并校验 SDKAppID;存储事件 ID/组合键以幂等处理重试。
  5. 传输与额外加密:腾讯信息安全说明说明其默认传输有私有传输协议/TLS/WSS 保护。若组织政策要求额外媒体私有加密,Native C++ API 提供 enablePayloadPrivateEncryption,见媒体流私有加密;该能力需要相应套餐,并与云端录制、旁路转推等能力存在冲突,应在架构阶段选定。Electron 官方另有 C++ 动态库形式的自定义媒体加解密插件,实施成本应单独评估。
  6. 录制默认关闭:只有在业务、告知同意、保存期限、访问控制和删除策略均明确后才启用。官方说明云录制文件存入客户指定的云存储;开启私有加密会限制云录制等服务。
  7. 日志最小化:不记录 UserSig、PrivateMapKey、完整 IPC 消息、病历内容或屏幕标题;支持包上传前先脱敏。SDK 日志目录应受操作系统用户权限保护并配置留存期。
  8. 程序供应链Windows 代码签名;macOS Developer ID、Hardened Runtime/必要 entitlement、Notarization;固定已验证 SDK 版本,升级先做双平台回归。
  9. 网络准入:医院/机构网络可能限制 UDP。上线前按防火墙白名单在真实网络验证 Native/Electron 或 WebRTC 所需端口与动态域名,不要只在家庭网络测试。
  10. 合规不是 SDK 自动获得:腾讯的信息安全说明明确不是国家/行业标准承诺,强制要求建议通过书面 SLA 确认。医疗隐私、录制同意、数据驻留和留存仍需项目方做法务/安全评审。

最小可验证集成(推荐:Electron companion

验证目标

先在一个 Windows 10/11 x64 和一个受支持 macOS 真机上实现 doctor ↔ patient 互通;进入预生产前再增加同平台终端,覆盖 Windows ↔ Windows、macOS ↔ macOS。最终证明安全签票、跨平台进房、音视频、设备权限、屏幕辅路、重连、正常退房和打包后运行都成立。

实施顺序

  1. TRTC 开发应用
    • 新建独立开发 SDKAppID。
    • 先关闭自动录制/旁路转推;高级权限控制在基础链路跑通后于同一开发应用或新应用验证。
  2. Python/任意现有后端的 ticket endpoint
    • POST /api/appointments/{id}/rtc-ticket
    • 从登录态和预约记录派生 userId/room ID;使用腾讯官方 Python HMAC-SHA256 示例在服务端生成 UserSig。
    • 响应中不包含 SecretKey;票据只允许用于该预约与短时间窗。
  3. 最小 Electron companion
    • 安装官方 SDK,创建 TRTCCloud 单例并先注册回调。
    • 请求相机/麦克风权限,提供摄像头、麦克风、扬声器测试。
    • 使用 TRTCAppSceneVideoCall 进房;等待 onEnterRoom > 0
    • 用户点击后调用 startLocalPreview()startLocalAudio(TRTCAudioQualitySpeech)
    • 监听远端主路/辅路可用事件并渲染;实现窗口/整屏辅路分享和停止。
    • 退出时完整清理并调用 destroyTRTCShareInstance()
  4. PySide6 最小联动
    • “开始面诊”请求 ticket,创建带随机 IPC nonce 的 companionticket 通过受认证 IPC 发送,不放命令行。
    • companion 将状态和最终错误码回传;PySide6 只展示状态并提供结束入口。
  5. 后端回调
    • 配置 HTTPS 房间/媒体回调,启用自定义 callback key。
    • 对原始 body 验签并幂等落库;把客户端与回调状态关联到 appointment/session ID。
  6. 高级权限控制验证
    • 服务端生成 PrivateMapKey;验证错误房间、过期/错误票据、患者无屏幕上行权限均被服务端拒绝。

最小验收清单

  • Windows ↔ Windows、macOS ↔ macOS、Windows ↔ macOS 三组均能进房。
  • SDKSecretKey 不存在于 Python 包、Electron 包、JS source map、命令行和日志。
  • 正确票据进房成功;错误 UserSig、错误 PrivateMapKey、非预约参与者进房失败。
  • 摄像头、麦克风、扬声器可检测/切换;拒绝授权后 UI 可恢复;设备拔插不崩溃。
  • 医生与患者可看到/听到对方;以首帧和首个音频回调确认,不只凭 UI 按钮状态。
  • 辅路屏幕分享与摄像头并存;系统 UI 停止分享后双方状态同步;第二路分享被正确阻止。
  • 网络断开时进入 reconnecting,恢复后继续通话;应用强杀后服务端约 90 秒收敛,客户端有经过验证的重新取票/进房路径。
  • 重复 UserID 的互踢行为有明确提示;正常退出释放摄像头/麦克风并销毁实例。
  • 回调验签失败被拒绝;腾讯回调重试不会重复结算或重复关闭预约。
  • Windows 签名安装包和 macOS 签名/公证包在干净机器可运行并能申请权限。
  • 医院/目标机构网络按官方白名单完成真实音视频与屏幕分享测试。

决策门槛

  • 若 Electron companion 的包体/双窗口体验可以接受,按该架构进入生产化。
  • 若产品坚持单窗口,可并行做 2 个受限 POC:
    1. QWebEngineView:仅在上述 WebView 准入测试全部通过后采用;失败即回退 Electron。
    2. Native C++ bridge:先只实现 SDK version、实例、回调、一个本地/远端原生渲染视图和完整销毁;确认 Qt 6/PySide6 稳定后再扩展设备与屏幕分享。
  • 若组织要求媒体私有加密且同时要求云端录制,必须先解决官方能力冲突,不能在开发末期再补。

官方资料索引