跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

RK3588 MIPI 采集 OpenCV 处理硬件编码推流 WebRTC 低延迟播放

基于 RK3588 平台的 MIPI 摄像头采集、OpenCV 图像处理、硬件 H.264 编码及 WebRTC 低延迟推流的完整方案。通过 GStreamer 对接底层驱动,利用 MediaMTX 作为流媒体服务器,实现了从采集到网页端秒开观看及客户端无损录像的全链路。文章提供了环境配置、核心 Python 脚本代码、避坑指南及性能优化建议,重点解决了内存映射异常、端口访问错误及画面延迟等问题。

涅槃凤凰发布于 2026/4/5更新于 2026/7/2661 浏览

本文介绍基于 RK3588 的完整视频推流链路方案,涵盖 MIPI 摄像头采集、OpenCV 图像处理、硬件 H.264 编码及 WebRTC 低延迟推流。

整体架构思路

主要功能使用 Python 实现:

  1. 画面采集:使用 GStreamer 直接对接底层驱动,利用 RK3588 的硬件 ISP 把 MIPI RAW 数据转成彩色的缩小画面。
  2. OpenCV 处理:OpenCV 拿到图片后,可以进行所需的图像处理或 AI 推理。
  3. 硬件编码推流:将处理后的画面交给 mpph264enc(瑞芯微硬件编码器)压缩,推给本机的流媒体服务器。
  4. 终端分发:使用轻量级 MediaMTX 作为流媒体服务器,客户端通过 WebRTC 协议实现网页端秒开与超低延迟观看。

第一步:环境准备

  1. 确认你的摄像头节点(比如单摄时是 /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

第二步:部署轻量级流媒体服务器 (MediaMTX)

建议在板子上跑服务器,这样客户端不需做任何配置。

在 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 脚本(rtsp 推流与处理)

新建一个 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)

CPU 占用与延迟

以下是纯推流,基本没有图像处理的资源消耗。

延迟的话,体感上在 1 秒以内,没准确测过。所以实际上还有很大的优化空间。

避坑指南

分享几个过程中最容易卡住的问题:

  1. 使用 gstreamer 无法打开摄像头
    • 原因:RK3588 的 V4L2 驱动在处理 MIPI 摄像头和 ISP 内存时,默认的 mmap 内存映射方式有时候在 GStreamer 中会引发异常(特别是在申请 buffer 时)
    • 解法:给 v4l2src 加上 io-mode=4(使用 DMABUF)或 io-mode=2(USERPTR)往往能瞬间解决问题。
  2. MediaMTX 报错 invalid rtmp version (71)
    • 原因:进错端口了!用 HTTP 浏览器去访问了 1935 (RTMP) 或 8554 (RTSP) 端口。
    • 解法:浏览器观看必须要访问 8889 端口。
  3. 推流成功了,但是画面全是'纯绿色'的
    • 原因:OpenCV 推入的画面分辨率和推流器配置的分辨率不匹配,导致内存错位;或者忘记启动 rkaiq ISP 服务导致画面全是空数据。
    • 解法:严格检查 cap_pipeline、cv2.VideoWriter 和 push_pipeline 三个地方的分辨率参数是否完全一致。
  4. 延迟越来越大,跑久了像看回放
    • 原因:加入 AI 推理后处理速度跟不上采集速度,OpenCV 把旧画面全缓存在了内存里。
    • 解法:务必在读取管道末尾加上 appsink max-buffers=1 drop=true。

小贴士

我们直接传图像到 pc 端之所以会卡,只是因为图像没有经过压缩,网络传输速度不够。如果只是单纯想流畅的观看调试图像,可以直接用 opencv 自带的编码函数:

# 编码为 JPEG 格式
success, encoded_img = cv2.imencode(".jpg", img)

然后再通过 flask 之类的框架进行网络传输,好处是简单直接方便,只是性能不高。

目录

  1. 整体架构思路
  2. 第一步:环境准备
  3. 第二步:部署轻量级流媒体服务器 (MediaMTX)
  4. 第三步:核心 Python 脚本(rtsp 推流与处理)
  5. 1. 配置读取摄像头的 GStreamer Pipeline (根据你的 MIPI 摄像头节点调整,这里假设是 /dev/video11)
  6. 强制设定分辨率和帧率,并转换为 BGR 格式给 OpenCV 处理
  7. 2. 配置推流的 GStreamer Pipeline
  8. appsrc 接收 OpenCV 的 BGR 图像,转为 NV12,交给 mpph264enc 硬编,然后推流给 MediaMTX
  9. 初始化视频读取
  10. 初始化视频推流器
  11. 第四步:如何在客户端观看与保存?
  12. 注意这里的端口号选的是 8554(rtsp)
  13. CPU 占用与延迟
  14. 避坑指南
  15. 小贴士
  16. 编码为 JPEG 格式
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • IntelliJ IDEA 快速搭建 Spring Boot 项目指南
  • AI 大模型嵌入模型性能优化:缓存机制与 LangChain 实战
  • 字节跳动 AI 原生 IDE Trae 安装与使用指南
  • C 语言快速排序详解与优化实践
  • 开源纯粹主义与现实困境:当每一颗螺丝钉都要自由
  • 前端加密攻防实战:encrypt-labs 靶场环境搭建与通关解析
  • 基于微服务的智能家居物联网平台
  • Linux Ext2 文件系统深度解析
  • AI 变现误区解析:为何掌握工具不等于拥有商业能力
  • 基于 Python 的 GitHub 热门项目 AI 分析 Agent 实战
  • Python 转行职业规划与核心岗位技能分析
  • Python Flask Web 开发实战:将本地成绩系统升级为在线应用
  • GitHub 加速工具 FastGithub 部署与配置指南
  • AI 大模型入门教程:从零基础到精通
  • 网络安全基础核心知识点梳理与防护策略
  • 基于 Next.js 构建支持 TokenP 钱包登录的 DApp 前端实战
  • 前端地图开发基础:服务类型、坐标系与 SDK 简介
  • ToClaw:不只是炫技 AI,更是易用的桌面工具
  • JetBrains 授权机制解析与合法使用策略指南
  • 贪心算法实战:摆动序列与股票买卖

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online