腾讯TRRO SDK深度剖析

腾讯 TRRO SDK 深度剖析

本文基于腾讯云 TRRO(Tencent Real-time Remote Operation) 工业能源版官方 SDK 发行包、头文件、License 清单与 Demo 工程,结合 现场设备端 / 远端设备端 文档,从 产品定位、产物矩阵、技术栈与依赖、跨平台 C ABI 架构、三通道原理、双端分工 等层面展开。

速览

  • 双端模型 :现场 Gateway/Fieldlibtrro_field + trro_field.h)+ 远端 Controller/Remotelibtrro_remote + trro_remote.h),C ABI flat API
  • 三通道 :MQTT 信令 + WebRTC 音视频 + 独立二进制控制通道(QoS 0/1,带 VCCT/RCCT 度量)。
  • 工业能力 :Multipath(视频融合调度 + 控制双发)、master/guest 仲裁、按需推流、最高 8 路、私有化部署。
  • 底层三分库libtrro_field|remote + librtc_media + librtc_engine;现场端 FFmpeg 3.x 目录 ,远端 Linux 包附带 FFmpeg 6.1.2.so
  • 版本线索 :官方文档口径 2.4.3 ;Web SDK 包内嵌 2.4.7.0 ;C SDK 运行时 TRRO_getSdkVersion() / TRRO_getVersion() 为准。

