串流=编码、封装、传输三层:树莓派用 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,本节补全它的用法。
一、三层概念:编码、封装、传输
把【串流】拆开,其实就三个动作:
- 编码:原始画面每秒上百兆(10-4 算过 178 MiB/秒),必须压缩——树莓派芯片里有硬件 H.264 编码器,一边拍一边压,CPU 几乎不干活
- 封装:压缩后的码流包进一个【集装箱】(如 MPEG-TS),方便接收方按帧拆包
- 传输:集装箱从网络发出去——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
逐段拆读:
-t 0:不限时长,一直发-n:无预览窗口(无头 SSH 主场,10-3 的规矩)--codec libav --libav-format mpegts:用 libav 压码并包成 MPEG-TS(VLC 友好的集装箱)-o tcp://0.0.0.0:8080?listen=1:监听本机 8080 端口,等客户端来连(listen 参数漏了就成了【主动往外推】,方向反了连不上)
电脑上(Windows 的 VLC):菜单【媒体 → 打开网络串流】,输入
tcp://树莓派的IP:8080
(IP 忘了?2-5 的老办法:路由器后台或 hostname -I。)画面即刻出现——这就是一个不要花一分钱的网络监控摄像头。
三、UDP 与 RTSP:各一句话认识
- UDP 版(延迟更低、允许丢帧,局域网内爽):树莓派
rpicam-vid -t 0 -n --codec libav --libav-format mpegts -o udp://电脑IP:5000,电脑用 VLC 打开udp://@:5000 - RTSP 版(监控 NVR、Home Assistant 这类设备认的标准协议):需要先架一个小型 RTSP 服务器(如 mediamtx),再把
rpicam-vid的输出管道给它;入门阶段知道有这条路即可
怎么选:自己看画面 → 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 里出现树莓派镜头前的实时画面,延迟约零点几到两秒;树莓派终端无报错持续输出。
读结果:
- 画面卡顿先降分辨率再怀疑网络:加
--width 1280 --height 720重试(逐项改,一次只改一个) - 端口被占用会报错:换 8081 或查
ss -tlnp | grep 8080 - Ctrl+C 停止树莓派端,VLC 随即断流——流的生死在发送端
七、30 秒实验:串流带宽的账
H.264 串流码率按 8 Mbps(兆比特每秒)算:
- 每秒传多少 MB?
- 连续串流 1 小时,过网多少数据?
- 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 实际有效带宽常打对折还要共享,多路串流优先走有线或降低码率。
八、常见误区
- 【照抄老教程 raspivid | cvlc 就能看】 —— 裸 H.264 已不被 VLC 支持,套 MPEG-TS 封装(
--codec libav --libav-format mpegts)。 - 【忘了 listen=1,客户端连不上】 ——
?listen=1是【服务器模式:等我】;漏了它会去【主动推】一个不存在的地址。 - 【卡顿一定是网速慢】 —— 先降分辨率/帧率再怀疑网络;一次只改一个变量。
- 【MJPEG 和 H.264 是一回事】 —— MJPEG 是【连续图片】(每帧独立压缩,带宽大);H.264 利用帧间相似性压缩(带宽小)。浏览器方案图省事、VLC 方案省带宽。
- 【端口随便换着用】 —— 树莓派端监听端口与 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【只传帧间变化】的红利;换来的是零门槛(浏览器直接看)。- ☐ 下一节(10-6 使用外接 USB 网络摄像头)
相关笔记
- 网络连接与蓝牙装置 —— 查 IP 与局域网基础
- 架设 Web 服务器 —— HTTP 服务思想:MJPEG 浏览器方案的亲戚
- 使用 Python 操作相机模块 —— picamera2:MJPEG 示例的地基
- 在终端机使用相机模块 —— rpicam-vid 参数(-t、-n、--codec)的出处
- 🍓 树莓派 · 索引 —— 全课路线图