远程驾驶不是坐在家里开卡车的直播,它要求操作员看到的画面与车辆的实时状态之间的延迟低于人脑感知阈值。超过 200ms,操作员就会感到车辆反应慢半拍,在紧急情况下直接意味着事故。本文以即构科技(ZEGO)的方案为例拆解无人远程控车的实时音视频(RTC) 架构。

一、远程控车对 RTC 的极限要求
| 场景需求 | 核心指标 | 难点 |
|---|---|---|
| 超低延迟画面回传 | 端到端延迟 < 100ms | 控车场景中延迟直接影响操控安全性 |
| 操控指令与画面同步 | 指令延迟 < 50ms | 转向/刹车指令必须与画面帧对齐 |
| 弱网保底 | 画面降级但指令不丢 | 车辆可能进入弱覆盖区 |
| 多路摄像头同时回传 | 前后左右 4 路画面 | 远程驾驶需要 360° 视角 |
| 低码率极限推流 | 640×360@10fps @ 200kbps | 4G 基站切换时上行带宽骤降 |
二、整体架构
┌──────────────────────────────────────────────────────┐
│ 业务层:远程驾驶控制台 │
│ 方向盘信号 · 刹车/油门 · 档位控制 · 仪表盘回传 │
├──────────────────────────────────────────────────────┤
│ RTC 双通道分离 │
│ 画面通道(视频) · 指令通道(信令) │
│ 前/后/左/右摄像头 操控指令 < 50ms │
│ → 低延迟 JitterBuffer → ZEGO 内置信令 │
├──────────────────────────────────────────────────────┤
│ 车载端 │ 远程操控端 │
│ 4 路摄像头自定义采集 │ 拉流 4 路 + 画面拼接 │
│ 指令信令接收执行 │ 自定义渲染 + 方向盘渲染 │
│ → ZEGO Express SDK │ → ZEGO Express SDK │
├──────────────────────────────────────────────────────┤
│ 基础设施层 │
│ SD-RTN™ · 4G/5G · 边缘节点 · NTP 时钟同步 │
└──────────────────────────────────────────────────────┘
三、核心技术实现
3.1 超低延迟视频配置
远程控车场景的关键是 JitterBuffer 设置,不能为画面流畅牺牲延迟:
// 远程控车场景:创建引擎时选择低延迟模式
ZegoEngineProfile profile;
profile.appID = appID;
profile.appSign = appSign;
profile.scenario = ZegoScenario::ZEGO_SCENARIO_DEFAULT; // 默认低延迟
auto engine = ZegoExpressSDK::createEngine(profile, nullptr);
// 设置低码率视频配置
ZegoVideoConfig videoConfig;
videoConfig.encodeWidth = 640;
videoConfig.encodeHeight = 360;
videoConfig.fps = 15;
videoConfig.bitrate = 500; // 500kbps
engine->setVideoConfig(videoConfig);
// 开启硬件编码降低编码延迟
engine->enableHardwareEncoder(true);
// 关闭流量控制(避免自适应码率引入额外延迟)
// 控车场景需要稳定的码率和帧率
engine->enableTrafficControl(false, 0);
3.2 操控指令与画面帧对齐
通过 SEI 帧将车辆的状态信息(速度、转向角、GPS 坐标)嵌入到视频帧中,远程操控端从画面上看到的是带实时数据的仪表盘:
// 车载端:每帧发送车辆状态数据(通过 SEI)
uint64_t ntpNow = getNtpTime();
unsigned char vehicleData[32];
memcpy(vehicleData, &ntpNow, 8); // NTP 时间戳
float speed = getVehicleSpeed(); // 当前速度 km/h
float steering = getSteeringAngle(); // 方向盘角度
memcpy(vehicleData + 8, &speed, 4);
memcpy(vehicleData + 12, &steering, 4);
// 发送 SEI
engine->sendSEI(vehicleData, 16, ZEGO_PUBLISH_CHANNEL_MAIN);
3.3 多路摄像头自定义渲染
远程操控端需要看到 360° 环视画面。通过自定义视频渲染,可以将 4 路摄像头的画面拼接在自定义 UI 中:
// 远程操控端:开启自定义视频渲染
ZegoCustomVideoRenderConfig renderConfig;
renderConfig.bufferType = ZEGO_VIDEO_BUFFER_TYPE_RAW_DATA;
renderConfig.frameFormatSeries = ZEGO_VIDEO_FRAME_FORMAT_SERIES_RGB;
engine->enableCustomVideoRender(true, &renderConfig);
// 设置自定义渲染回调,接收视频帧数据进行拼接
class TeleopRenderHandler : public IZegoCustomVideoRenderHandler {
void onRemoteVideoFrame(const unsigned char** data,
unsigned int* dataLength,
ZegoVideoFrameParam param,
const std::string& streamID,
ZegoPublishChannel channel) override {
// 根据 streamID 判断来自哪个摄像头
// 将前后左右的画面拼接到 360° 环视窗口
stitchToSurroundView(streamID, data[0], param);
}
};
engine->setCustomVideoRenderHandler(new TeleopRenderHandler());
四、FAQ
Q1:远程控车的 RTT 要求是多少?
100ms 以内为优秀,200ms 为可用临界值。超过 300ms 操作员会产生明显延迟感,紧急避障场景不可接受。
Q2:为什么控车场景要关闭流量控制?
流量控制的原理是动态调整码率和帧率适应带宽变化,这会导致画面帧率和码率不稳定。控车场景需要稳定的帧间隔(15fps 即每 66ms 一帧),码率波动会让编码时间不确定,增加端到端延迟方差。
五、总结
无人远程控车是 RTC 在延迟指标上要求最严苛的场景之一。核心思路是:固定码率 + 硬件编码 + JitterBuffer 极低延迟 + 自定义渲染。ZEGO SDK 的场景选择提供了较低的默认延迟,配合 enableHardwareEncoder 和 sendSEI 可实现 100ms 级的端到端画面回传。
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/info/69328.html