目录

  • [1. 产品定位](#1. 产品定位)
  • [2. SDK 版本矩阵与产物包](#2. SDK 版本矩阵与产物包)
    • [2.1 官方版本对照](#2.1 官方版本对照)
    • [2.2 顶层包结构](#2.2 顶层包结构)
  • [3. 技术栈与二进制依赖](#3. 技术栈与二进制依赖)
    • [3.5 跨平台 C ABI 与绑定层](#3.5 跨平台 C ABI 与绑定层)
  • [4. 系统原理:云管端 + 三通道模型](#4. 系统原理:云管端 + 三通道模型)
    • [4.5 多网卡与 Multipath 实现](#4.5 多网卡与 Multipath 实现)
    • [4.6 弱网传输(单链路能力)](#4.6 弱网传输(单链路能力))
  • [5. 现场设备端(Field / Gateway)](#5. 现场设备端(Field / Gateway))
  • [6. 远端设备端(Remote / Controller)](#6. 远端设备端(Remote / Controller))
    • [6.4 接管权限流程(master / guest)](#6.4 接管权限流程(master / guest))
    • [6.5 各平台 SDK 产物矩阵](#6.5 各平台 SDK 产物矩阵)
    • [6.6 官方 Demo 与语言绑定](#6.6 官方 Demo 与语言绑定)
    • [6.7 官方 Demo 胶水层实现详解](#6.7 官方 Demo 胶水层实现详解)
      • [6.7.1 总览:六种胶水模式](#6.7.1 总览:六种胶水模式)
      • [6.7.2 C/C++ 直连(零胶水)](#6.7.2 C/C++ 直连(零胶水))
      • [6.7.3 Go CGO(远端)](#6.7.3 Go CGO(远端))
      • [6.7.4 Python ctypes(双端)](#6.7.4 Python ctypes(双端))
      • [6.7.5 Java JNA(远端 Linux)](#6.7.5 Java JNA(远端 Linux))
      • [6.7.6 Android AAR + JNI(双端)](#6.7.6 Android AAR + JNI(双端))
      • [6.7.7 Unity 双路径(P/Invoke + AndroidJavaObject)](#6.7.7 Unity 双路径(P/Invoke + AndroidJavaObject))
      • [6.7.8 iOS / HarmonyOS / Web(官方封装,Demo 无自研胶水)](#6.7.8 iOS / HarmonyOS / Web(官方封装,Demo 无自研胶水))
  • [7. 接入要点与踩坑](#7. 接入要点与踩坑)
  • [8. 一句话总结](#8. 一句话总结)
  • [9. 延伸阅读](#9. 延伸阅读)

1. 产品定位

腾讯云 实时互动-工业能源版 TRRO 面向工业遥操场景:Robotaxi 安全接管、工程机械远程操控、具身智能数采、机器人运维等。SDK 以 现场网关(Gateway)+ 远端控制器(Controller) 双端模型组织:设备注册上线,远端通过 TRRO_connectField 拉取多路视频并下发控制。

维度 说明
产品族 腾讯云 TRRO 工业能源版
典型场景 远控、多路监控、数采、运维
API 形态 C ABI:TRRO_init* / TRRO_connectField() 等;各平台再包 Java/ObjC/Web
鉴权 device_id + password + certificate + License
控制通道 独立二进制控制通道,QoS 0/1,内建 VCCT/RCCT 度量
多路视频 单现场设备最高 8 路
多网融合 Multipath + network_bind
接管权限 master / guest 仲裁
部署 公有云 / 国际站 / 私有化server_ip:2883

2. SDK 版本矩阵与产物包

TRRO 工业能源版按 现场端 / 远端端 分 SDK 发布,并配套多平台 Demo。官方文档当前版本 2.4.3 ,支持 Linux / Windows / Android / iOS / Web / HarmonyOS远端设备端文档)。

说明 :部分文档分析素材包可能仅含头文件、配置、License 与 Demo 源码;.so / .dll / .aar 等运行时二进制需从 腾讯云 TRRO 控制台 下载完整 SDK 。下文库名来自官方包内 MD5.txt、readme、lib_install.sh 与 Demo 引用。

2.1 官方版本对照

平台 / 产物 版本线索 产物形态 角色
现场 C SDK(Linux aarch64) 运行时 TRRO_getSdkVersion() trro_field.h + libtrro_field.so + sdk_lib/{nvidia,soft,ffmpeg3} Gateway 推流
现场 C SDK(Linux x64) 同上 精简包:头文件 + 配置 + run_loader_x64.sh 同上
现场 Android Demo 分支 v1.1.1 *.aarTrroGateway Java API) 车端/机器人 Android 网关
远端 C SDK(Linux x64) 包名 linux_x64_release trro_remote.h + libtrro_remote.so + FFmpeg 6.x third_lib/ 操控端拉流
远端 C SDK(Windows x64) 文件夹名 win_x86(实际 x64 DLL) trro_remote.dll + 头文件 PC 安全员台
远端 iOS --- TRROControl.framework(ObjC:TrroRemote / TrroGateway 平板/手机远控
远端 Web 外层 v2.4.0_r67,内嵌 2.4.7.0 index.js + index.d.ts 浏览器操控台
远端 Android Demo v1.1.1 AAR + com.tencent.trro.api.* 移动端远控
远端 HarmonyOS Demo v1.1.1 sdklibrary.har + ArkTS com.tencent.trro.api.* 鸿蒙远控
远端 Unity Unity 2021.3+ remoteuinty-release.aar + Windows Plugins DLL 组 云游戏/HMI 原型
官方文档 2.4.3 API 说明 ---

2.2 顶层包结构

典型官方下载目录分为 现场设备端远端设备端demo 三大类:

text 复制代码
TRRO 工业能源版 SDK 包
├── 现场设备端/
│   ├── trro-gateway-sdk-release-aarch64/    ← Linux ARM(Jetson nvidia / 通用 soft+RK)
│   └── trro-gateway-sdk-release-x64/        ← Linux x64 现场包
├── 远端设备端/
│   ├── trro-controller-sdk-linux_x64_release/
│   ├── trro_remote_sdk-win_x86/             ← Windows x64
│   ├── TRROControl/                         ← iOS Framework
│   └── trro_web_sdk/                        ← Web TRROSDK
└── demo/                                    ← 11 个子工程(C++/Qt/Go/Java/Python/Unity/...)

现场 aarch64 完整包 额外含:trro_sample.cppconfig_gen.pydevice.pemtrro_field_license.txttrro_field_doc/(Doxygen HTML)、GetDeviceInfo 设备指纹工具、run_loader.sh


3. 技术栈与二进制依赖

3.1 三分库架构

TRRO Native 侧统一拆为 产品封装 + 媒体 + 传输 三个动态库(Windows 为同名 DLL):

现场端 远端端 职责
产品层 libtrro_field.so libtrro_remote.so / trro_remote.dll TRRO 业务:MQTT 信令、设备注册、Multipath 配置、控制通道、权限仲裁
媒体层 librtc_media.so 同左 采集/编码/解码/渲染、FFmpeg 桥接、硬编硬解适配
传输层 librtc_engine.so 同左 WebRTC 族 ICE/SRTP、拥塞控制、FEC/NACK、DataChannel 类控制承载

现场端 readme 典型链接命令:

bash 复制代码
g++ trro_sample.cpp -o trro-test -I ./include \
  -L ./sdk_lib/ -L ./sdk_lib/soft \
  -ltrro_field -lrtc_media -lrtc_engine -pthread -ldl \
  -Wl,--rpath-link=./sdk_lib/ffmpeg3

远端 Linux 包另含 lib_install.sh,为 sdk_lib/third_lib/ 下 FFmpeg 6.x 创建 libavcodec.so 等软链。

3.2 核心分层

#mermaid-svg-yJxgFxF89QX6O2Jv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yJxgFxF89QX6O2Jv .error-icon{fill:#552222;}#mermaid-svg-yJxgFxF89QX6O2Jv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yJxgFxF89QX6O2Jv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yJxgFxF89QX6O2Jv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yJxgFxF89QX6O2Jv .marker.cross{stroke:#333333;}#mermaid-svg-yJxgFxF89QX6O2Jv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yJxgFxF89QX6O2Jv p{margin:0;}#mermaid-svg-yJxgFxF89QX6O2Jv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yJxgFxF89QX6O2Jv .cluster-label text{fill:#333;}#mermaid-svg-yJxgFxF89QX6O2Jv .cluster-label span{color:#333;}#mermaid-svg-yJxgFxF89QX6O2Jv .cluster-label span p{background-color:transparent;}#mermaid-svg-yJxgFxF89QX6O2Jv .label text,#mermaid-svg-yJxgFxF89QX6O2Jv span{fill:#333;color:#333;}#mermaid-svg-yJxgFxF89QX6O2Jv .node rect,#mermaid-svg-yJxgFxF89QX6O2Jv .node circle,#mermaid-svg-yJxgFxF89QX6O2Jv .node ellipse,#mermaid-svg-yJxgFxF89QX6O2Jv .node polygon,#mermaid-svg-yJxgFxF89QX6O2Jv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yJxgFxF89QX6O2Jv .rough-node .label text,#mermaid-svg-yJxgFxF89QX6O2Jv .node .label text,#mermaid-svg-yJxgFxF89QX6O2Jv .image-shape .label,#mermaid-svg-yJxgFxF89QX6O2Jv .icon-shape .label{text-anchor:middle;}#mermaid-svg-yJxgFxF89QX6O2Jv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yJxgFxF89QX6O2Jv .rough-node .label,#mermaid-svg-yJxgFxF89QX6O2Jv .node .label,#mermaid-svg-yJxgFxF89QX6O2Jv .image-shape .label,#mermaid-svg-yJxgFxF89QX6O2Jv .icon-shape .label{text-align:center;}#mermaid-svg-yJxgFxF89QX6O2Jv .node.clickable{cursor:pointer;}#mermaid-svg-yJxgFxF89QX6O2Jv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yJxgFxF89QX6O2Jv .arrowheadPath{fill:#333333;}#mermaid-svg-yJxgFxF89QX6O2Jv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yJxgFxF89QX6O2Jv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yJxgFxF89QX6O2Jv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yJxgFxF89QX6O2Jv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yJxgFxF89QX6O2Jv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yJxgFxF89QX6O2Jv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yJxgFxF89QX6O2Jv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yJxgFxF89QX6O2Jv .cluster text{fill:#333;}#mermaid-svg-yJxgFxF89QX6O2Jv .cluster span{color:#333;}#mermaid-svg-yJxgFxF89QX6O2Jv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yJxgFxF89QX6O2Jv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yJxgFxF89QX6O2Jv rect.text{fill:none;stroke-width:0;}#mermaid-svg-yJxgFxF89QX6O2Jv .icon-shape,#mermaid-svg-yJxgFxF89QX6O2Jv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yJxgFxF89QX6O2Jv .icon-shape p,#mermaid-svg-yJxgFxF89QX6O2Jv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yJxgFxF89QX6O2Jv .icon-shape .label rect,#mermaid-svg-yJxgFxF89QX6O2Jv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yJxgFxF89QX6O2Jv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yJxgFxF89QX6O2Jv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yJxgFxF89QX6O2Jv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 编解码与处理
信令与接入
媒体引擎
TRRO SDK 封装层
应用层
ICE: host/srflx/prflx/relay
现场业务:相机/CAN/杆量
操控端:HMI/VR/安全员台
libtrro_field.so

trro_field.h
libtrro_remote.so

trro_remote.h
librtc_media.so

采集/编码/解码/渲染
librtc_engine.so

WebRTC 传输栈
MQTT (paho.mqtt.c)

设备注册/在线/配置下发
device.pem 证书链
FFmpeg3
硬编:NVENC / RK / 地平线 / MediaCodec
硬解:NVENC/D3D/MediaCodec
TRRO 云端 SFU/接入

3.2.1 二进制模块依赖链
text 复制代码
应用
 └─ libtrro_field.so / libtrro_remote.so     ← TRRO 业务:MQTT、Multipath、控制通道、权限
      ├─ librtc_media.so                     ← 编解码、采集、渲染、FFmpeg 桥接
      │    ├─ sdk_lib/ffmpeg3/(现场 ARM)或 third_lib/libav*.so.60(远端 Linux)
      │    └─ 平台硬编插件(NVENC / RK / MediaCodec / VideoToolbox 等)
      └─ librtc_engine.so                    ← WebRTC 传输:ICE/SRTP/FEC/NACK/DataChannel
           └─ OpenSSL + libsrtp(License 披露)

3.3 开源与第三方组件(License 文件披露)

trro_field_license.txt / trro_remote_license.txt 列出主要依赖(节选):

组件 License 版本/说明 用途
WebRTC BSD 3-Clause 内嵌于 librtc_engine ICE、SRTP、拥塞控制、JitterBuffer
libsrtp BSD 3-Clause 随 WebRTC 栈 SRTP 加解密
FFmpeg LGPL 2.1+ 现场包目录名 ffmpeg3 ;License 声明源码 6.1.2 (远端 libavcodec.so.60 等) 转码、RTSP、软编解、缩放
OpenSSL Apache 2.0 3.0.12(License 中 zip 链接) TLS、MQTT/HTTPS 证书校验
paho.mqtt.c EPL/EDL --- MQTT 信令(Demo 日志可见 mqtt kickoutkTrroKickout
curl curl license --- HTTP 配置/日志上报
zlib zlib license --- 压缩
cJSON MIT --- JSON 配置解析
spdlog MIT --- 日志

FFmpeg 版本说明 :现场 aarch64 包 readme 仍写 sdk_lib/ffmpeg3 目录名(历史命名);远端 Controller Linux 包 third_lib/ 使用 FFmpeg 6.x soname(libavcodec.so.60libavutil.so.58 等,与 6.1.2 License 条目一致)。集成时 勿混用 两套 FFmpeg 目录到同一 LD_LIBRARY_PATH

3.4 编解码与传输能力

头文件 trro_field.hTrroCodec 枚举:

枚举 说明
0 Trro_H264 H.264
1 Trro_H265 H.265
2 Trro_AV1 AV1
20 Trro_OPUS 音频 OPUS
能力 现场端 远端端
视频编码 H.264 / H.265 / AV1 硬编 + H.264 软编 ---
视频解码 --- H.264/H.265/AV1,平台硬解
音频 OPUS,PCM 外部输入 PCM 混音回调(TRRO_onRemoteMixAudioFrame,10ms 16bit)
硬编平台 NVIDIA Jetson(sdk_lib/nvidia)、RK、地平线、Android MediaCodec ---
传输 抗弱网低延迟 UDP(WebRTC 栈) 同左
穿网模式 ICE:host / srflx / prflx / relayTRRO_onMediaStatestun 字段) 同左

3.5 跨平台 C ABI 与绑定层

与通用 RTC SDK(C++ 抽象类 + Java/ObjC 绑定)不同,TRRO 对外主契约是 C flat API

c 复制代码
// trro_remote.h --- extern "C" + 函数指针回调
typedef void (STD_CALL *TRRO_onAllLatencyReport)(void* context, const char* gwid,
    int conn_fd, long long latency1, long long latency2,
    long long videotime, int rcct);
TRRO_EXPORT int TRRO_connectField(const char* gwid, int streams_num,
    int streams_id[], int conn_fds[]);
集成方式 API 面 绑定方式
Linux/Windows C/C++ trro_field.h / trro_remote.h 直接链接 .so/.dll
Android com.tencent.trro.api.TrroGateway / TrroRemote AAR + JNI → 同上三分库
iOS TrroRemoteTrroGateway(ObjC) TRROControl.framework
Web TRROSDK class(index.d.ts 浏览器 WebRTC + 独立信令栈, Native .so
HarmonyOS com.tencent.trro.api.*(ArkTS) sdklibrary.har
Unity TrroInterface.cs / TrroDemo.cs P/Invoke / Android AAR
Go / Python / Java Demo 工程 CGO / ctypes / JNA 薄封装(详见 [§6.7](#集成方式 API 面 绑定方式 Linux/Windows C/C++ trro_field.h / trro_remote.h 直接链接 .so/.dll Android com.tencent.trro.api.TrroGateway / TrroRemote AAR + JNI → 同上三分库 iOS TrroRemote、TrroGateway(ObjC) TRROControl.framework Web TRROSDK class(index.d.ts) 浏览器 WebRTC + 独立信令栈,非 Native .so HarmonyOS com.tencent.trro.api.*(ArkTS) sdklibrary.har Unity TrroInterface.cs / TrroDemo.cs P/Invoke / Android AAR Go / Python / Java Demo 工程 CGO / ctypes / JNA 薄封装(详见 §6.7))

Windows 头文件对 C# 友好:USE_CSHARP + __stdcallSTD_CALL)导出约定。
#mermaid-svg-pNmRtToWbtQWR5Vu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-pNmRtToWbtQWR5Vu .error-icon{fill:#552222;}#mermaid-svg-pNmRtToWbtQWR5Vu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pNmRtToWbtQWR5Vu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pNmRtToWbtQWR5Vu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pNmRtToWbtQWR5Vu .marker.cross{stroke:#333333;}#mermaid-svg-pNmRtToWbtQWR5Vu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pNmRtToWbtQWR5Vu p{margin:0;}#mermaid-svg-pNmRtToWbtQWR5Vu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-pNmRtToWbtQWR5Vu .cluster-label text{fill:#333;}#mermaid-svg-pNmRtToWbtQWR5Vu .cluster-label span{color:#333;}#mermaid-svg-pNmRtToWbtQWR5Vu .cluster-label span p{background-color:transparent;}#mermaid-svg-pNmRtToWbtQWR5Vu .label text,#mermaid-svg-pNmRtToWbtQWR5Vu span{fill:#333;color:#333;}#mermaid-svg-pNmRtToWbtQWR5Vu .node rect,#mermaid-svg-pNmRtToWbtQWR5Vu .node circle,#mermaid-svg-pNmRtToWbtQWR5Vu .node ellipse,#mermaid-svg-pNmRtToWbtQWR5Vu .node polygon,#mermaid-svg-pNmRtToWbtQWR5Vu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pNmRtToWbtQWR5Vu .rough-node .label text,#mermaid-svg-pNmRtToWbtQWR5Vu .node .label text,#mermaid-svg-pNmRtToWbtQWR5Vu .image-shape .label,#mermaid-svg-pNmRtToWbtQWR5Vu .icon-shape .label{text-anchor:middle;}#mermaid-svg-pNmRtToWbtQWR5Vu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-pNmRtToWbtQWR5Vu .rough-node .label,#mermaid-svg-pNmRtToWbtQWR5Vu .node .label,#mermaid-svg-pNmRtToWbtQWR5Vu .image-shape .label,#mermaid-svg-pNmRtToWbtQWR5Vu .icon-shape .label{text-align:center;}#mermaid-svg-pNmRtToWbtQWR5Vu .node.clickable{cursor:pointer;}#mermaid-svg-pNmRtToWbtQWR5Vu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-pNmRtToWbtQWR5Vu .arrowheadPath{fill:#333333;}#mermaid-svg-pNmRtToWbtQWR5Vu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pNmRtToWbtQWR5Vu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pNmRtToWbtQWR5Vu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pNmRtToWbtQWR5Vu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-pNmRtToWbtQWR5Vu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pNmRtToWbtQWR5Vu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-pNmRtToWbtQWR5Vu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pNmRtToWbtQWR5Vu .cluster text{fill:#333;}#mermaid-svg-pNmRtToWbtQWR5Vu .cluster span{color:#333;}#mermaid-svg-pNmRtToWbtQWR5Vu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pNmRtToWbtQWR5Vu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-pNmRtToWbtQWR5Vu rect.text{fill:none;stroke-width:0;}#mermaid-svg-pNmRtToWbtQWR5Vu .icon-shape,#mermaid-svg-pNmRtToWbtQWR5Vu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-pNmRtToWbtQWR5Vu .icon-shape p,#mermaid-svg-pNmRtToWbtQWR5Vu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-pNmRtToWbtQWR5Vu .icon-shape .label rect,#mermaid-svg-pNmRtToWbtQWR5Vu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-pNmRtToWbtQWR5Vu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-pNmRtToWbtQWR5Vu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-pNmRtToWbtQWR5Vu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Native 三分库
C ABI 契约层
语言绑定
独立实现
Android Java AAR
iOS TrroRemote
Web TRROSDK.js
Go/Python/JNA/Unity
trro_field.h
trro_remote.h
libtrro_field / libtrro_remote
librtc_media
librtc_engine
TRRO 云端


4. 系统原理:云管端 + 三通道模型

4.1 端到端数据流

远端设备端 libtrro_remote TRRO 云端 MQTT + SFU 现场设备端 libtrro_field 远端设备端 libtrro_remote TRRO 云端 MQTT + SFU 现场设备端 libtrro_field #mermaid-svg-tbufCJTcwYs3z6aw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tbufCJTcwYs3z6aw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tbufCJTcwYs3z6aw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tbufCJTcwYs3z6aw .error-icon{fill:#552222;}#mermaid-svg-tbufCJTcwYs3z6aw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tbufCJTcwYs3z6aw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tbufCJTcwYs3z6aw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tbufCJTcwYs3z6aw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tbufCJTcwYs3z6aw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tbufCJTcwYs3z6aw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tbufCJTcwYs3z6aw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tbufCJTcwYs3z6aw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tbufCJTcwYs3z6aw .marker.cross{stroke:#333333;}#mermaid-svg-tbufCJTcwYs3z6aw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tbufCJTcwYs3z6aw p{margin:0;}#mermaid-svg-tbufCJTcwYs3z6aw .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-tbufCJTcwYs3z6aw text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-tbufCJTcwYs3z6aw .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-tbufCJTcwYs3z6aw .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-tbufCJTcwYs3z6aw .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-tbufCJTcwYs3z6aw .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-tbufCJTcwYs3z6aw #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-tbufCJTcwYs3z6aw .sequenceNumber{fill:white;}#mermaid-svg-tbufCJTcwYs3z6aw #sequencenumber{fill:#333;}#mermaid-svg-tbufCJTcwYs3z6aw #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-tbufCJTcwYs3z6aw .messageText{fill:#333;stroke:none;}#mermaid-svg-tbufCJTcwYs3z6aw .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-tbufCJTcwYs3z6aw .labelText,#mermaid-svg-tbufCJTcwYs3z6aw .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-tbufCJTcwYs3z6aw .loopText,#mermaid-svg-tbufCJTcwYs3z6aw .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-tbufCJTcwYs3z6aw .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-tbufCJTcwYs3z6aw .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-tbufCJTcwYs3z6aw .noteText,#mermaid-svg-tbufCJTcwYs3z6aw .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-tbufCJTcwYs3z6aw .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-tbufCJTcwYs3z6aw .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-tbufCJTcwYs3z6aw .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-tbufCJTcwYs3z6aw .actorPopupMenu{position:absolute;}#mermaid-svg-tbufCJTcwYs3z6aw .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-tbufCJTcwYs3z6aw .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-tbufCJTcwYs3z6aw .actor-man circle,#mermaid-svg-tbufCJTcwYs3z6aw line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-tbufCJTcwYs3z6aw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ① 信令通道 (MQTT) ② 视频通道 (WebRTC/ICE) ③ 控制通道 (二进制透传) 注册 device_id + 证书 注册 + 拉取在线网关列表 TRRO_connectField(gwid, streams) 按需推流指令 (有人观看才推) H264/H265/AV1 多路编码流 SFU 转发 (不混流) 硬解 + 窗口渲染 / 外部解码回调 TRRO_sendControlData (qos 0/1) TRRO_onControlData 回调 TRRO_sendControlData (状态/回显) TRRO_onReportData 回调

4.2 三通道职责

通道 协议栈 承载内容
信令 MQTT over TLS 设备上下线、配置下发、权限、会话协调
视频/音频 WebRTC (ICE + SRTP) 多路编码视频、OPUS 音频
控制 SDK 内独立 Data 通道 任意二进制(杆量、CAN 帧、关节指令等)

控制通道是 TRRO 面向遥操的 核心能力。头文件中:

  • 现场端:TRRO_sendControlData(msg, len, qos) / TRRO_registerControlDataCallback
  • 远端端:TRRO_sendControlData(gwid, msg, len, qos) / TRRO_registerReportDataCallback
  • QoS:0 = unreliable(低延迟、可丢),1 = reliable(可靠传输)
  • 限流(头文件 trro_error_enum.h / trro_field.h):
    • TRRO_MESSAGE_RATE_EXCEED:发送频率过高(3 秒内超过最大消息数)
    • TRRO_MESSAGE_MAX_EXCEED1 秒内发送数据量超过上限
    • TRRO_MESSAGE_BYTE_EXCEED:单条或周期内消息长度超限

对应遥操文档中的「~100Hz 控制通道」------这是通道能力上限,实际频率受网络与限流约束。

4.3 关键时延指标(SDK 内建)

远端头文件 TRRO_onAllLatencyReport 定义了工业遥操最关心的口径:

指标 含义
latency1 视频上行时延(ms)
latency2 视频上行 + 控制下行 时延
vcct(现场端 TRRO_onLatencyReport 视频控制闭环 = 视频上行(不含采集)+ 控制下行
rcct 控制信道往返时延 = 控制上行 + 控制下行
videotime 现场设备采集时间戳(帧对齐用)
user_time 用户自定义时间戳(外部输入 YUV/编码帧时打入)

现场 Demo 用 TRRO_externalVideoDataWithUserTime 打用户时间戳,用于帧级对齐:

cpp 复制代码
TRRO_externalVideoDataWithUserTime(id, data, data_width, data_height, 0, GetTime2(), 0);

4.4 建连过程(远端 SDK 暴露的 ICE 时间线)

TrroConnectCost 结构体把 WebRTC 建连拆成可观测阶段(T0→C9),便于 POC 定位瓶颈:

复制代码
T0 受理 ConnectPeer
 → C0b 提交 main_loop
 → C1  RtcConfig 请求
 → C3  engine->Join
 → C4  onJoined 成功
 → C5  收到对端 publish
 → C5b 发起订阅
 → C5c 订阅成功
 → C7  ICE 连接中
 → C8  PEER_CONNECTED
 → C9  首帧到达(触发回调)

媒体面走的是 Join → Publish/Subscribe → ICE 的经典 WebRTC SFU 模式,而非 RTMP 推拉流。

4.5 多网卡与 Multipath 实现

TRRO 的 Multipath 不是 「主链路挂了再切备链路」的传统主备,而是 多路径同时可用 :切换下沉到传输栈,会话不断开、应用无感 。官方宣传在 Multipath 场景下网络切换 <50ms多网聚合与切换)。详细配置见 多网络路径传输

4.5.1 与主备倒换的差异
模式 故障感知 → 切换 切换时应用层
主备倒换 检测超时 → 换路由 → 常触发重连 黑屏、会话重建
TRRO Multipath 副路径已在传 / 调度已就绪 无 reconnect
4.5.2 视频 vs 控制:两种 Multipath 策略

官方对 媒体控制 采用不同策略(同一 network_bind 下):

路径 配置项 策略 带宽特点
视频/音频 media_trans_mode 融合多网 :按各链路 RTT/丢包 调度 到多张网卡 通常非全量 N 倍复制
控制/消息 dc_double_trans_enable 默认 消息双发 :同一 PDU 多路径同时发,对端取先到 双发时控制带宽约 ≈2×
json 复制代码
"network_bind": ["192.168.8.96", "192.168.67.96"],
"media_trans_mode": 1,
"dc_double_trans_enable": 1
media_trans_mode 含义 适用
1(默认) 5G 增强,切换最快 多 5G
2 均衡 多网质量接近
3 4G 增强 多 4G
dc_double_trans_enable 含义
1(默认) 控制通道双发,延迟敏感
0 关闭双发,控制也走融合调度

多网传输在计费上约有 ×1.2 带宽系数(相对单网),可按车队/路段选择性开启。

4.5.3 四层实现架构

#mermaid-svg-RzZzAn0qyxUKgEnp{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RzZzAn0qyxUKgEnp .error-icon{fill:#552222;}#mermaid-svg-RzZzAn0qyxUKgEnp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RzZzAn0qyxUKgEnp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RzZzAn0qyxUKgEnp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RzZzAn0qyxUKgEnp .marker.cross{stroke:#333333;}#mermaid-svg-RzZzAn0qyxUKgEnp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RzZzAn0qyxUKgEnp p{margin:0;}#mermaid-svg-RzZzAn0qyxUKgEnp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RzZzAn0qyxUKgEnp .cluster-label text{fill:#333;}#mermaid-svg-RzZzAn0qyxUKgEnp .cluster-label span{color:#333;}#mermaid-svg-RzZzAn0qyxUKgEnp .cluster-label span p{background-color:transparent;}#mermaid-svg-RzZzAn0qyxUKgEnp .label text,#mermaid-svg-RzZzAn0qyxUKgEnp span{fill:#333;color:#333;}#mermaid-svg-RzZzAn0qyxUKgEnp .node rect,#mermaid-svg-RzZzAn0qyxUKgEnp .node circle,#mermaid-svg-RzZzAn0qyxUKgEnp .node ellipse,#mermaid-svg-RzZzAn0qyxUKgEnp .node polygon,#mermaid-svg-RzZzAn0qyxUKgEnp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RzZzAn0qyxUKgEnp .rough-node .label text,#mermaid-svg-RzZzAn0qyxUKgEnp .node .label text,#mermaid-svg-RzZzAn0qyxUKgEnp .image-shape .label,#mermaid-svg-RzZzAn0qyxUKgEnp .icon-shape .label{text-anchor:middle;}#mermaid-svg-RzZzAn0qyxUKgEnp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RzZzAn0qyxUKgEnp .rough-node .label,#mermaid-svg-RzZzAn0qyxUKgEnp .node .label,#mermaid-svg-RzZzAn0qyxUKgEnp .image-shape .label,#mermaid-svg-RzZzAn0qyxUKgEnp .icon-shape .label{text-align:center;}#mermaid-svg-RzZzAn0qyxUKgEnp .node.clickable{cursor:pointer;}#mermaid-svg-RzZzAn0qyxUKgEnp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RzZzAn0qyxUKgEnp .arrowheadPath{fill:#333333;}#mermaid-svg-RzZzAn0qyxUKgEnp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RzZzAn0qyxUKgEnp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RzZzAn0qyxUKgEnp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RzZzAn0qyxUKgEnp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RzZzAn0qyxUKgEnp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RzZzAn0qyxUKgEnp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RzZzAn0qyxUKgEnp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RzZzAn0qyxUKgEnp .cluster text{fill:#333;}#mermaid-svg-RzZzAn0qyxUKgEnp .cluster span{color:#333;}#mermaid-svg-RzZzAn0qyxUKgEnp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RzZzAn0qyxUKgEnp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RzZzAn0qyxUKgEnp rect.text{fill:none;stroke-width:0;}#mermaid-svg-RzZzAn0qyxUKgEnp .icon-shape,#mermaid-svg-RzZzAn0qyxUKgEnp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RzZzAn0qyxUKgEnp .icon-shape p,#mermaid-svg-RzZzAn0qyxUKgEnp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RzZzAn0qyxUKgEnp .icon-shape .label rect,#mermaid-svg-RzZzAn0qyxUKgEnp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RzZzAn0qyxUKgEnp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RzZzAn0qyxUKgEnp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RzZzAn0qyxUKgEnp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} TRRO 云端
librtc_engine
config.json
OS / 硬件
网卡1 → 运营商A
网卡2 → 运营商B
策略路由 ip rule + table
network_bind
media_trans_mode
dc_double_trans_enable
源 IP / 网卡绑定
视频:融合调度
控制:双发 + 去重
Multipath 融合网关
SFU 只转发

  1. OS 层 :每个 network_bind IP 须能 独立出公网(不同 SIM / 不同 CPE WAN)。
  2. SDK 配置层network_bind 开启多网;可选 media_trans_modedc_double_trans_enable
  3. 传输栈 :每链路独立 socket;TrroMultiNetworkStats 上报各 path 的 RTT/丢包/收发字节,供调度决策。
  4. 云端:Multipath 网关汇聚多 path 上行,与 SFU 转发配合。
4.5.4 OS 多网前置:策略路由

典型车端:多网卡各接不同 CPE,或单网卡多 IP(eth0:0 / eth0:1)+ 按源 IP 选路

bash 复制代码
ip rule add from 192.168.8.96 table 10
ip rule add from 192.168.67.96 table 20
ip route add default via 192.168.8.1 dev eth0 table 10
ip route add default via 192.168.67.1 dev eth1 table 20

验收官方要求):每个 bind IP 应打出 不同公网 IP

bash 复制代码
curl http://cip.cc --interface 192.168.8.96
curl http://cip.cc --interface 192.168.67.96

CPE 侧可参考:单 CPE 多 WAN(VLAN 分网段)或多 CPE 各接不同运营商。

4.5.5 SDK 配置与权限

config_gen.py 中开启示例:

python 复制代码
json_data["network_bind"] = ["192.168.8.96", "192.168.67.96"]

物联网卡白名单 场景,network_bind 可带 DNS(物联网卡白名单配置):

json 复制代码
"network_bind": [
  "192.168.8.11/192.168.8.1",
  "192.168.67.11/192.168.67.1"
]

绑定指定网卡需 cap_net_raw + cap_net_bind_service (或 root),否则 network_bind 可能失效:

bash 复制代码
sudo setcap cap_net_raw,cap_net_bind_service+ep ./trro-test
4.5.6 运行时观测

现场端注册 按网卡粒度 统计(trro_field.h):

cpp 复制代码
struct TrroMultiNetworkStats {
    char local_ip[16];   int local_port;
    char extern_ip[16];  int extern_port;
    float rtt;  float lost;
    unsigned long long send_bytes, recv_bytes;
};
// TRRO_registerMultiNetworkStatsCallback(...)

结合 TRRO_onMediaStatestun 字段(0 host / 1 srflx / 2 prflx / 3 relay)可判断各 path 穿网形态。

4.5.7 与标准 WebRTC / MPTCP 对比
方案 多 SIM / 多网卡
标准 WebRTC 无原生 Multipath;断网常 ICE restart
MPTCP 内核层,车载/运营商 NAT 场景少见
TRRO network_bind + 自研 UDP 栈 融合/双发 + 云端 MP 网关
4.5.8 Multipath POC 检查清单
  1. 硬件:多 CPE / 多 SIM / 多网口(或单口多 IP + 策略路由)
  2. OS:curl --interface 验证多公网 IP
  3. 配置:network_bind + 按需 media_trans_mode / dc_double_trans_enable
  4. 权限:setcap 或 root
  5. 运行:注册 TRRO_registerMultiNetworkStatsCallback,观察各 path RTT/lost
  6. 对比:单网 vs 多网 同路线跑 ≥1 周,测卡顿、切换时延、RCCT 尖刺

4.6 弱网传输(单链路能力)

Multipath 解决 多 path 切换 ;单条 path 上 TRRO 依赖 librtc_engine 内嵌 WebRTC 族栈的弱网算法:

机制 作用
FEC XOR + RS 类冗余,按帧类型动态
NACK / ARQ 时间序判丢 + 重传
拥塞控制 改良 GCC + 类 BBR,与编码码率联动
JitterBuffer 与 FEC/流控联动,初始队列偏浅(低延迟向)
SFU 只转发不混流,减少云端处理时延

宣传口径:约 30% 丢包 下卡顿率 <1%(须 POC 实测,不可直接当 SLA)。


5. 现场设备端(Field / Gateway)

头文件trro_field.h

角色 :车端、机器人、挖机工控机、数采网关------多路采集编码 + 上行 + 接收控制

5.1 生命周期与信令状态

复制代码
TRRO_initGwPathWithLicense(config.json, license.txt, mode)
  → TRRO_registerSignalStateCallback → kTrroReady   // MQTT 信令就绪
  → TRRO_start()                                    // 启动媒体业务
  → ... 运行 ...
  → TRRO_stop()
SignalState 含义
kTrroReady 信令连接成功
kTrroLost 断开,SDK 自动重连
kTrroReup 自动重连成功
kTrroKickout 被踢(如 MQTT kickout)
kTrroAuthFailed 用户名/密码错误

初始化 API 族:TRRO_initGwPath / TRRO_initGwJson / TRRO_initGwPathWithLicensemode=0 同步阻塞至就绪,mode=-1 异步经 TRRO_onSignalState 通知。

5.2 视频输入模式(streams_config

config.json / config_gen.py 支持多种 protocol

protocol 含义 典型硬件
v4l2 本地相机采集(DMA/MMAP) USB 相机、GMSL
outside 外部喂 YUV(TRRO_externalVideoData* 自研 ISP 管线
outenc 外部喂已编码 H264/H265 车端硬编后直接注入
rtsp_enc RTSP 拉流不转码直推 网络摄像机
普通 RTSP 拉流 + 转码 异构源

配置示例(config.json 字段):

json 复制代码
{
  "projectid": "xxxx",
  "device_id": "xxxx",
  "device_streams": 1,
  "streams_config": [{
    "protocol": "v4l2",
    "camera": 0,
    "width": 1920, "height": 1080,
    "encode_width": 1280, "encode_height": 720,
    "bps": 2000, "always_push": 0, "codec": 0
  }],
  "sdk_mode": "server2",
  "cloud_mode": "public"
}

5.3 现场端独有能力

能力 API / 配置 原理
按需推流 always_push: 0 远端无人观看时不推,省带宽
多网 Multipath network_bind + §4.5 多 4G/5G/WiFi;TRRO_registerMultiNetworkStatsCallback
ROI 编码 TRRO_setEncodeRoi 重点区域高 QP,弱网保关键区域
接管权限仲裁 TRRO_setOperationPermission / TRRO_onOperationPermissionRequest 同时仅一个 master
本地录制 TRRO_startRecorder(实验性) 旁路存 H264
NVIDIA 零拷贝 TRRO_externalVideoDataDmaNative Jetson DMA fd 输入
网络质量探测 TRRO_testNetworkQuality 指定流 ID 主动测网
密码热更新 TRRO_updatePassword 运行时更新 MQTT 密码

头文件 trro_error_enum.h / trro_field.h 按模块分段定义错误码(配置 0x01*、初始化 0x02*、License、控制限流 TRRO_MESSAGE_* 等),可用 getErrorMsg(code) 转文字。

5.4 sdk_mode 三种模式

模式 含义
p2p 端到端直连倾向
server 经云端 SFU 转发(私有化常用)
server2 公有云推荐模式(config_gen.py 默认)

5.5 部署模式与 cloud_mode

cloud_mode 说明 典型配置
public 国内公有云 projectidcertificatepassword;配置工具 console.trro.config
public_intl 国际站 config_gen.pyuse_international=True
private 私有化 server_ip:2883(接入)、rtc_server_ip:rtc_server_port(媒体);最小启动后可经 http://serverip:8190/config_template 在线下发 streams_config

私有化最小现场配置(readme.md):

json 复制代码
{
  "device_id": "test_gw",
  "device_name": "test_gw",
  "server_ip": "xxx.xxx.xxx.xxx",
  "server_port": 2883
}

License :现场端 TRRO_initGwPathWithLicense;校验失败错误码含 TRRO_INIT_LICENSE_CHECK_*、公有云 TRRO_INIT_PUBLIC_LICENSE_CHECK_*(超时、未绑定、数量不足、过期等)。新用户可申请 2 周免费试用 License(2 个授权)。

断网重连 :现场端自管理------信令 kTrroLost → 自动重连 → kTrroReup;媒体 path 劣化时由 Multipath / 弱网算法恢复,无需应用层 rebuild 会话。


6. 远端设备端(Remote / Controller)

头文件trro_remote.h

角色 :安全员 PC、VR 头显、运维平板------拉多路视频 + 下发控制 + 渲染

6.1 生命周期

复制代码
TRRO_initJson / TRRO_initJsonAsync(config)
  → TRRO_onSignalState(kTrroReady)
  → TRRO_connectField(gwid, streams_num, streams_id[], conn_fds[])
  → TRRO_setWindows(conn_fds[], HWND[], num)   // 绑定渲染窗口
  → TRRO_sendControlData(gwid, msg, len, qos)    // 下发控制
  → TRRO_disconnect / TRRO_destroy

远端配置比现场端简洁------不负责采集编码 ,只声明自身身份与最大流数(config.json.sample):

json 复制代码
{
  "device_id": "ctrl1",
  "device_name": "vin234",
  "cloud_mode": "public",
  "certificate": "./device.pem",
  "projectid": "******",
  "password": "******",
  "max_streams": 8
}

6.2 远端端独有能力

能力 API 用途
网关发现 TRRO_getGwList() / TRRO_getGwInfo(gwid) 列出在线现场设备
多路拉流 TRRO_connectField + conn_fd 数组 最高 8 路并行
内部/外部渲染 TRRO_setWindows / TRRO_registerRemoteFrameCallback 窗口硬渲染或自研渲染管线
外部解码 TRRO_useExternalDecoder + TRRO_registerRemoteEncodedFrameCallback 自研 GPU 解码
权限申请 TRRO_requestPermission(gwid, master/guest) 接管前申请 master
诊断 TRRO_diagRequestTRRO_OnDiagReport 排障 JSON 报告
转推 CDN TRRO_startMediaPush(conn_fd, rtmp_url) 旁路录制/监管
导航线(实验) TRRO_simpleNavigationLine / TRRO_cameraViewNavigationLine 工程机械 AR 辅助线
远程调码率 TRRO_fieldDeviceEncodeConfig(gwid, stream_id, json) 操控端动态改现场编码参数

6.3 官方能力清单对照

远端设备端文档 列出的能力与头文件一致:视频渲染、H264/H265/AV1 解码、低延迟传输、二进制透传、推流管理、延时/链路报告、本地录制(Android 有,iOS 无)。

现场设备端文档 侧重:视频处理(采集/缩放/剪裁/拼接)、硬编、传输、二进制透传、推流自管理、断网重连。

6.4 接管权限流程(master / guest)

工业遥操要求 同一现场设备同一时刻仅一个 master 可发控;guest 仅观看。
现场设备 TRRO 云端 操控端B 操控端A 现场设备 TRRO 云端 操控端B 操控端A #mermaid-svg-M6F6VFpBvVQoF4IZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-M6F6VFpBvVQoF4IZ .error-icon{fill:#552222;}#mermaid-svg-M6F6VFpBvVQoF4IZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-M6F6VFpBvVQoF4IZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-M6F6VFpBvVQoF4IZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-M6F6VFpBvVQoF4IZ .marker.cross{stroke:#333333;}#mermaid-svg-M6F6VFpBvVQoF4IZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-M6F6VFpBvVQoF4IZ p{margin:0;}#mermaid-svg-M6F6VFpBvVQoF4IZ .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-M6F6VFpBvVQoF4IZ text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-M6F6VFpBvVQoF4IZ .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-M6F6VFpBvVQoF4IZ .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-M6F6VFpBvVQoF4IZ .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-M6F6VFpBvVQoF4IZ .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-M6F6VFpBvVQoF4IZ #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-M6F6VFpBvVQoF4IZ .sequenceNumber{fill:white;}#mermaid-svg-M6F6VFpBvVQoF4IZ #sequencenumber{fill:#333;}#mermaid-svg-M6F6VFpBvVQoF4IZ #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-M6F6VFpBvVQoF4IZ .messageText{fill:#333;stroke:none;}#mermaid-svg-M6F6VFpBvVQoF4IZ .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-M6F6VFpBvVQoF4IZ .labelText,#mermaid-svg-M6F6VFpBvVQoF4IZ .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-M6F6VFpBvVQoF4IZ .loopText,#mermaid-svg-M6F6VFpBvVQoF4IZ .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-M6F6VFpBvVQoF4IZ .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-M6F6VFpBvVQoF4IZ .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-M6F6VFpBvVQoF4IZ .noteText,#mermaid-svg-M6F6VFpBvVQoF4IZ .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-M6F6VFpBvVQoF4IZ .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-M6F6VFpBvVQoF4IZ .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-M6F6VFpBvVQoF4IZ .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-M6F6VFpBvVQoF4IZ .actorPopupMenu{position:absolute;}#mermaid-svg-M6F6VFpBvVQoF4IZ .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-M6F6VFpBvVQoF4IZ .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-M6F6VFpBvVQoF4IZ .actor-man circle,#mermaid-svg-M6F6VFpBvVQoF4IZ line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-M6F6VFpBvVQoF4IZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 非 master 调用 sendControlData → TRRO_UNAUTHORIZED TRRO_requestPermission(gwid, master) TRRO_onOperationPermissionRequest TRRO_setOperationPermission(R1, master) TRRO_OnOperationPermissionState(self=master) TRRO_requestPermission(gwid, master) 新 master 覆盖旧 master(仅一个 master)

角色 权限 API
guest 观看、拉流 TRRO_connectField
master 观看 + TRRO_sendControlData TRRO_requestPermission → 现场端 TRRO_setOperationPermission

白名单 / 临时观看:TRRO_setSessionPermissionToken(gwid, signature)(未注册设备临时授权)。

6.5 各平台 SDK 产物矩阵

现场设备端(Field / Gateway)
平台 官方包 核心产物 备注
Linux aarch64 trro-gateway-sdk-release-aarch64 trro_field.h + 三分库 + ffmpeg3/ sdk_lib/nvidia(Jetson)、sdk_lib/soft(通用 ARM + RK 加速)
Linux x64 trro-gateway-sdk-release-x64 同上(无 nvidia/soft 分目录的精简包) run_loader_x64.sh
Android 控制台 AAR + trro_gateway_demo_android TrroGateway Java API app/libs/*.aar,minSdk 24
远端设备端(Remote / Controller)
平台 官方包 核心产物 备注
Linux x64 trro-controller-sdk-linux_x64_release trro_remote.h + 三分库 + FFmpeg third_lib/ lib_install.sh 创建 .so 软链
Windows x64 trro_remote_sdk-win_x86 trro_remote.dll + 头文件 文件夹名 win_x86 易误解,MD5 为 x64 DLL
iOS TRROControl.framework ObjC:TrroRemoteTrroGatewayTrroMedia PrivacyInfo.xcprivacy
Web trro_web_sdk_v2.4.0_r67 index.js(内嵌 v2.4.7.0)+ TS 声明 Chrome/Edge 84+;公有云/国际站/私有化 Demo HTML
Android 控制台 AAR + demo TrroRemote 与 Unity 共用 remoteuinty-release.aar
HarmonyOS 控制台 HAR + demo ArkTS API 依赖 sdklibrary.har
Unity demo Plugins Windows:trro_remote.dllrtc_*.dll、FFmpeg 60/58/9/7/4 系 DLL 组 Android:remoteuinty-release.aar;Unity 2021.3+,GLES 3.1

Unity Windows 插件依赖链 (Demo meta 引用,须完整拷贝):trro_remote.dllrtc_media.dllrtc_engine.dllavcodec-60.dll / avformat-60.dll / avutil-58.dll / swscale-7.dll 等 + libcurl.dll + OpenGL/DX 运行库。

6.6 官方 Demo 与语言绑定

Demo 工程 平台 语言/框架 说明
trro_gateway_demo_linux Linux C++ 外部 YUV/H264/H265/JPEG 推流
trro_gateway_demo_android Android Java 现场 TrroGateway 集成示例
trro_gateway_python Linux aarch64 Python ctypes 需放入现场 SDK 的 nvidia/soft 库路径
trro_remote_demo_win_linux Linux x64 + Win x64 Qt 5.13 C++ 多路拉流、布局、诊断;git 分支 v2.4.1
trro_remote_demo_ios iOS ObjC + CocoaPods 本地 pod 集成 TRROControl + rtc_engine.xcframework
trro_remote_demo_android Android Java 远端拉流
trro_remote_demo_harmony HarmonyOS ArkTS sdklibrary.har
trro_remote_go Linux x64 Go CGO trro_remote.go 封装 C API
trro_remote_java Linux Java JNA TrroJavaAPI.java
trro_remote_python Linux x64/aarch64 + Win x64 Python 三套 SDK 目录
trro_remote_unity Android + Windows Unity C# TrroInterface.cs / TrroCallbackInterface.cs

Web SDK 典型流程index.d.ts):初始化 TRROSDK → 配置 CloudModepublic / public_intl / private)→ 连接现场 gateway → 订阅 track → 收发 control data → 断开。信令状态机含 scheduling / scheduled / reconnecting 等,与 Native SignalStatekTrroReady / kTrroLost / kTrroReup)概念对应但枚举名不同。

设备指纹与 License :现场包提供 GetDeviceInfo 工具读取设备指纹;TRRO_initGwPathWithLicense(config, license.txt, mode) 校验 License(错误码 TRRO_INIT_LICENSE_CHECK_*TRRO_INIT_PUBLIC_LICENSE_CHECK_*)。新用户可申请 2 周免费试用 License(2 个授权)。

6.7 官方 Demo 胶水层实现详解

官方 Demo 仓库的价值之一,是展示 如何把 C flat API 接到各语言运行时 。除 Android / iOS / HarmonyOS / Web 走 官方预封装 SDK 外,Linux/Windows 侧 Demo 普遍采用 「C ABI → 薄绑定 → 业务逻辑」 三层结构;绑定层只负责加载 .so/.dll、声明函数签名、把 C 函数指针回调桥回宿主语言,不重复实现信令/媒体栈
#mermaid-svg-WylR152dWCvPcDDf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WylR152dWCvPcDDf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WylR152dWCvPcDDf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WylR152dWCvPcDDf .error-icon{fill:#552222;}#mermaid-svg-WylR152dWCvPcDDf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WylR152dWCvPcDDf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WylR152dWCvPcDDf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WylR152dWCvPcDDf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WylR152dWCvPcDDf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WylR152dWCvPcDDf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WylR152dWCvPcDDf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WylR152dWCvPcDDf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WylR152dWCvPcDDf .marker.cross{stroke:#333333;}#mermaid-svg-WylR152dWCvPcDDf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WylR152dWCvPcDDf p{margin:0;}#mermaid-svg-WylR152dWCvPcDDf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-WylR152dWCvPcDDf .cluster-label text{fill:#333;}#mermaid-svg-WylR152dWCvPcDDf .cluster-label span{color:#333;}#mermaid-svg-WylR152dWCvPcDDf .cluster-label span p{background-color:transparent;}#mermaid-svg-WylR152dWCvPcDDf .label text,#mermaid-svg-WylR152dWCvPcDDf span{fill:#333;color:#333;}#mermaid-svg-WylR152dWCvPcDDf .node rect,#mermaid-svg-WylR152dWCvPcDDf .node circle,#mermaid-svg-WylR152dWCvPcDDf .node ellipse,#mermaid-svg-WylR152dWCvPcDDf .node polygon,#mermaid-svg-WylR152dWCvPcDDf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WylR152dWCvPcDDf .rough-node .label text,#mermaid-svg-WylR152dWCvPcDDf .node .label text,#mermaid-svg-WylR152dWCvPcDDf .image-shape .label,#mermaid-svg-WylR152dWCvPcDDf .icon-shape .label{text-anchor:middle;}#mermaid-svg-WylR152dWCvPcDDf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WylR152dWCvPcDDf .rough-node .label,#mermaid-svg-WylR152dWCvPcDDf .node .label,#mermaid-svg-WylR152dWCvPcDDf .image-shape .label,#mermaid-svg-WylR152dWCvPcDDf .icon-shape .label{text-align:center;}#mermaid-svg-WylR152dWCvPcDDf .node.clickable{cursor:pointer;}#mermaid-svg-WylR152dWCvPcDDf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WylR152dWCvPcDDf .arrowheadPath{fill:#333333;}#mermaid-svg-WylR152dWCvPcDDf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WylR152dWCvPcDDf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WylR152dWCvPcDDf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WylR152dWCvPcDDf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WylR152dWCvPcDDf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WylR152dWCvPcDDf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WylR152dWCvPcDDf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WylR152dWCvPcDDf .cluster text{fill:#333;}#mermaid-svg-WylR152dWCvPcDDf .cluster span{color:#333;}#mermaid-svg-WylR152dWCvPcDDf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WylR152dWCvPcDDf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WylR152dWCvPcDDf rect.text{fill:none;stroke-width:0;}#mermaid-svg-WylR152dWCvPcDDf .icon-shape,#mermaid-svg-WylR152dWCvPcDDf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WylR152dWCvPcDDf .icon-shape p,#mermaid-svg-WylR152dWCvPcDDf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WylR152dWCvPcDDf .icon-shape .label rect,#mermaid-svg-WylR152dWCvPcDDf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WylR152dWCvPcDDf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WylR152dWCvPcDDf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WylR152dWCvPcDDf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Native 三分库
C ABI
胶水层
Demo 业务层
Qt / Tk / main.go / Demo.java
Go CGO
Python ctypes
Java JNA
Unity P/Invoke
Android AAR JNI
trro_field.h / trro_remote.h
libtrro_field / libtrro_remote
librtc_media + librtc_engine
FFmpeg .so/.dll

6.7.1 总览:六种胶水模式
Demo 工程 胶水技术 加载的 Native 回调桥接 Demo 层额外工作
trro_gateway_demo_linux 现场 (C++ 直连) libtrro_field.so + 三分库 + FFmpeg 3.x C 函数指针直接注册 YUV/H264/H265/JPEG 文件推流、控制回环
trro_remote_demo_win_linux 远端 (Qt C++ 直连) libtrro_remote.so / trro_remote.dll Qt lambda → C 回调 多路布局、TRRO_setWindows 硬渲染
trro_remote_go 远端 CGO 同上 + #cgo LDFLAGS 链 FFmpeg C extern → Go //export → Go closure 类型化 Go API、RegisterAllCallback 批量注册
trro_gateway_python 现场 ctypes libtrro_field.so @CFUNCTYPE 装饰器 run_py.shLD_LIBRARY_PATH(nvidia/soft)
trro_remote_python 远端 ctypes libtrro_remote.so / trro_remote.dll @CFUNCTYPE Linux 自渲染 YUV→RGB;Windows 走 TRRO_setWindows
trro_remote_java 远端 JNA libtrro_remote.so 接口 extends Callback 内部类 Native.load 映射全量 C API
trro_gateway_demo_android 现场 AAR + JNI AAR 内 libgateway.so → 三分库 Java TrroGatewayListener 仅调 TrroGateway,不写 JNI
trro_remote_demo_android 远端 AAR + JNI TrroRemote AAR Java TrroRemoteListener TXCloudVideoView 硬渲染
trro_remote_unity 远端 P/Invoke + AndroidJavaObject Win:trro_remote.dll;Android:remoteuinty-release.aar C# delegate / AndroidJavaProxy 平台 #if 分支、纹理/YUV 自渲染
trro_remote_demo_ios 远端 ObjC Framework TRROControl.framework Block / delegate(官方封装) Demo 只调 TrroRemote
trro_remote_demo_harmony 远端 HAR + NAPI sdklibrary.har TrroRemoteListener 接口 ArkTS TrroRemote.getInstance()
Web SDK Demo 远端 无 Native 胶水 浏览器内 JS 栈 TRROSDK 事件回调 独立 WebRTC 实现,非 .so 绑定

共性 :所有 Native 绑定最终都落到 trro_field.h / trro_remote.h 的 C 函数 + 函数指针回调;差异只在「谁帮你写这层映射」------自己写(CGO/ctypes/JNA/P/Invoke)还是官方 AAR/Framework/HAR 已写好。

6.7.2 C/C++ 直连(零胶水)

现场 trro_gateway_demo_linux远端 trro_remote_demo_win_linux 是最「原生」的集成方式:直接 #include "trro_field.h""trro_remote.h",链接 -ltrro_field / -ltrro_remote-lrtc_media -lrtc_engine 与 FFmpeg 依赖。

要点 现场 C++ Demo 远端 Qt Demo
初始化 TRRO_initGwPath("./config.json", mode) TRRO_init() / TRRO_initJsonPath
推流/拉流 TRRO_externalVideoData / 编码帧 API TRRO_connect + TRRO_setWindows
回调 普通 C 函数,如 onControlData 内再 TRRO_sendControlData 回环 TRRO_registerOnState 等,Qt 用 C++11 lambda 作函数指针
构建 Makefile + run_loader.sh 设库路径 QtRemoteDemoApp.pro 按 OS 切换 LIBS / INCLUDEPATH

适用场景:嵌入式 Linux、工控机、已有 C++ 渲染管线(OpenGL/DirectX)的团队;无 GC、无跨语言回调开销,也是其他语言 Demo 的对照基准。

6.7.3 Go CGO(远端)

trro_remote_gotrro/trro_remote.go 中用 CGO 嵌入 C 头文件与静态 inline 注册函数 ,是官方 Demo 里结构最完整的 自研绑定范例

链接声明(编译期固定依赖链):

go 复制代码
#cgo CFLAGS: -I./include
#cgo LDFLAGS: -L./sdk_lib -L./sdk_lib/third_lib \
    -ltrro_remote -lrtc_media -lrtc_engine \
    -lavformat -lavcodec -lavutil -lavdevice -lswresample -lswscale

回调桥接模式(三层):

  1. C 侧:static inline void trro_register_go_callback(void* ctx) 内调用 TRRO_registerAllLatencyCallback(ctx, cgoAllLatencyReportCallback) 等,把 C 函数指针指向 extern 声明。
  2. Go 侧://export cgoAllLatencyReportCallback 导出 C 可调用符号,内部 C.GoString / C.GoBytes 转 Go 类型,再调用户注册的 Go closure。
  3. 应用层:test.gotrro.RegisterSignalStateCallback(nil, func(...) { ... }) 写业务逻辑。

设计要点

  • 包级变量保存各 *Callback 函数指针,防止 GC 回收导致 C 侧悬空指针。
  • RegisterAllCallback 一次性注册 8 类回调,避免应用遗漏。
  • Go 侧对 SignalStateStateCodec 等做了 typed enum,比 ctypes/JNA 更接近「SDK 风格 API」。
6.7.4 Python ctypes(双端)

Python Demo 采用标准库 ctypes,无第三方 FFI 依赖;现场与远端各一份脚本,模式高度相似。

现场 trro_gateway_python/trro_sample.py

python 复制代码
trro_dll = ctypes.CDLL('libtrro_field.so')

@CFUNCTYPE(None, c_void_p, c_int)
def OnSignalConnectionState(context, signal_state):
    if signal_state == 0:
        trro_dll.TRRO_registerControlDataCallback(None, OnControlData)
        trro_dll.TRRO_start()
  • 异步初始化:mode=-1 时先 TRRO_registerSignalStateCallback,在 signal_state==0 后再注册其余回调并 TRRO_start
  • 推流:TRRO_externalVideoData 按帧循环喂 YUV;需 run_py.shsdk_lib/nvidiasoft + ffmpeg3 加入 LD_LIBRARY_PATH

远端 trro_remote_python/trro_demo.py

python 复制代码
if platform.system() == 'Windows':
    trro_dll = ctypes.CDLL('./Win_X64/trro_remote.dll')
    sdk_render = True   # TRRO_setWindows 硬渲染
else:
    trro_dll = ctypes.CDLL('libtrro_remote.so')
    sdk_render = False  # TRRO_registerRemoteFrameCallback 自渲染
  • Linux:注册 image_callback,用 NumPy/PIL 把 I420 转 RGB 在 Tk Canvas 显示。
  • Windows:走 SDK 内部窗口渲染,与 Qt Demo 的 TRRO_setWindows 同类。
  • 需对部分 API 手动设置 argtypes / restype(如 TRRO_initJson),否则 ctypes 默认 c_int 可能传参错误。
6.7.5 Java JNA(远端 Linux)

trro_remote_javaJNA (非 JNI 手写)映射 C API:TrroJavaAPI extends LibraryNative.load("libtrro_remote.so", TrroJavaAPI.class)

机制 说明
API 映射 接口方法名与 C 函数名一致,JNA 按名称解析符号
回调 内部类 implements TRRO_onRemoteFrameDataCallback extends Callback;Windows 注释要求改用 StdCallCallback 配合 trro_remote.dll
指针/数组 视频帧 Pointer data + getByteArray(0, len)int[] conn_fds 直接映射
初始化顺序 TRRO_registerSignalStateCallback 先于 TRRO_initJsonPath(与头文件注释一致)

Demo 的 Demo.java 展示典型流程:注册回调 → TRRO_initJsonPath("./config.json")TRRO_getGwListTRRO_connect → 循环 TRRO_sendControlData

6.7.6 Android AAR + JNI(双端)

Android Demo 不写 JNI,只依赖控制台下载的 AAR;胶水层在 AAR 内部。

调用链(与解压 AAR 结构一致):
#mermaid-svg-HWIzteVunnf3gTqD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HWIzteVunnf3gTqD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HWIzteVunnf3gTqD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HWIzteVunnf3gTqD .error-icon{fill:#552222;}#mermaid-svg-HWIzteVunnf3gTqD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HWIzteVunnf3gTqD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HWIzteVunnf3gTqD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HWIzteVunnf3gTqD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HWIzteVunnf3gTqD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HWIzteVunnf3gTqD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HWIzteVunnf3gTqD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HWIzteVunnf3gTqD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HWIzteVunnf3gTqD .marker.cross{stroke:#333333;}#mermaid-svg-HWIzteVunnf3gTqD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HWIzteVunnf3gTqD p{margin:0;}#mermaid-svg-HWIzteVunnf3gTqD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HWIzteVunnf3gTqD .cluster-label text{fill:#333;}#mermaid-svg-HWIzteVunnf3gTqD .cluster-label span{color:#333;}#mermaid-svg-HWIzteVunnf3gTqD .cluster-label span p{background-color:transparent;}#mermaid-svg-HWIzteVunnf3gTqD .label text,#mermaid-svg-HWIzteVunnf3gTqD span{fill:#333;color:#333;}#mermaid-svg-HWIzteVunnf3gTqD .node rect,#mermaid-svg-HWIzteVunnf3gTqD .node circle,#mermaid-svg-HWIzteVunnf3gTqD .node ellipse,#mermaid-svg-HWIzteVunnf3gTqD .node polygon,#mermaid-svg-HWIzteVunnf3gTqD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HWIzteVunnf3gTqD .rough-node .label text,#mermaid-svg-HWIzteVunnf3gTqD .node .label text,#mermaid-svg-HWIzteVunnf3gTqD .image-shape .label,#mermaid-svg-HWIzteVunnf3gTqD .icon-shape .label{text-anchor:middle;}#mermaid-svg-HWIzteVunnf3gTqD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HWIzteVunnf3gTqD .rough-node .label,#mermaid-svg-HWIzteVunnf3gTqD .node .label,#mermaid-svg-HWIzteVunnf3gTqD .image-shape .label,#mermaid-svg-HWIzteVunnf3gTqD .icon-shape .label{text-align:center;}#mermaid-svg-HWIzteVunnf3gTqD .node.clickable{cursor:pointer;}#mermaid-svg-HWIzteVunnf3gTqD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HWIzteVunnf3gTqD .arrowheadPath{fill:#333333;}#mermaid-svg-HWIzteVunnf3gTqD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HWIzteVunnf3gTqD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HWIzteVunnf3gTqD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HWIzteVunnf3gTqD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HWIzteVunnf3gTqD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HWIzteVunnf3gTqD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HWIzteVunnf3gTqD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HWIzteVunnf3gTqD .cluster text{fill:#333;}#mermaid-svg-HWIzteVunnf3gTqD .cluster span{color:#333;}#mermaid-svg-HWIzteVunnf3gTqD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HWIzteVunnf3gTqD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HWIzteVunnf3gTqD rect.text{fill:none;stroke-width:0;}#mermaid-svg-HWIzteVunnf3gTqD .icon-shape,#mermaid-svg-HWIzteVunnf3gTqD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HWIzteVunnf3gTqD .icon-shape p,#mermaid-svg-HWIzteVunnf3gTqD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HWIzteVunnf3gTqD .icon-shape .label rect,#mermaid-svg-HWIzteVunnf3gTqD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HWIzteVunnf3gTqD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HWIzteVunnf3gTqD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HWIzteVunnf3gTqD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} System.loadLibrary
Java: TrroGateway / TrroRemote
JNI: libgateway.so / libremote.so
libtrro_field.so / libtrro_remote.so
librtc_media.so + librtc_engine.so
FFmpeg + libc++_shared.so

组件 现场 Gateway AAR 远端 Remote AAR
Java 入口 com.tencent.trro.api.TrroGateway com.tencent.trro.api.TrroRemote
Native 桥 libgateway.soGatewayNative Remote 侧对应 JNI 库
捆绑库 libtrro_field.so、三分库、FFmpeg 6.x 系、libc++_shared.so libtrro_remote.so 及同构依赖
ABI Demo AAR 常见 仅 arm64-v8a 同左,集成时需与目标设备 ABI 匹配
Demo 用法 initWithOptionsstart(TXCloudVideoView) initWithOptionsconnectList + TrroRemoteListener

Unity Android 分支则走 com.tencent.remote.uinty.TrroRemoteUnityAPIremoteuinty-release.aar),与纯 Java Demo 的 TrroRemote同一 Native 栈、不同 Java 封装

6.7.7 Unity 双路径(P/Invoke + AndroidJavaObject)

trro_remote_unity/Assets/Demo/TrroInterface.cs预处理器分平台,是「一套 C#、两种胶水」的典型:

平台 绑定方式 关键类型
Windows / Editor [DllImport("trro_remote.dll", CallingConvention = CallingConvention.Cdecl)] [UnmanagedFunctionPointer(CallingConvention.StdCall)] delegate
Android new AndroidJavaObject("com.tencent.remote.uinty.TrroRemoteUnityAPI") AndroidJavaProxy 实现 TrroUnityListenerInterface

Windows 路径 :直接 P/Invoke C API,与 C++ Demo 等价;Plugins 目录须带齐 rtc_media.dllrtc_engine.dll、FFmpeg 60/58/7/4 系 DLL(见 §6.5)。

Android 路径 :C# 不加载 libtrro_remote.so,全部经 Java 层回调;TrroListeneronStateonAllLatencyCallback 等转发到 TrroCallbackInterface 单例,再驱动 Unity UI。

注意 :头文件 Windows 导出可用 __stdcallUSE_CSHARP),但 Unity Demo 对 DLL 使用 CallingConvention.Cdecl------以 Demo 实际写法为准,集成时不要混用约定。

6.7.8 iOS / HarmonyOS / Web(官方封装,Demo 无自研胶水)

这三类 Demo 不包含 CGO/ctypes/JNA 式自研绑定,直接消费官方高级 API:

平台 Demo 入口 封装形态 Demo 职责
iOS trro_remote_demo_ios TRROControl.frameworkTrroRemoteTrroGateway ObjC 类) CocoaPods 集成;getGwList → 拉流 UI
HarmonyOS trro_remote_demo_harmony sdklibrary.har(ArkTS TrroRemoteTrroOptions TrroRemoteListener 实现各回调;TXCloudVideoView 渲染
Web trro_web_sdk HTML Demo TRROSDK(TS 声明 index.d.ts 浏览器 WebRTC + 独立信令;与 Native C ABI 无直接链接关系

若只需「快速集成」,优先用官方 AAR/Framework/HAR/Web SDK;若需 Linux 服务端/工控进程 深度定制,参考 Go CGOPython ctypes Demo 自建绑定层。


7. 接入要点与踩坑

7.0 完整 SDK 与二进制部署

  • TRRO 控制台 下载对应平台 完整 SDK (含 .so/.dll/.aar),Demo 仓库通常 不含 运行时库。
  • 现场 aarch64 运行前确认 run_loader.shLD_LIBRARY_PATH 指向 nvidiasoft 变体 + ffmpeg3
  • 远端 Linux 首次集成执行 ./lib_install.sh [目标目录] 创建 FFmpeg 软链。
  • Unity/Android 须将 Plugins 下全部 DLL/so 一并打包,缺任一 FFmpeg 依赖会导致加载失败。

7.1 配置生成

  • 公有云推荐:控制台配置工具
  • 私有化最小配置:device_id + server_ip:2883,上线后再通过 http://serverip:8190/config_template 下发视频流配置

7.2 安全

  • Demo 中 device_id + passwordconfig.json 明文------生产应配合设备证书、License 绑定、一机一密
  • 控制通道 master 权限必须走 TRRO_requestPermission → 现场端 TRRO_setOperationPermission 仲裁,避免多操控端冲突;非 master 发控会返回 TRRO_UNAUTHORIZED

7.3 多网部署

Multipath 完整原理、配置项与 POC 清单见 §4.5。此处仅列最易踩坑项:

  • OS 未配策略路由network_bind 写了但两路打出同一公网 IP → Multipath 无效
  • 缺权限 :未 setcap / root → 绑定网卡失败
  • 视频与控制策略混淆 :视频是融合调度,控制默认双发;关 dc_double_trans_enable 后控制延迟特性会变
  • 计费:多网约 ×1.2 带宽系数,可按场景 selective 开启
bash 复制代码
sudo setcap cap_net_raw,cap_net_bind_service+ep ./trro-test

7.4 初始化模式与线程安全

API 模式 说明
现场 TRRO_initGwPath(..., mode=0) 同步 阻塞至信令 kTrroReady
现场 TRRO_initGwPath(..., mode=-1) 异步 通过 TRRO_onSignalState 通知
远端 TRRO_initJsonAsync 异步 结果经 TRRO_onSignalState / TRRO_OnErrorEvent

回调线程TRRO_OnConnectCostTRRO_OnErrorEvent 等均在 SDK 内部线程触发------勿在回调内阻塞;耗时逻辑转工作线程。

7.5 控制通道限流(易忽略)

除 QoS 0/1 外,头文件还定义(活跃会话下):

  • 单条消息长度上限
  • 1 秒内 累计发送量上限(超限 TRRO_MESSAGE_MAX_EXCEED
  • 3 秒内 消息条数上限(TRRO_MESSAGE_RATE_EXCEED
  • 发送缓冲区满(TRRO_MESSAGE_BLOCK

100Hz 控制需应用层 打包聚合 (多轴杆量合并为一帧二进制),而非 100 次/秒单独调用 sendControlData

7.6 帧级对齐(数采)

推荐路径:

  1. 采集端用 TRRO_externalVideoDataWithUserTimeTRRO_externalEncodeVideoDataUserTime 打统一单调时钟戳
  2. 控制指令同帧打包或在应用层维护 (user_time, control_state) 序列
  3. 远端通过 TRRO_onAllLatencyReportvideotime + rcct 做闭环监控
  4. POC 验收时区分 G2G vs VCCT vs RCCT

7.7 语言绑定层踩坑(Demo 胶水层)

绑定方式 常见坑 建议
ctypes 未设 argtypes/restype 导致栈破坏或返回值错误 TRRO_initJsonTRRO_connect 等显式声明;Linux 必须配 LD_LIBRARY_PATH
ctypes 回调 回调对象被 GC 回收 → 段错误 用模块级变量持有 @CFUNCTYPE 函数引用
Go CGO 回调 closure 未保存到包级变量 与 Demo 相同,用全局变量存 *Callback
JNA Linux .soCallback;Windows .dllStdCallCallback TrroJavaAPI.java 注释切换;回调内避免阻塞
JNA / CGO 线程 C SDK 在内部线程调回调 回调内只做轻量转发,重逻辑丢工作线程(见 §7.4)
Unity P/Invoke 缺 FFmpeg/rtc DLL → DllNotFoundException Plugins 整包拷贝(§6.5);CallingConvention 与 Demo 一致
Unity Android 误在 Android 分支再 P/Invoke .so 必须走 TrroRemoteUnityAPI + AndroidJavaProxy
Android AAR 仅 arm64-v8a、缺 libc++_shared.so 核对 AAR 内 jni/ ABI;与 NDK 版本兼容
Python 现场 nvidia/soft 库选错 run_py.sh 与 Jetson/通用 ARM 硬件匹配
Python 远端 Linux 未注册 RemoteFrameCallback 却期望画面 Windows 用 TRRO_setWindows;Linux 需自渲染或改走硬渲染 API

8. 一句话总结

TRRO 是一套面向工业遥操的 C 语言双端 SDK (Web 为独立 JS 实现):现场端 libtrro_field 负责多路采集/编码/按需推流/收控,远端端 libtrro_remote 负责多路拉流/渲染/发控;底层以 WebRTC 三分库(librtc_engine + librtc_media)+ FFmpeg 做低延迟媒体,以 MQTT(paho.mqtt.c) 做设备信令,以 独立二进制控制通道 承载高频遥操数据;Multipath 在 OS 策略路由 + network_bind 之上,对视频做 融合调度 、对控制默认 双发冗余 ,并内建 master/guest 权限、VCCT/RCCT 时延度量 等工业遥操能力。官方支持 Linux / Windows / Android / iOS / Web / HarmonyOS 全栈远控,现场以 Linux ARM/x64 + Android 为主。


9. 延伸阅读

资源 说明
多网络路径传输(官方) network_bindmedia_trans_mode、路由示例
多网聚合与切换(社区) Multipath 工程原理与 <50ms 切换含义
物联网卡白名单配置 多网 network_bind 带 DNS
免费试用 License 2 周 2 授权
腾讯云 TRRO 产品 指标、试用、FAQ
现场设备端 SDK 文档 官方 API 与能力说明
远端设备端 SDK 文档 官方 API 与能力说明
TRRO 控制台配置工具 生成 config.json
腾讯云 TRRO 产品 指标、试用、FAQ
TRRO 控制台下载 各平台完整 SDK

文档版本对照以官方 2.4.3 文档与 Web SDK 内嵌 2.4.7.0 为准;C Native 以运行时 TRRO_getSdkVersion() 为准。

相关推荐
字节跳动视频云技术团队2 小时前
拒绝被剧透!解密大型赛事直播背后的超低延迟黑科技
人工智能·音视频开发·直播
阿拉斯攀登4 小时前
FFmpeg 入门:命令行的 20 个常用场景
ffmpeg·音视频·webrtc·视频编解码
ai产品老杨14 小时前
H264 H265视频分析常见问题和排查清单
人工智能·算法·音视频
“码”力全开15 小时前
AI视频分析API性能优化指南
人工智能·性能优化·音视频
美狐美颜SDK开放平台17 小时前
Android/iOS直播APP平台开发中的视频美颜SDK优化技巧
android·ios·音视频·美颜sdk·第三方美颜sdk
AI服务老曹18 小时前
视觉算法模型管理完整流程:多版本上线、灰度发布与回滚的落地实践
人工智能·docker·音视频
AaronZZH20 小时前
AAF 框架能力介绍:图文音视频一站式 AIGC 模块上线
aigc·音视频
Mister Leon21 小时前
视频时序数据处理:CNN+LSTM
cnn·音视频·lstm
俊哥工具1 天前
解决文件正在使用无法删除,顽固文件清理工具超好用
智能手机·电脑·word·音视频·媒体