本文介绍基于 RK3588 的完整视频推流链路方案,涵盖 MIPI 摄像头采集、OpenCV 图像处理、硬件 H.264 编码及 WebRTC 低延迟推流。
整体架构思路
主要功能使用 Python 实现:
- 画面采集:使用 GStreamer 直接对接底层驱动,利用 RK3588 的硬件 ISP 把 MIPI RAW 数据转成彩色的缩小画面。
基于 RK3588 平台的 MIPI 摄像头采集、OpenCV 图像处理、硬件 H.264 编码及 WebRTC 低延迟推流的完整方案。通过 GStreamer 对接底层驱动,利用 MediaMTX 作为流媒体服务器,实现了从采集到网页端秒开观看及客户端无损录像的全链路。文章提供了环境配置、核心 Python 脚本代码、避坑指南及性能优化建议,重点解决了内存映射异常、端口访问错误及画面延迟等问题。
本文介绍基于 RK3588 的完整视频推流链路方案,涵盖 MIPI 摄像头采集、OpenCV 图像处理、硬件 H.264 编码及 WebRTC 低延迟推流。
主要功能使用 Python 实现:
mpph264enc(瑞芯微硬件编码器)压缩,推给本机的流媒体服务器。MediaMTX 作为流媒体服务器,客户端通过 WebRTC 协议实现网页端秒开与超低延迟观看。/dev/video11)。确保安装了带 GStreamer 支持的 OpenCV 和相关插件(注意 pypi 上的 opencv 默认不支持 gstreamer,建议直接下载系统环境的 opencv,或者手动编译):
sudo apt-get update
sudo apt-get install python3-opencv
sudo apt-get install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-rtsp
建议在板子上跑服务器,这样客户端不需做任何配置。
在 RK3588 上下载 ARM64 版本并运行:
wget https://github.com/bluenviron/mediamtx/releases/download/v1.16.1/mediamtx_v1.16.1_linux_arm64.tar.gz
tar -zxvf mediamtx_v1.16.1_linux_arm64.tar.gz
./mediamtx
你应该能看到以下输出:
user@rk3588:~/Downloads$ ./mediamtx
2026/02/21 15:07:07 INF MediaMTX v1.16.1, linux, arm64
2026/02/21 15:07:07 INF configuration loaded from /home/user/Downloads/mediamtx.yml
2026/02/21 15:07:07 INF [RTSP] listener opened on :8554 (TCP/RTSP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
2026/02/21 15:07:07 INF [RTMP] listener opened on :1935
2026/02/21 15:07:07 INF [HLS] listener opened on :8888
2026/02/21 15:07:07 INF [WebRTC] listener opened on :8889 (HTTP), :8189 (ICE/UDP)
2026/02/21 15:07:07 INF [SRT] listener opened on :8890 (UDP)
(保持此终端不关,另外打开新的终端)
新建一个 Python 脚本 stream.py。这段代码包含了降分辨率、防缓存延迟和调用 MPP 硬件编码的核心参数。
import cv2
import time
class FPSCounter:
"""FPS counter class"""
def __init__(self, buffer_size=20):
self.timestamps = []
self.buffer_size = buffer_size
def update(self):
"""Update FPS count"""
current_time = time.time()
self.timestamps.append(current_time)
# Keep only recent timestamps
if len(self.timestamps) > self.buffer_size:
self.timestamps.pop(0)
def get_fps(self):
"""Calculate current FPS"""
if len(self.timestamps) < 2:
return 0.0
time_span = self.timestamps[-1] - self.timestamps[0]
if time_span <= 0:
return 0.0
return (len(self.timestamps) - 1) / time_span
# 1. 配置读取摄像头的 GStreamer Pipeline (根据你的 MIPI 摄像头节点调整,这里假设是 /dev/video11)
# 强制设定分辨率和帧率,并转换为 BGR 格式给 OpenCV 处理
cap_pipeline = (
"v4l2src device=/dev/video11 io-mode=2 ! "
"video/x-raw, width=640, height=480, framerate=30/1, format=NV12 ! "
"videoconvert ! video/x-raw, format=BGR ! "
"appsink max-buffers=1 drop=true"
)
# 2. 配置推流的 GStreamer Pipeline
# appsrc 接收 OpenCV 的 BGR 图像,转为 NV12,交给 mpph264enc 硬编,然后推流给 MediaMTX
push_pipeline = (
"appsrc is-live=true ! "
"video/x-raw, format=BGR, width=640, height=480, framerate=30/1 ! "
"videoconvert ! video/x-raw, format=NV12 ! "
"mpph264enc bps=4000000 rc-mode=vbr ! "
"h264parse ! "
"rtspclientsink location=rtsp://127.0.0.1:8554/live protocols=tcp"
)
# 初始化视频读取
cap = cv2.VideoCapture(cap_pipeline, cv2.CAP_GSTREAMER)
if not cap.isOpened():
print("错误:无法打开 MIPI 摄像头。请检查节点和 ISP 状态。")
exit()
# 初始化视频推流器
out = cv2.VideoWriter(push_pipeline, cv2.CAP_GSTREAMER, 0, 30, (640, 480))
if not out.isOpened():
print("错误:无法初始化 GStreamer 推流器。")
exit()
print("成功启动采集和推流,按 'Ctrl+C' 停止。")
try:
fps_counter = FPSCounter()
while True:
ret, frame = cap.read()
if not ret:
print("未能读取到画面")
break
# ==========================================
# ★ 在这里加入你的 AI 推理代码 ★
# ==========================================
# 例如:
# results = rknn_model.inference(frame)
# frame = draw_bounding_boxes(frame, results)
fps_counter.update()
fps = fps_counter.get_fps()
# 作为演示,我们在这里加上时间戳和 fps
cv2.putText(frame, f"Time: {time.ctime()}", (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1)
cv2.putText(frame, f"Fps: {fps}", (30, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 1)
# ==========================================
# 将画好框的处理后图像,写入推流管道(由 mpp 硬件编码)
out.write(frame)
except KeyboardInterrupt:
print("停止推流...")
finally:
cap.release()
out.release()
运行脚本:python3 stream.py
此时,你的 RK3588 已经变成了一个 IP 摄像头。假设你的板子局域网 IP 是 192.168.0.137。
1. 低延迟观看(网页直开)
直接在电脑/手机浏览器里输入:http://192.168.0.137:8889/live (这里的端口号在之前 MediaMTX 的输出中能看到)。利用 WebRTC 协议,延迟基本在百毫秒以内。
2. 在客户端无损录像(不需板端 CPU 占用) 想要在电脑上把刚才的监控视频存下来?只需要一行命令,直接将底层编好的 H.264 流封装成文件,完全不消耗客户端算力: 在电脑上安装 ffmpeg(windows / linux / mac 均可),运行:
ffmpeg -rtsp_transport tcp -i rtsp://192.168.0.137:8554/live -c copy -f mp4 record_video.mp4
# 注意这里的端口号选的是 8554(rtsp)
以下是纯推流,基本没有图像处理的资源消耗。
延迟的话,体感上在 1 秒以内,没准确测过。所以实际上还有很大的优化空间。
分享几个过程中最容易卡住的问题:
invalid rtmp version (71)
8889 端口。rkaiq ISP 服务导致画面全是空数据。cap_pipeline、cv2.VideoWriter 和 push_pipeline 三个地方的分辨率参数是否完全一致。appsink max-buffers=1 drop=true。我们直接传图像到 pc 端之所以会卡,只是因为图像没有经过压缩,网络传输速度不够。如果只是单纯想流畅的观看调试图像,可以直接用 opencv 自带的编码函数:
# 编码为 JPEG 格式
success, encoded_img = cv2.imencode(".jpg", img)
然后再通过 flask 之类的框架进行网络传输,好处是简单直接方便,只是性能不高。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online