🍓 第十章 相机模块与视频串流
📄 一句话概括

串流=编码、封装、传输三层:树莓派用 rpicam-vid 把画面压成 H.264、包进 MPEG-TS、从网口发出去——老教程的【裸 H.264 直接给 VLC】已经失效,VLC 现在不吃裸流,套一层 MPEG-TS 封装就好。

📝 本节和前面几节的关系

10-3 的录像把画面写进文件,本节把同一份画面写进网络——这是【文件 vs 流】的区别。2-5 的 IP 与 SSH 知识是前提(你要知道树莓派的地址);5-1 架过 Web 服务器(HTTP 那条路),本节的浏览器方案就是它的视觉版。10-4 的 picamera2 在结尾露了一手 MJPEG,本节补全它的用法。

一、三层概念:编码、封装、传输

把【串流】拆开,其实就三个动作:

  1. 编码:原始画面每秒上百兆(10-4 算过 178 MiB/秒),必须压缩——树莓派芯片里有硬件 H.264 编码器,一边拍一边压,CPU 几乎不干活
  2. 封装:压缩后的码流包进一个【集装箱】(如 MPEG-TS),方便接收方按帧拆包
  3. 传输:集装箱从网络发出去——TCP(可靠)、UDP(低延迟可丢包)、RTSP(监控行业标准)

老教程失效的原因就在第二层:早年 raspivid | vlc 传的是裸 H.264(不装集装箱),VLC 新版不再支持裸流——照抄老命令,画面黑屏,还以为相机坏了。

二、主线方案:一条命令 TCP 串流(MPEG-TS 封装)

树莓派上(服务器,等待连接):

rpicam-vid -t 0 -n --codec libav --libav-format mpegts -o tcp://0.0.0.0:8080?listen=1

逐段拆读:

电脑上(Windows 的 VLC):菜单【媒体 → 打开网络串流】,输入

tcp://树莓派的IP:8080

(IP 忘了?2-5 的老办法:路由器后台或 hostname -I。)画面即刻出现——这就是一个不要花一分钱的网络监控摄像头。

三、UDP 与 RTSP:各一句话认识

怎么选:自己看画面 → TCP 主线方案最省事;要接现成监控系统 → RTSP;延迟敏感且网络稳 → UDP。

四、浏览器方案:MJPEG(picamera2 出场)

不想装 VLC、想直接浏览器看?用 picamera2 官方自带的 MJPEG 示例服务器:

# 官方示例路径按系统版本略有差异,找到它并运行:
python3 /usr/share/doc/python3-picamera2/examples/mjpeg_server.py

然后浏览器打开 http://树莓派IP:8000——画面直接出现在网页里。

MJPEG 的原理:把每一帧压成 JPEG,连续不断地推给浏览器(HTTP 的 multipart/x-mixed-replace)——本质是【连续的图片】,不是视频流。优点是零门槛(有浏览器就能看);代价是带宽大得多(没有 H.264 压缩的帧间优势),适合低帧率小画面的场景。这正好是 5-1 Web 服务器的亲戚:都是 HTTP 服务,一个送网页、一个送画面。

五、开机自启:systemd 服务一段

监控类项目要【断电重启后自动恢复】,用 4-x 时代见过的 systemd:

# /etc/systemd/system/pistream.service
[Unit]
Description=Pi camera TCP stream
After=network.target

[Service]
ExecStart=/usr/bin/rpicam-vid -t 0 -n --codec libav --libav-format mpegts -o tcp://0.0.0.0:8080?listen=1
Restart=on-failure

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now pistream.service
systemctl status pistream.service    # active (running) 即成功

(写服务文件的注意事项同 4-4 的系统目录规矩:这是系统级配置,放 /etc/systemd/system/。)

六、动手 Demo:完整跑通一次 TCP 串流

准备:树莓派和 Windows 在同一局域网;Windows 装了 VLC(官网免费)。

# 树莓派上:① 查自己的 IP
hostname -I
# ② 起流(参数照抄第二节)
rpicam-vid -t 0 -n --codec libav --libav-format mpegts -o tcp://0.0.0.0:8080?listen=1

Windows 上:VLC → 媒体 → 打开网络串流 → 输入 tcp://上一步的IP:8080 → 播放。

看到什么算成功:VLC 里出现树莓派镜头前的实时画面,延迟约零点几到两秒;树莓派终端无报错持续输出。

读结果:

七、30 秒实验:串流带宽的账

H.264 串流码率按 8 Mbps(兆比特每秒)算:

  1. 每秒传多少 MB?
  2. 连续串流 1 小时,过网多少数据?
  3. Wi-Fi 理论 150 Mbps,同时给两路 8 Mbps 的流够吗?

参考答案:1. 8 Mb ÷ 8 = 1 MB/秒(比特换字节除 8)。2. 1 MB × 3600 = 3.6 GB——串流是持续吃带宽的活儿,看清楚数字再定方案。3. 2 × 8 = 16 Mbps,理论够;但 Wi-Fi 实际有效带宽常打对折还要共享,多路串流优先走有线或降低码率。

八、常见误区

  1. 【照抄老教程 raspivid | cvlc 就能看】 —— 裸 H.264 已不被 VLC 支持,套 MPEG-TS 封装(--codec libav --libav-format mpegts)。
  2. 【忘了 listen=1,客户端连不上】 —— ?listen=1 是【服务器模式:等我】;漏了它会去【主动推】一个不存在的地址。
  3. 【卡顿一定是网速慢】 —— 先降分辨率/帧率再怀疑网络;一次只改一个变量。
  4. 【MJPEG 和 H.264 是一回事】 —— MJPEG 是【连续图片】(每帧独立压缩,带宽大);H.264 利用帧间相似性压缩(带宽小)。浏览器方案图省事、VLC 方案省带宽。
  5. 【端口随便换着用】 —— 树莓派端监听端口与 VLC 里输入的端口必须一致;占用时先 ss -tlnp 查,别瞎换。
自测三问(点开对答案) 1. 串流三层的顺序与各自动作? 2. 老教程 VLC 黑屏的根因是什么、怎么修? 3. 为什么浏览器方案带宽大? **参考答案** 1. **编码**(硬件 H.264 压缩)→ **封装**(包进 MPEG-TS 集装箱)→ **传输**(TCP/UDP/RTSP 发出去)。 2. 裸 H.264 不装封装,新版 VLC 不再支持;修复=加 `--codec libav --libav-format mpegts` 再串流。 3. MJPEG **每一帧都独立压缩成 JPEG**,吃不到 H.264【只传帧间变化】的红利;换来的是零门槛(浏览器直接看)。

相关笔记