
文章目录Q1请介绍一下这个智能监控平台的整体架构和数据流Q2RockX 行人检测是怎么集成进推流链路的检测框如何叠加到画面Q3为什么不是每帧都做行人检测你会如何权衡检测频率Q4软硬件 H.264 编码分别怎么做推流封装用的是什么Q5自定义 TCP 协议长什么样注册、心跳、推流控制如何交互Q6Socket 超时、心跳超时、断线重连具体怎么做的还有哪些可改进点Q7从 Web 点击「开始推流」到画面出来完整调用链是什么Q8视频卡顿、设备离线、推流中断你会怎么用 GDB / Wireshark 排查Q9如果推流稳定性出问题你会从采集、编码、网络哪几侧优化Q10自定义协议相对 MQTT/gRPC 有何取舍若让你重构设备通信怎么设计项目要点RockX 行人检测与画面叠加、软硬件 H.264 推流、自定义 TCP注册/心跳/推流控制、Socket/心跳超时与断线重连、GDB/Wireshark 故障排查。项目主链路Web → Server(HTTPTCP) → Device → RTMP 推流 → 流媒体 → Web 拉流。Q1请介绍一下这个智能监控平台的整体架构和数据流这是一个四层监控系统前端 React 负责设备管理和播放监控服务器基于 Muduo同时提供 HTTP API约 8001和设备 TCP 接入约 8081设备端负责注册、心跳、采集、AI 检测、编码和推流流媒体服务器接收设备 RTMP/RTSP 推流供 Web 通过 HLS/HTTP-FLV 拉流播放。用户点击开流后Web 调 HTTP 接口服务器通过长连接 TCP 下发推流命令和 URL设备再推到rtmp://媒体IP/Streaming_Channels/{deviceId}_{channelId}实现远程监控闭环。解析层次关键模块职责Websrc/web设备列表、开/停流、播放ServerMonitoringServerDeviceManagerHTTP 控流、TCP 管设备状态DeviceNetworkStreamManagerPushStreamer协议交互 采集编码推流Medianginx-rtmp 等收推流、对外拉流串起来就是Web ──HTTP──► Server ──TCP──► Device ──RTMP──► 流媒体 ──拉流──► Web 播放「四层」 前端 业务服务器 摄像头设备 流媒体面试官常追问「为什么设备不用 HTTP 轮询」因为开流是服务端主动下发需要长连接保持deviceId → TcpConnection映射。Q2RockX 行人检测是怎么集成进推流链路的检测框如何叠加到画面在 ARM/Rockchip 路径上相机经 RKMedia VI 采集 NV12再经 RGA 送入 AI 线程使用rockx_create加载ROCKX_MODULE_PERSON_DETECTION_V2调用rockx_person_detect做人检测。为降低时延约每 5 帧检测一次中间帧复用上一帧框检测结果用 OpenCV 在 NV12 的 Y 平面上画矩形和文字再把同一块 buffer 送给 VENC 做 H.264 硬件编码因此叠加结果会直接进入推流码流观众端无需再画框。相机采 NV12 → RGA 给 AI → RockX 做人检测约每 5 帧一次→ OpenCV 在画面上画框 → VENC 硬编 H.264 推流。解析Camera/ISP → VI(NV12) → RGA ↓ RockX 检测约 1/5 帧 ↓ OpenCV 画框改 Y 平面 ↓ VENC H.264 → FFmpeg 封装推 RTMP关键实现push_streamer.cpp中rkmedia_vi_rockx_thread()。为何改 Y 平面NV12 亮度在 Y灰度框/字在编码前写入成本低且无需额外叠加图层。独立 Demorkmedia_rockx_person_detection.cpp走 VO 本地显示产品路径走 VENC推流面试时要分清。Q3为什么不是每帧都做行人检测你会如何权衡检测频率单次 RockX 检测大约几十毫秒量级若每帧都跑容易拖垮整条实时链路造成采集积压、编码/推流卡顿。项目里用detect_threshold 5隔帧检测并复用上一帧结果在「框略滞后」和「实时流畅」之间折中。实际还可按分辨率、CPU/NPU 负载、目标运动速度动态调整静止场景可更疏高速移动可更密或把检测放到独立线程并限制队列长度避免阻塞编码线程。解析收益降低 AI 算力占用保证 VENC/推流节奏稳定。代价框有短暂延迟快速穿越画面时可能「跟不上」。可答优化跟踪Track补帧、异步检测最新结果覆盖、按 ROI 检测、降分辨率检测再映射回原图坐标。Q4软硬件 H.264 编码分别怎么做推流封装用的是什么非 ARM/x64 走软件路径V4L2 采集 → 格式转成 YUV420P → FFmpeglibx264编码音频 ALSA → 重采样 → AAC再用 FFmpeg 按 URL 选 FLVRTMP或 RTSP 封装写出。ARM 上视频走 Rockchip VENC 硬件 H.264CBR、NV12 输入编码后的MEDIA_BUFFER转成AVPacket交给同一套 FFmpeg 输出上下文推流音频仍多用软件 AAC。也就是说编码可软可硬推流出口统一走 FFmpeg方便一套逻辑兼容 RTMP/RTSP。解析平台视频编码音频推流x64SwEncoderlibx264AACFFmpeg RTMP/FLV 或 RTSPARMRKVENCH.264AAC软件同上常见追问为何硬编码还要 FFmpeg——VENC 只出裸 H.264RTMP 需要 FLV 复用、时间戳、网络写FFmpeg 负责这一层。Q5自定义 TCP 协议长什么样注册、心跳、推流控制如何交互协议是二进制头 JSON 体魔数0xAA、版本0x01、命令字、payload 长度、messageId、时间戳、16 字节 deviceId后面跟 UTF-8 JSON。设备连上后发REGISTER_REQUEST(0x01)服务器回REGISTER_RESPONSE(0x02)并下发心跳间隔之后设备周期性发HEARTBEAT_REQUEST(0x03)上报状态与各通道是否在推流Web 开流时服务器发STREAM_CONTROL_REQUEST(0x07)含start_stream/stop_stream和streamUrl设备执行后回STREAM_CONTROL_RESPONSE(0x08)。这样控制面走 TCP媒体面走 RTMP职责分离。解析MessageHeader: magic | version | command | length | messageId | timestamp | deviceId[16] JSON payload命令方向作用0x01 / 0x02设备 ↔ 服务器注册0x03 / 0x04设备 ↔ 服务器心跳0x07 / 0x08服务器 ↔ 设备推流控制流地址由服务器分配设备不自己拼业务路径便于统一管理和鉴权扩展。Q6Socket 超时、心跳超时、断线重连具体怎么做的还有哪些可改进点设备连接时设置SO_RCVTIMEO/SO_SNDTIMEO约 5 秒避免阻塞读写卡死收包线程在非阻塞模式下遇EAGAIN短暂休眠继续等。心跳线程按间隔注册后服务器常指定约 5 秒发送若发送失败、对端关闭recv0或致命读错误则走reconnect断开 → 睡约 2 秒 → 重连 → 重新注册失败再隔约 5 秒重试。配置里虽有heartbeatTimeout当前更依赖「TCP 断开判定离线」若要更严应在服务器用定时器扫lastHeartbeatTime超时主动踢下线并通知前端。解析已有机制发送超时、读超时、断线重连、重注册。薄弱点可主动说体现思考设备侧heartbeatTimeout读取后未充分用于业务判定服务器主要靠 TCP close 标离线弱网「假在线」可能存在协议头未统一网络字节序、CRC 设计与实现不完全一致时要讲清风险与兼容前提同端序部署。Q7从 Web 点击「开始推流」到画面出来完整调用链是什么前端请求服务器 HTTP 开流接口MonitoringServer校验设备在线后拼出媒体 URL经 Muduo TCP 连接向设备发STREAM_CONTROL_REQUEST设备Network解析命令Device/StreamManager创建或启动对应通道的PushStreamer采集 →可选 RockX 叠加→ 软/硬编码 → FFmpeg 推 RTMP成功后回STREAM_CONTROL_RESPONSE前端再用返回的播放地址从流媒体拉 HLS/HTTP-FLV。停流则反向发stop_stream停采集编码并断开推流会话。解析步骤清单Web → HTTPstartServer查DeviceManager→ 组 URL → TCP 下发DevicehandleCommand→StartStreamPushStreamer::Start采集/AI/编码/推流线程起来Media 收流就绪 → Web 播放器拉流面试加分说明控制面TCP与媒体面RTMP失败要分别处理例如命令成功但推流失败需把错误带回响应或下次心跳的isStreaming。Q8视频卡顿、设备离线、推流中断你会怎么用 GDB / Wireshark 排查先分层定位卡顿优先看采集是否跟得上、编码耗时、发送阻塞离线看 TCP 是否断、心跳是否停推流中断看 RTMP 握手/写失败还是上游命令没到。GDB 挂设备进程对卡顿线程看调用栈是否堵在 RockX、av_write_frame、VENC GetBuffer对崩溃看 core、空指针和缓冲生命周期。Wireshark 抓设备↔服务器端口看自定义协议帧是否粘包/半包、心跳是否规律抓设备↔媒体 1935 看 RTMP chunk、是否重连、TCP 重传与窗口。两边时间线对齐往往能区分「协议控制断了」还是「媒体链路断了」。解析可复述的排查表现象优先怀疑工具手段画面卡、延迟升AI 过密、编码慢、网络上行不足GDB 栈、耗时日志、CPU设备显示离线TCP 断、重连失败、服务器踢连接Wireshark TCP、服务端连接表有命令无画面URL 错、RTMP 鉴权/拒绝、编码器未出帧Wireshark RTMP、推流日志间歇中断弱网重传、心跳与业务争用、缓冲区满抓包重传率 应用重连日志Q9如果推流稳定性出问题你会从采集、编码、网络哪几侧优化采集侧保证缓冲队列有界、丢旧保新避免积压导致延迟雪崩AI 与编码解耦检测失败不能阻塞送帧到 VENC。编码侧 ARM 优先硬编、合理 GOP/码率 CBR关键帧间隔可调软编则限制 preset/线程防止 CPU 打满。网络侧对 RTMP 写失败快速失败并触发有限次重推控制面 TCP 与媒体面分离心跳只带轻量 JSON必要时降分辨率/帧率做自适应。项目里已通过「隔帧检测 硬编 断线重连」覆盖常见稳定性点线上再补指标推流码率、丢帧、重连次数闭环。解析采集队列长度、背压策略。编码软硬切换、码率、IDR。网络超时、重连退避、与心跳线程协作避免同时狂重试。可量化端到端延迟、重连成功率、平均检测耗时——体现工程化思维。Q10自定义协议相对 MQTT/gRPC 有何取舍若让你重构设备通信怎么设计自定义 TCP 足够轻、与嵌入式设备契合二进制头解析快JSON 体便于扩展字段Muduo 长连接也方便服务端主动推命令。代价是要自己处理粘包半包、心跳租约、重连、版本兼容和安全加密鉴权。若重构我会保留「控制面长连接 媒体面 RTMP」分层协议上明确大端序与长度字段、完整 CRC 或 length-prefix 帧、心跳超时双向强制离线安全上 TLS 或至少 token 注册实现上可用长度字段状态机解析并加命令幂等commandId防止重连后重复开流。解析对比一句话版方案优点缺点自定义 TCP现状可控、轻量、易嵌工程细节多、易有帧/超时漏洞MQTT现成会话与 QoS需 Broker嵌入式集成与运维成本gRPC强契约、流式设备体积与依赖更重结合本项目可主动提当前协议设计里 CRC/字节序等细节与实现不完全对齐时重构应优先「帧格式正确性 心跳租约」再谈功能扩展。