RK3588S 离线多模态智能终端 Offline Multimodal Edge AI Assistant based on RK3588S
EdgeSight Assistant 是一个部署在 RK3588S 平台上的离线多模态智能终端项目。
当前仓库优先交付与验证下面这条链路,暂不接入 ASR、Qwen3-VL、TTS 或 GUI:
Logitech C310 (MJPEG, 1280x720@30)
-> FFmpeg V4L2 input + MJPEG decoder
-> FFmpeg h264_rkmpp hardware encoder
-> RTMP/FLV
-> external SRS
程序是一个前台 C++ CLI。摄像头采集、解码、硬件编码和 RTMP 发布均使用 FFmpeg 库;如果 h264_rkmpp 不可用,程序会失败并说明原因,绝不退回软件编码。
目标板须安装包含 V4L2、FLV、RTMP 和 h264_rkmpp 的 Rockchip FFmpeg 运行时及开发包。先检查环境:
scripts/check_dependencies.sh随后创建本地配置、填入 SRS 地址并构建运行:
cp config/config.example.yaml config/config.yaml
scripts/preflight.sh
scripts/run.sh目标板 FFmpeg 安装布局与依赖检查详见 docs/rk3588-dependencies.md。 运行时数据流、资源边界与失败行为见 docs/phase1-architecture.md。
在没有 RK3588S 或 FFmpeg 开发库的开发机上,可只构建并测试配置校验逻辑:
scripts/test.sh配置文件中的 camera.device 有值时优先使用该设备;为空时才会按 camera.camera_name 自动发现。推流 URL 由 stream.server、stream.port、stream.app 和 stream.stream_key 拼成:
rtmp://<server>:<port>/<app>/<stream_key>
对于 C310,建议保留 camera.disable_dynamic_framerate: true。启动脚本会在发布器打开摄像头前设置 UVC 的 exposure_dynamic_framerate=0,避免自动曝光把实际帧率降到约 15 FPS;该控制设置失败时启动也会失败并输出诊断。
使用 Ctrl+C 正常停止。验收过程和记录模板见 docs/phase1-acceptance.md。
Phase 1 完成后,Phase 2 的激活验证契约见
docs/phase2-activation.md。目前已增加可选的
edgesight_audio:它在目标板上读取 C310 的 ALSA 麦克风,调用 sherpa-onnx
KWS,并输出结构化唤醒事件;VAD、唤醒后的 ASR 和最终唤醒词仍未完成验收。
项目使用罗技 C310 摄像头采集视频和麦克风音频,在设备本地完成:
- V4L2 视频采集
- 视频实时编码与网络推流
- 离线 ASR 语音识别
- Qwen3-VL 图像 / 场景理解
- 离线 TTS 语音合成
- ALSA 音频播放
- 用户通过语音对当前摄像头画面进行问答
项目目标是在不依赖云端 AI API 的情况下,实现:
看得见、听得懂、能回答、会说话,同时还能持续推流。
以下是视频推流 MVP 验收后才会规划的长期方向;当前 Phase 1 不实现或验收其中的 AI、音频、GUI、自动重连或音视频合流功能:
Logitech C310
|
+-- V4L2 Video
| |
| +--> Video Encode --> RTMP/RTSP Stream
| |
| +--> Capture Latest Frame
| |
| v
| Qwen3-VL
| |
| v
| Text Answer
|
+-- ALSA Microphone
|
v
Offline ASR
|
v
User Question
|
+------------> Qwen3-VL
|
v
Text Answer
|
v
Offline TTS
|
v
ALSA
|
v
Speaker
目标示例:
用户面对摄像头说:
桌子上有什么?
系统执行:
C310 麦克风
↓
ASR
↓
“桌子上有什么?”
↓
获取当前最新视频帧
↓
Qwen3-VL
↓
“桌子上有一台笔记本电脑和一个水杯。”
↓
TTS
↓
喇叭播放
与此同时,视频推流链路保持持续工作,不等待大模型推理结束。
- Rockchip RK3588S
- Firefly ROC-RK3588S-PC
- Logitech C310 USB Camera
- USB / 3.5mm / HDMI Speaker
- 8GB / 16GB RAM 推荐
- Ubuntu Linux
- Linux
- C / C++
- CMake
- V4L2
- ALSA
- FFmpeg
- Rockchip MPP
- RKNN / RKLLM
- Qwen3-VL
- Offline ASR
- Offline TTS
后续可选:
- Qt 6
- QML
- RTSP
- RTMP
- SRS
- WebSocket / HTTP API
功能:
Audio -> Text
候选方案:
- SenseVoiceSmall
- sherpa-onnx
- Paraformer
- Whisper Tiny / Base
第一版优先考虑:
SenseVoiceSmall / sherpa-onnx
要求:
- 完全离线
- ARM64 可运行
- 尽量支持 C/C++
- 中文识别效果较好
- 尽量降低 CPU / 内存占用
核心模型:
Qwen3-VL-2B
后续阶段可优先使用 2B 版本跑通完整链路。
后续根据 RK3588S 实际性能测试升级:
Qwen3-VL-4B
功能:
- 单帧图像理解
- 场景描述
- Visual Question Answering
- 多帧图像理解
- 简单视频语义理解
第一版不要求逐帧运行 Qwen3-VL。
建议工作模式:
视频:25/30 FPS 持续采集
Qwen3-VL:语音触发 / 手动触发 / 定时抽帧
功能:
Text -> Audio
候选:
- sherpa-onnx TTS
- Piper
- VITS
- MeloTTS
优先要求:
- 完全离线
- ARM64 支持
- 中文支持
- 启动速度快
- 内存占用低
使用:
V4L2
目标设备:
Logitech C310
采集线程必须独立运行。
基础流程:
V4L2
↓
Frame Capture
↓
Latest Frame Buffer
建议使用“最新帧”模型,不为 AI 模块积压大量历史帧。
视频推流链路与 AI 推理链路必须解耦。
推荐结构:
+--> AI Latest Frame
|
V4L2 --> Frame --+
|
+--> Encoder --> RTMP / RTSP
AI 推理变慢时:
不得阻塞视频采集
不得阻塞视频编码
不得阻塞网络推流
优先考虑:
V4L2
↓
MPP Hardware Encoder
↓
H.264 / H.265
↓
RTMP / RTSP
也可以第一版先通过 FFmpeg 完成推流验证。
C310 自带麦克风。
通过 ALSA 获取 PCM 数据。
流程:
ALSA Capture
↓
PCM Buffer
↓
VAD
↓
ASR
后续考虑加入 VAD(Voice Activity Detection),避免持续将静音数据送给 ASR。
推荐第一版采用:
语音触发视觉分析
而不是让 Qwen3-VL 持续分析所有视频帧。
状态流程:
IDLE
↓
检测到用户讲话
↓
录制一段语音
↓
ASR
↓
得到问题文本
↓
获取当前最新视频帧
↓
Qwen3-VL(question + image)
↓
得到回答
↓
TTS
↓
Speaker
↓
IDLE
建议模块:
VideoCaptureThread
AudioCaptureThread
VideoEncodeThread
StreamThread
ASRWorker
VLWorker
TTSWorker
AudioPlaybackThread
线程之间避免直接耦合。
建议使用:
- 有界阻塞队列
- Latest Frame Buffer
- std::mutex
- std::condition_variable
- atomic flag
- shared_ptr / unique_ptr
- RAII
Qwen3-VL 不应该处理视频采集队列中已经过期的帧。
例如:
30 FPS camera
如果一次 VL 推理需要较长时间,则不应该:
frame1
frame2
frame3
...
frame60
排队依次推理。
而应该:
VL Ready
↓
直接读取 latest_frame
旧帧自动被覆盖。
这样可以保证用户问:
“现在画面里面有什么?”
看到的是尽可能新的画面。
EdgeSight-Assistant/
├── README.md
├── CMakeLists.txt
├── config/
│ └── config.yaml
├── include/
│ ├── video/
│ ├── audio/
│ ├── ai/
│ ├── stream/
│ └── common/
├── src/
│ ├── main.cpp
│ ├── video/
│ │ ├── v4l2_capture.cpp
│ │ └── frame_buffer.cpp
│ ├── audio/
│ │ ├── alsa_capture.cpp
│ │ ├── audio_player.cpp
│ │ └── vad.cpp
│ ├── ai/
│ │ ├── asr_engine.cpp
│ │ ├── qwen_vl_engine.cpp
│ │ └── tts_engine.cpp
│ ├── stream/
│ │ ├── video_encoder.cpp
│ │ └── stream_publisher.cpp
│ └── common/
├── models/
│ ├── asr/
│ ├── qwen3_vl/
│ └── tts/
├── scripts/
├── tests/
└── docs/
模型文件不提交 Git。
.gitignore 中应包含:
models/
build/
*.rknn
*.rkllm
*.onnx
*.bin
*.wav
*.mp4
*.log
职责:
- 初始化 V4L2
- 设置分辨率 / FPS / Pixel Format
- mmap buffer
- 获取视频帧
- 更新 latest frame
输入:
PCM audio
输出:
std::string text
输入:
image
question
输出:
answer
接口形式示例:
std::string infer(
const ImageFrame& image,
const std::string& prompt
);输入:
text
输出:
PCM audio
输入:
EncodedPacket
输出:
RTMP / RTSP
不要一开始同时集成所有模型。
完成:
C310 -> V4L2 -> 获取视频
验收:
- 稳定运行
- FPS 正常
- 无持续内存增长
完成:
V4L2 -> Encoder -> RTMP / RTSP
验收:
- 持续推流
- 画面流畅
- 长时间稳定
完成离线 ASR:
C310 Mic -> ALSA -> ASR -> Console Text
完成 Qwen3-VL:
Current Frame + Text Prompt -> Qwen3-VL -> Answer
第一版先使用静态图片验证。
再接入 V4L2 最新帧。
完成 TTS:
Text -> TTS -> ALSA -> Speaker
打通:
Speech
↓
ASR
↓
Question
↓
Current Frame
↓
Qwen3-VL
↓
Answer
↓
TTS
↓
Speaker
保证 AI 工作期间:
视频仍持续推流
完成基础版本后,可增加:
- 多轮对话
- 多帧视觉理解
- 定时场景描述
- 异常事件检测
- VAD
- Wake Word
- Qt GUI
- 对话历史
- 截图
- 视频录像
- Web 管理界面
- REST API
- WebSocket
- RTSP Server
- RTMP 推流
- AI 结果叠加到视频
- AI 文本字幕
- TTS 音频与视频合流
本项目不是让 Qwen3-VL 逐帧处理 30 FPS 视频。
设计目标是:
视频链路:实时
AI 链路:异步
例如:
Video Capture 30 FPS
Video Stream 25~30 FPS
ASR Event Driven
Qwen3-VL Event Driven
TTS Event Driven
后续再测试周期性视觉分析:
0.2 FPS
0.5 FPS
1 FPS
根据 RK3588S 实际性能决定。
需要统计:
- Capture FPS
- Encode FPS
- Stream FPS
- Encode latency
- Stream latency
- Audio duration
- Recognition latency
- Real-time factor
- Vision preprocessing time
- Prefill time
- First token latency
- Decode tokens/s
- Total response latency
- Peak memory
- First audio latency
- Synthesis time
- Real-time factor
- CPU utilization
- NPU utilization
- Memory utilization
- Temperature
- Power consumption
第一版完成以下场景即可认为项目主链路跑通:
- C310 视频能够稳定采集。
- 视频能够持续实时推流。
- C310 麦克风能够正常采集语音。
- ASR 能够离线识别中文问题。
- Qwen3-VL 能够读取当前视频帧。
- Qwen3-VL 能根据用户问题理解画面。
- TTS 能够离线生成中文语音。
- 喇叭能够播放回答。
- AI 推理期间视频推流不中断。
- 整个 AI 主链路无需云端 API。
用户:
你现在看到了什么?
系统:
画面中有一张桌子,桌子上放着一台电脑和一个水杯。
用户:
我的手机在哪里?
系统根据当前画面回答。
另一台电脑通过 RTMP / RTSP 播放器观看实时画面。
用户与设备进行语音问答时:
视频推流保持正常。
该项目重点不是训练大模型,而是:
- RK3588S 大模型部署
- 端侧视觉语言模型
- C++ AI 工程化
- V4L2 视频采集
- ALSA 音频处理
- 硬件视频编码
- 实时网络推流
- 多线程任务调度
- ASR / VLM / TTS 多模型协同
- 边缘多模态 AI 系统设计
RK3588S
|
+----------+----------+
| |
Camera Microphone
| |
V4L2 ALSA
| |
+----+----+ ASR
| | |
Stream Latest Frame Question
| | |
| +-------+--------+
| |
RTMP/RTSP Qwen3-VL
|
Answer
|
TTS
|
ALSA
|
Speaker
最终形成一套完全本地运行的:
Offline Multimodal Edge AI Assistant