文章目录
-
-
- ssh远程登陆
- 文件传输
- 家目录
- USB免驱摄像头
- 软件包安装
- [SSH 连接](#SSH 连接)
- 查看摄像头参数
- FFmpeg+MediaMTX
-
- 1,视频推流+本地查看
- [2. MJPEG 推流 + 手机 VLC 局域网 查看](#2. MJPEG 推流 + 手机 VLC 局域网 查看)
- [MJPEG / H.264](#MJPEG / H.264)
-
- [3. H.264 软编码](#3. H.264 软编码)
- [4. 1080P 不稳定 会重启](#4. 1080P 不稳定 会重启)
- [5. 720P 稳定](#5. 720P 稳定)
-
ssh远程登陆
Windows 主机使用 MobaXterm
SSH登录
https://rockchip.100ask.net/docs/DshanPi-R1/DshanOS/RemoteConfig
文件传输
- MobaXterm 在建立 SSH 连接的同时,会自动开启 SFTP 文件传输面板,非常便捷。
- FileZilla 是一款专业的 FTP/SFTP 客户端,适合大量文件的管理。
- https://rockchip.100ask.net/docs/DshanPi-R1/DshanOS/FileTransfer
家目录
- 超级管理员 root 的家目录在 /root。
而 root 的家目录直接放在根目录下, - 普通用户 baiwen 的家目录在 /home/baiwen,
普通用户的家目录在 /home/用户名/,
在工作中,大多数不会把 root 轻易给开发,大家都是用普通用户 + sudo 提权。
千万不要把乱七八糟的代码放在中文目录(桌面、文档、下载)下------因为嵌入式 Linux 终端对中文路径支持不好,编译时会报错。 - 普通用户家目录下,新建一个全英文的 projects 文件夹,在这里干活
- /home/baiwen/projects
USB免驱摄像头
- 把USB摄像头连接到开发板,在Linux下通常很直接,因为大部分免驱摄像头都遵循 UVC(USB Video Class) 标准,内核会自带驱动
- 检查USB设备:在终端输入以下命令,查看系统是否检测到新硬件
lsusb
如果输出中出现了你的摄像头品牌(如 Logitech, Microsoft)或芯片型号,说明硬件已连接 - 查找视频设备:摄像头会被系统识别为一个视频设备文件
ls /dev/video*
注意:在某些平台上(如RK3576),因为存在多个视频处理单元,/dev/video* 节点可能会非常多(70+个)。USB摄像头对应的通常是编号较大的那一个



- 为了更方便地测试和预览摄像头,推荐安装 v4l-utils 工具包,它包含了 v4l2-ctl 等强大的命令行工具
sudo apt update
sudo apt install v4l-utils fswebcam -y
v4l-utils:包含 v4l2-ctl 等调试工具。
fswebcam:一个轻量级的命令行拍照工具 - 使用 v4l2-ctl 命令来列出所有视频设备,并从中找到你的USB摄像头
v4l2-ctl --list-devices - 找到正确的设备节点(假设是 /dev/video0)后,用 fswebcam 拍一张照片来验证
fswebcam -d /dev/video0 test.jpg
如果命令成功执行,会在当前目录生成一张名为 test.jpg 的照片 - 查看这张照片正确,表面摄像头功能成功启动
软件包安装
- 软件源本质上就是存放软件包的网络服务器。这些服务器的地址被记录在系统的配置文件中。
配置文件位置:主要配置文件是 /etc/apt/sources.list。额外的源通常放在 /etc/apt/sources.list.d/ 目录下。
地址格式:文件里每行是一个软件源,格式类似 deb http://site.com/debian distribution main - 不同发行版(如Debian、Ubuntu)使用的软件源完全不同。因为每个发行版都是基于特定的代码库、版本和编译选项构建的,混用源(如在Debian上使用Ubuntu源)会导致严重的兼容性问题,甚至系统崩溃
SSH 连接
- 主力操作窗口。用来敲命令、编译(或者交叉编译后传文件)、调试应用程序
- 关键认知:串口是"硬件调试器",SSH 是"软件操作台"
- 一旦开发板的网络(有线或 WiFi)通了,99% 的操作都会切到 SSH
- 串口(底层救急,生命线)
串口不依赖网络,只要开发板通电、串口线接好,它就能工作。它的核心价值在于 "看门狗" 和 "救砖" - 看启动日志(Boot log):Linux 内核启动时,printk 打印的硬件初始化信息(内存检测、设备树加载、驱动挂载),只会输出到串口。SSH 要等系统完全启动、网络服务起来后才能连,但串口从按电源键的第一毫秒就能看日志。如果你的内核崩了(Kernel Panic),SSH 瞬间断连,你看不到死机前的"遗言",只有串口能抓到。
- 修改 Uboot 参数:启动时按住按键进入 Uboot 命令行(类似 BIOS),这里只能用串口操作。如果不小心把网卡驱动搞崩了,系统起不来,SSH 完全废了,只能靠串口进去改配置或重新烧录。
查看摄像头参数
- 查看摄像头设备节点
baiwen@dshanpi-r1:~$ ls /dev/video*
/dev/video0 /dev/video1 - 查看摄像头支持的所有格式、分辨率、帧率
c
baiwen@dshanpi-r1:~$ v4l2-ctl -d /dev/video0 --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x960
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 640x360
Interval: Discrete 0.033s (30.000 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 1280x960
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
Size: Discrete 640x360
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.040s (25.000 fps)
[2]: 'NV12' (Y/UV 4:2:0)
Size: Discrete 640x480
Interval: Discrete 0.033s (30.000 fps)
Size: Discrete 1920x1080
Interval: Discrete 0.200s (5.000 fps)
Size: Discrete 1280x960
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 1280x720
Interval: Discrete 0.067s (15.000 fps)
Size: Discrete 640x360
Interval: Discrete 0.033s (30.000 fps)
baiwen@dshanpi-r1:~$
v4l2-ctl Video4Linux2 的控制工具
-d /dev/video1 指定你要查询的设备
--list-formats-ext 列出所有支持的像素格式,以及每种格式下的分辨率和帧率组合
- 'MJPG'、'YUYV':像素格式的名字。
- MJPG 是硬件压缩的 JPEG 流(体积小,省带宽),
- YUYV 是原始未压缩数据(体积大,但兼容性好)。
- Size: Discrete 1280x720:该格式下支持的分辨率
- Interval: Discrete 0.033s (30.000 fps):该分辨率下支持的帧率,这里表示 30 帧/秒

在摄像头传感器(Sensor)内部,它永远在以固定的帧率(比如 30 帧/秒)连续不断地抓取光线信号,生成一串连续的数字图像流。
录像:系统启动流(Stream ON),把每一帧连续地保存下来(或编码成 MP4)。
拍照:系统启动流(Stream ON),只取其中的某一帧(比如第 1 帧),保存为 JPG/PNG,然后立刻停止流(Stream OFF)。
方案一:FFmpeg + MediaMTX (RTSP) ------ 功能最全面的"黄金搭档"
这是目前最主流、功能最强大的组合,被广泛应用于各种开发板项目。
核心组件:
MediaMTX:一个用Go语言编写的轻量级RTSP流媒体服务器。它就像一个视频流的"交换机",接收FFmpeg推送的视频,再转发给手机等客户端。
FFmpeg:负责从摄像头读取视频,进行编码,然后推送给MediaMTX。
为什么它是主流?:FFmpeg和MediaMTX都是非常成熟、维护活跃的开源项目,这意味着强大的功能和及时的错误修复。两者组合非常灵活,FFmpeg能处理几乎任何格式的视频源,MediaMTX作为服务器则能将RTSP流转发给多个客户端,并发能力很强。
优点:功能强大,延迟较低(通常在200ms左右),灵活性和扩展性强(例如,可轻松添加录像功能)。
缺点:涉及两个软件的配置,对新手来说稍显复杂。如果使用软件编码(libx264),CPU占用会比较高。
一句话总结:如果你对视频流的稳定性、可扩展性和低延迟有要求,且不介意花些时间配置,选这个方案就对了
FFmpeg+MediaMTX
1,视频推流+本地查看
- 安装 ffmpeg
- 下载并运行 MediaMTX
- 运行mediamtx
bash
运行效果
baiwen@dshanpi-r1:~/videottt$ ls
auto.crt auto.key LICENSE mediamtx mediamtx_v1.20.0_linux_arm64.tar.gz mediamtx.yml
baiwen@dshanpi-r1:~/videottt$ ./mediamtx
2026/08/27 22:47:56 INF MediaMTX v1.20.0, linux, arm64
2026/08/27 22:47:56 INF configuration loaded from /home/baiwen/videottt/mediamtx.yml
2026/08/27 22:47:56 INF [RTSP] started with listeners on :8554 (TCP/RTSP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
2026/08/27 22:47:56 INF [RTMP] started with listener on :1935 (TCP/RTMP)
2026/08/27 22:47:56 INF [HLS] started with listener on :8888 (TCP/HTTP)
2026/08/27 22:47:56 INF [WebRTC] started with listeners on :8889 (TCP/HTTP), :8189 (UDP/ICE)
2026/08/27 22:47:56 INF [SRT] started with listener on :8890 (UDP/SRT)
2026/08/27 22:47:56 INF [MoQ] started with listeners on :8892 (TCP/HTTP2), :8892 (UDP/HTTP3), :8893 (UDP/QUIC)
- 使用 FFmpeg 进行推流
bash
ffmpeg -re -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 -i /dev/video0 \
-c:v copy \
-f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/live
- 使用 ffplay(最低延迟):在开发板的桌面终端执行
ffplay -rtsp_transport tcp -fflags nobuffer -flags low_delay rtsp://127.0.0.1:8554/live
- 最终本地画面延时很小
运行输出解释
bash
/*
* ============================================================================
* MediaMTX 启动日志逐行翻译与讲解(C 语言注释风格)
* 日志来源:在目录 ~/videottt 下执行 ./mediamtx 命令的输出
* ============================================================================
*/
/* --------------------------------------------------------------------------
* 行 1:命令提示符和执行的命令
* 原文:baiwen@dshanpi-r1:~/videottt$ ./mediamtx
* 翻译:用户 baiwen 在主机 dshanpi-r1 的 ~/videottt 目录下,执行当前目录中的 mediamtx 程序。
* 讲解:mediamtx 是 MediaMTX 媒体服务器的可执行文件,此前已从压缩包解压得到。
* 执行该命令会启动一个支持多种流媒体协议的服务器进程。
*/
/* --------------------------------------------------------------------------
* 行 2:版本信息和运行环境
* 原文:2026/08/27 22:47:56 INF MediaMTX v1.20.0, linux, arm64
* 翻译:2026年8月27日 22:47:56 信息级别:MediaMTX 版本 1.20.0,运行于 Linux 操作系统,ARM 64位架构。
* 讲解:时间戳为启动时间,INF 表示信息级别日志。版本号 1.20.0 是当前使用的 MediaMTX 版本,
* 编译目标为 arm64 架构,与开发板硬件匹配。
*/
/* --------------------------------------------------------------------------
* 行 3:配置文件加载信息
* 原文:2026/08/27 22:47:56 INF configuration loaded from /home/baiwen/videottt/mediamtx.yml
* 翻译:2026年8月27日 22:47:56 信息级别:配置文件已加载,路径为 /home/baiwen/videottt/mediamtx.yml。
* 讲解:MediaMTX 启动时读取同目录下的 mediamtx.yml 配置文件,该文件包含
* 各类协议的端口、认证、路径映射等设置。如不存在则使用默认配置。
* 这里说明加载成功,所有后续监听端口均来自该配置(或默认值)。
*/
/* --------------------------------------------------------------------------
* 行 4:RTSP 协议监听端口
* 原文:2026/08/27 22:47:56 INF [RTSP] started with listeners on :8554 (TCP/RTSP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
* 翻译:2026年8月27日 22:47:56 信息级别:[RTSP] 已启动,监听以下地址:
* - :8554 (TCP/RTSP) -> RTSP 控制信令端口
* - :8000 (UDP/RTP) -> RTP 媒体传输端口(UDP)
* - :8001 (UDP/RTCP) -> RTCP 控制包端口(UDP)
* 讲解:RTSP 协议使用 TCP 端口 8554 传输控制信令(如 DESCRIBE、SETUP、PLAY)。
* 媒体数据(RTP 包)和 RTCP 控制包默认使用 UDP 传输,端口分别为 8000 和 8001。
* 因监听地址未指定 IP(以 : 开头),表示监听所有网络接口(0.0.0.0)。
* 后续客户端拉流时需通过 rtsp://开发板IP:8554/路径 访问。
*/
/* --------------------------------------------------------------------------
* 行 5:RTMP 协议监听端口
* 原文:2026/08/27 22:47:56 INF [RTMP] started with listener on :1935 (TCP/RTMP)
* 翻译:2026年8月27日 22:47:56 信息级别:[RTMP] 已启动,监听 TCP 端口 1935(RTMP 标准端口)。
* 讲解:RTMP 是 Adobe 的流媒体协议,常用于推流到直播平台或通过 Flash 播放器播放。
* MediaMTX 支持接收 RTMP 推流或提供 RTMP 拉流,端口 1935 是 RTMP 默认端口。
*/
/* --------------------------------------------------------------------------
* 行 6:HLS 协议监听端口
* 原文:2026/08/27 22:47:56 INF [HLS] started with listener on :8888 (TCP/HTTP)
* 翻译:2026年8月27日 22:47:56 信息级别:[HLS] 已启动,监听 TCP 端口 8888(HTTP 协议)。
* 讲解:HLS(HTTP Live Streaming)是苹果公司的流媒体协议,通过 HTTP 传输 m3u8 播放列表和 TS 切片。
* 客户端(如 Safari、VLC)可通过 http://开发板IP:8888/路径/playlist.m3u8 访问。
* 端口 8888 是自定义端口,可在配置文件中修改。
*/
/* --------------------------------------------------------------------------
* 行 7:WebRTC 协议监听端口
* 原文:2026/08/27 22:47:56 INF [WebRTC] started with listeners on :8889 (TCP/HTTP), :8189 (UDP/ICE)
* 翻译:2026年8月27日 22:47:56 信息级别:[WebRTC] 已启动,监听以下地址:
* - :8889 (TCP/HTTP) -> 信令和 HTTP 服务端口(用于 SDP 交换和 HTTP 访问)
* - :8189 (UDP/ICE) -> ICE 候选者(用于 UDP 传输媒体数据)
* 讲解:WebRTC 是一种浏览器实时音视频通信协议。MediaMTX 提供 WebRTC 网关,
* 允许浏览器通过 JavaScript 直接拉取流。TCP 8889 用于 HTTP 信令和 Web 界面,
* UDP 8189 用于 ICE 建立 P2P 连接传输媒体(SRTP)。
*/
/* --------------------------------------------------------------------------
* 行 8:SRT 协议监听端口
* 原文:2026/08/27 22:47:56 INF [SRT] started with listener on :8890 (UDP/SRT)
* 翻译:2026年8月27日 22:47:56 信息级别:[SRT] 已启动,监听 UDP 端口 8890(SRT 协议)。
* 讲解:SRT(Secure Reliable Transport)是开源的视频传输协议,支持丢包重传和加密,
* 适合在不可靠网络(如公网)上传输高质量视频。端口 8890 为 SRT 默认端口(可配置)。
*/
/* --------------------------------------------------------------------------
* 行 9:MoQ 协议监听端口
* 原文:2026/08/27 22:47:56 INF [MoQ] started with listeners on :8892 (TCP/HTTP2), :8892 (UDP/HTTP3), :8893 (UDP/QUIC)
* 翻译:2026年8月27日 22:47:56 信息级别:[MoQ] 已启动,监听以下地址:
* - :8892 (TCP/HTTP2) -> 基于 HTTP/2 的 MoQ 传输(TCP)
* - :8892 (UDP/HTTP3) -> 基于 HTTP/3 的 MoQ 传输(UDP)
* - :8893 (UDP/QUIC) -> 基于 QUIC 的 MoQ 传输(UDP)
* 讲解:MoQ(Media over QUIC)是新兴的基于 QUIC 协议的低延迟媒体传输标准。
* MediaMTX 支持多种 MoQ 传输方式,端口 8892 同时用于 TCP/HTTP2 和 UDP/HTTP3,
* 端口 8893 用于原生 QUIC。该协议目前尚处于发展初期,但在低延迟场景有潜力。
*/
/* ==========================================================================
* 总结:
* MediaMTX 成功启动,加载了配置文件,并同时开启了 7 种主流流媒体协议(RTSP、RTMP、HLS、
* WebRTC、SRT、MoQ,其中 RTSP 包含 RTP/RTCP 子端口)。所有监听端口均已绑定,
* 等待客户端连接或推流。用户此前用 ffmpeg 向 rtsp://127.0.0.1:8554/live 推流,
* 现在 MediaMTX 已就绪,该流可通过上述任意协议(视客户端支持情况)被拉取观看。
* 例如,可通过 VLC 拉取 RTSP,或通过浏览器访问 HLS/WebRTC 链接。
* ========================================================================== */
运行输出讲解

讲解
- 输入部分:精准捕获摄像头硬件数据
-re -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 -i /dev/video0
-re(灵魂参数):代表"Read at native frame rate"。没有它,FFmpeg会像脱缰的野马,以硬盘读取般的极限速度把摄像头数据瞬间塞爆内存缓冲区。加上它,FFmpeg会严格按 30 fps 的时钟节拍(每秒30次)去读取数据,保证推流是匀速的"实时流",这是消除延迟堆积的关键。
-f v4l2:指定使用Linux的V4L2框架驱动来采集。
-input_format mjpeg:这是最高效的一步。它强制V4L2驱动直接输出摄像头硬件编码好的MJPEG原始码流,而不是转换成未压缩的YUV/RGB(裸数据量是MJPEG的10倍以上)。
-video_size & -framerate:匹配你之前查到的摄像头支持参数(640x480@30fps)。注意,在 copy 模式下,这个 -framerate 只是告诉FFmpeg"时间戳按这个速度打",如果摄像头实际输出变慢了,它会等待;如果变快了,-re 会把它压回30fps。
- 核心处理层:Video拷贝(零CPU消耗)
-c:v copy
-c:v 指 Video Codec(视频编解码器)。
copy 指的是 Stream Copy(流复制),也叫比特流拷贝。
原理:FFmpeg在此处完全绕过了编解码器。它不进行任何解码(MJPEG -> YUV)或重新编码(YUV -> H.264),而是直接读取MJPEG数据包,打上时间戳(PTS/DTS)后,原封不动地塞给输出层。
效果:CPU占用率几乎为 0%(仅消耗一点内存拷贝和I/O中断开销)。这恰恰是你选择MJPEG摄像头最大的红利。
- 输出层:RTSP封装与TCP抗丢包
-f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/live
-f rtsp:强制输出格式为RTSP协议。
-rtsp_transport tcp:强制使用TCP传输(而非默认的UDP)。
为什么要加? UDP在Wi-Fi或内网波动时丢包严重,会导致VLC画面出现马赛克或绿屏。TCP有重传机制,虽然会引入微秒级延迟,但在无线开发板环境下,稳定性远优于UDP。
rtsp://127.0.0.1:8554/live:推流目标地址。
127.0.0.1 代表推给本机的MediaMTX服务器(端口8554)。
/live 是挂载点(Mount Point),客户端(如VLC)访问时需用 rtsp://开发板IP:8554/live。
- 关于 640x480 和 30fps 的带宽估算
既然用了 copy,网络传输的就是原始的MJPEG流。640x480的MJPEG单帧大小通常在 20KB ~ 50KB 之间(取决于画面复杂度)。
按30fps计算,瞬时带宽需求在 5MB/s ~ 15MB/s(约 40~120 Mbps)。
如果你的开发板用的是 Wi-Fi,这个码率可能会让无线网络丢包严重,导致画面花屏或断流
bash
/*
* ============================================================================
* FFmpeg 推流日志逐行翻译与讲解(C 语言注释风格)
* 日志来源:开发板 dshanpi-r1 上执行 ffmpeg 推流命令的输出
* 命令:ffmpeg -re -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 -i /dev/video0 -c:v copy -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/live
* ============================================================================
*/
/* --------------------------------------------------------------------------
* 第 1 行:用户执行命令的提示符和命令本身
* 原文:baiwen@dshanpi-r1:~$ ffmpeg -re -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 -i /dev/video0 \
* 翻译:用户 baiwen 在主机名为 dshanpi-r1 的终端中,执行 ffmpeg 命令,反斜杠表示续行。
* 讲解:这是 Bash 提示符,表示命令开始。ffmpeg 是程序名,后续是参数。
* -re : 以原始帧率读取(实时模式,防止数据爆发)
* -f v4l2 : 指定输入格式为 Video4Linux2(Linux 视频设备驱动框架)
* -input_format mjpeg : 强制使用 MJPEG 格式(摄像头硬件直接输出压缩流)
* -video_size 640x480 : 设置采集分辨率
* -framerate 30 : 设定帧率为 30 fps
* -i /dev/video0: 指定输入设备节点
* -c:v copy : 视频流复制(不编解码,直接拷贝)
* -f rtsp : 输出格式为 RTSP 协议
* -rtsp_transport tcp : 使用 TCP 传输(抗丢包)
* rtsp://127.0.0.1:8554/live : 推流目标地址(本机 MediaMTX 服务)
*/
/* --------------------------------------------------------------------------
* 第 2 行:FFmpeg 版本信息
* 原文:ffmpeg version 7.1.5-0+deb13u1 Copyright (c) 2000-2026 the FFmpeg developers
* 翻译:FFmpeg 版本 7.1.5-0+deb13u1,版权归 FFmpeg 开发者所有(2000-2026)
* 讲解:版本号中的 deb13u1 表示这是 Debian 系统的打包版本,基于 FFmpeg 7.1.5。
* 该版本较新,支持众多编解码器和滤镜。
*/
/* --------------------------------------------------------------------------
* 第 3 行:编译使用的 GCC 版本
* 原文: built with gcc 14 (Debian 14.2.0-19)
* 翻译:使用 GCC 14 (Debian 14.2.0-19) 编译
* 讲解:编译器版本,说明系统环境为 Debian 13(或更高),GCC 14 是比较新的版本。
*/
/* --------------------------------------------------------------------------
* 第 4 行及后续多行:FFmpeg 编译配置(configuration)
* 原文: configuration: --prefix=/usr --extra-version=0+deb13u1 --toolchain=hardened --libdir=/usr/lib/aarch64-linux-gnu --incdir=/usr/include/aarch64-linux-gnu --arch=arm64 --enable-gpl --disable-stripping --disable-libmfx --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --disable-libvpl --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libcaca --enable-libdvdnav --enable-libdvdread --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared
* 翻译:编译配置参数(此处列出所有启用的库和选项)
* 讲解:重点参数:
* --arch=arm64 : 目标架构为 64 位 ARM(说明开发板是 ARM 架构)
* --enable-gpl : 启用 GPL 许可的组件
* --enable-libx264 : 支持 H.264 软件编码(libx264)
* --enable-libvpx : 支持 VP8/VP9 编码
* --enable-libaom : 支持 AV1 编码
* --enable-libopus : 支持 Opus 音频编码
* --enable-libmp3lame : 支持 MP3 编码
* 以及其他很多库,说明该 FFmpeg 功能非常全面,可满足多种音视频处理需求。
* 其中 --enable-shared 表示动态库编译。
*/
/* --------------------------------------------------------------------------
* 接下来几行:库版本信息
* 原文:
* libavutil 59. 39.100 / 59. 39.100
* libavcodec 61. 19.101 / 61. 19.101
* libavformat 61. 7.103 / 61. 7.103
* libavdevice 61. 3.100 / 61. 3.100
* libavfilter 10. 5.100 / 10. 5.100
* libswscale 8. 3.100 / 8. 3.100
* libswresample 5. 3.100 / 5. 3.100
* libpostproc 58. 3.100 / 58. 3.100
* 翻译:各个 FFmpeg 子库的版本号(编译时版本 / 运行时版本,此处相同)
* 讲解:这些库分别负责工具函数(avutil)、编解码(avcodec)、封装格式(avformat)、
* 设备输入输出(avdevice)、滤镜(avfilter)、图像缩放(swscale)、
* 音频重采样(swresample)、后处理(postproc)。版本号一致,表示运行环境匹配。
*/
/* --------------------------------------------------------------------------
* 输入文件信息
* 原文:Input #0, video4linux2,v4l2, from '/dev/video0':
* 翻译:输入流 #0,格式为 video4linux2(V4L2),来源是 /dev/video0
* 讲解:FFmpeg 成功打开了摄像头设备,识别为 V4L2 设备。
*/
/* --------------------------------------------------------------------------
* 输入时长和起始时间
* 原文: Duration: N/A, start: 1065.222438, bitrate: N/A
* 翻译:时长:不可用,起始时间戳:1065.222438 秒,码率:不可用
* 讲解:对于实时流设备,时长没有意义,起始时间戳是系统启动后的相对时间(单位秒),
* 码率因是实时流,无法提前得知。
*/
/* --------------------------------------------------------------------------
* 输入流详细信息
* 原文: Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 640x480 [SAR 1:1 DAR 4:3], 30 fps, 30 tbr, 1000k tbn
* 翻译:输入流 #0:0,视频格式:MJPEG(基线),像素格式:yuvj420p(PC 级别,全范围亮度),
* 色彩空间为 bt470bg/unknown/unknown,分辨率 640x480,像素宽高比 1:1,显示宽高比 4:3,
* 帧率 30 fps,时间基准 30 tbr,时间戳精度 1000k tbn(即 1/1000000 秒)。
* 讲解:摄像头输出 MJPEG 压缩流,但 FFmpeg 内部将其描述为 yuvj420p(用于后续处理)。
* "pc" 表示亮度范围是 0-255(全范围),而非 TV 级别的 16-235。
* SAR 1:1 表示方形像素,DAR 4:3 是显示比例(640/480=4/3)。
* 30 tbr 是帧率基准,tbn=1000k 表示时间戳单位是微秒(1/1000000 秒)。
*/
/* --------------------------------------------------------------------------
* 流映射信息
* 原文:Stream mapping:
* 原文: Stream #0:0 -> #0:0 (copy)
* 翻译:流映射:输入流 #0:0 映射到输出流 #0:0,使用拷贝模式(copy)。
* 讲解:这是关键信息,表明 FFmpeg 不进行解码和重新编码,而是直接将 MJPEG 数据包
* 从输入搬运到输出,CPU 负载极低。
*/
/* --------------------------------------------------------------------------
* 输出文件信息
* 原文:Output #0, rtsp, to 'rtsp://127.0.0.1:8554/live':
* 翻译:输出流 #0,格式为 RTSP,目标地址为 rtsp://127.0.0.1:8554/live
* 讲解:输出封装为 RTSP 协议,推送到本机 MediaMTX 服务器的 /live 挂载点。
*/
/* --------------------------------------------------------------------------
* 输出元数据
* 原文: Metadata:
* 原文: encoder : Lavf61.7.103
* 翻译:元数据:编码器(这里指封装器)为 Lavf61.7.103(即 libavformat 版本)
* 讲解:Lavf 表示 FFmpeg 的封装库,版本号与前面一致。
*/
/* --------------------------------------------------------------------------
* 输出流详细信息
* 原文: Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 640x480 [SAR 1:1 DAR 4:3], q=2-31, 30 fps, 30 tbr, 90k tbn
* 翻译:输出流 #0:0,视频格式 MJPEG(基线),像素格式 yuvj420p(PC 级别),
* 分辨率 640x480,SAR 1:1,DAR 4:3,量化质量范围 q=2-31(但拷贝模式忽略),
* 帧率 30 fps,时间基准 30 tbr,时间戳精度 90k tbn(RTSP 常用 90kHz 时钟)。
* 讲解:输出流基本与输入一致,但 tbn 变为 90k(90kHz),这是 RTP 时间戳的标准时钟。
* 由于是 copy 模式,实际数据不变,只是封装时重新打时间戳。
*/
/* --------------------------------------------------------------------------
* 提示信息
* 原文:Press [q] to stop, [?] for help
* 翻译:按 q 键停止,按 ? 键查看帮助
* 讲解:FFmpeg 运行时交互提示,用户可按 q 正常退出。
*/
/* --------------------------------------------------------------------------
* 运行过程中的输出(此处只显示了最终统计,运行中每帧不显示)
* 原文:[out#0/rtsp @ 0xaaaafead93f0] video:896956KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
* 翻译:输出 #0 (RTSP) 统计:视频数据 896956 KiB,音频 0 KiB,字幕 0,其他流 0,全局头部 0,复用开销:未知。
* 讲解:这是用户按 Ctrl+C 后 FFmpeg 打印的最终统计。视频数据量约 876 MiB。
* 由于 RTSP 是流式协议,没有固定文件头尾,因此复用开销无法计算,显示 unknown 是正常的。
*/
/* --------------------------------------------------------------------------
* 最终帧统计和运行状态
* 原文:frame=34939 fps= 30 q=-1.0 Lsize=N/A time=00:19:28.80 bitrate=N/A speed= 1x
* 翻译:总帧数 34939,帧率 30 fps,质量因子 -1.0(表示拷贝模式无质量损失),
* 文件大小 N/A(流式输出无文件大小),运行时间 00:19:28.80,码率 N/A,速度 1x(实时)。
* 讲解:
* - frame=34939 : 共处理 34939 帧。
* - fps=30 : 实际帧率稳定在 30 fps,与设定一致。
* - q=-1.0 : 拷贝模式下质量参数无意义,固定为 -1.0。
* - Lsize=N/A : 因为输出是 RTSP 流,不是文件,所以没有最终大小。
* - time=00:19:28.80 : 总运行时间 19 分 28.8 秒。
* - bitrate=N/A : 实时流码率无法在结束时统计(动态变化)。
* - speed=1x : 速度因子为 1,表示以实时速度运行,没有过快或过慢,这是低延迟直播的理想状态。
*/
/* --------------------------------------------------------------------------
* 退出信息
* 原文:Exiting normally, received signal 2.
* 翻译:正常退出,收到信号 2(SIGINT,即用户按 Ctrl+C)
* 讲解:进程正常终止,非崩溃或错误退出。
*/
/* --------------------------------------------------------------------------
* 最后一行是命令提示符,表示命令执行完毕
* 原文:baiwen@dshanpi-r1:~$
* 翻译:终端提示符,等待用户输入下一条命令。
*/
/* ==========================================================================
* 总结:
* 该日志记录了一次完整的 RTSP 推流任务,从开始到用户主动停止,历时约 19.5 分钟。
* 整个过程无任何错误或警告,帧率稳定,速度实时,数据量合理(约 6 Mbps)。
* 说明开发板的 V4L2 驱动、FFmpeg 配置、MediaMTX 服务器配合良好。
* 后续可在此基础上升级分辨率或尝试硬件编码。
* ========================================================================== */
2. MJPEG 推流 + 手机 VLC 局域网 查看
- 获取开发板的局域网 IP
inet 192.168.31.113/24 brd 192.168.31.255 scope global dynamic noprefixroute wlx00367610adad - 启动 MediaMTX
./mediamtx - 新开一个终端,执行推流命令
c
ffmpeg -re -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 -i /dev/video0 \
-c:v copy \
-f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/live
- 手机 VLC 拉流查看
手机和开发板必须在同一个局域网
rtsp://192.168.31.113:8554/live
- 有两秒左右延时,但是画面流畅

MJPEG / H.264
MJPEG:简单粗暴,每帧都是完整图片,延迟低但体积大
H.264:聪明高效,只记录前后帧变化的部分,体积小但计算量大



3. H.264 软编码
- 运行 RTSP服务器
- 软编码推流
c
ffmpeg -f v4l2 -input_format mjpeg -video_size 640x480 -framerate 30 \
-i /dev/video0 \
-c:v libx264 -preset ultrafast -tune zerolatency \
-b:v 1M \
-g 30 \
-f rtsp -rtsp_transport tcp \
rtsp://127.0.0.1:8554/live
- 手机局域网 VLC查看
rtsp://192.168.x.x:8554/live
效果观看动态画面 流畅多了
4. 1080P 不稳定 会重启
5. 720P 稳定
720p@30fps 软编码命令
c
ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x720 -framerate 30 \
-i /dev/video0 \
-c:v libx264 \
-preset ultrafast \
-tune zerolatency \
-b:v 4M \
-maxrate 5M \
-bufsize 8M \
-profile:v high \
-g 30 \
-f rtsp -rtsp_transport tcp \
rtsp://127.0.0.1:8554/live
FFmpeg 720p@30fps 软编码推流命令 · 逐行详解
ffmpeg
-f v4l2
-input_format mjpeg
-video_size 1280x720
-framerate 30
-i /dev/video0
-c:v libx264
-preset ultrafast
-tune zerolatency
-b:v 4M
-maxrate 5M
-bufsize 8M
-profile:v high
-g 30
-f rtsp
-rtsp_transport tcp
rtsp://127.0.0.1:8554/live
-
ffmpeg
────────────────────────────────────────────────────────
调用 FFmpeg 多媒体处理工具。
FFmpeg 是业界最流行的开源音视频处理框架,支持采集、编码、
转码、推流、录制等几乎所有音视频操作。
-
-f v4l2
────────────────────────────────────────────────────────
指定输入格式(Input Format)为 Video4Linux2。
V4L2 是 Linux 内核中视频设备的统一驱动接口标准。
所有 USB 摄像头、CSI 摄像头在 Linux 下都通过 V4L2 驱动。
这里告诉 ffmpeg:"输入设备走 V4L2 驱动层读取数据"。
-
-input_format mjpeg
────────────────────────────────────────────────────────
让摄像头以 MJPEG 格式输出视频流。
MJPEG = Motion JPEG,即每一帧都是一张独立的 JPEG 图片。
摄像头内部硬件已经完成了 JPEG 压缩,所以:
✅ 数据量小(比原始 YUV 格式小 10 倍以上)
✅ USB 带宽占用低(USB 2.0 也能跑 1080p)
✅ CPU 只需解码 JPEG,不用编码原始数据
如果不用 mjpeg,摄像头输出的是原始 YUV 数据:
❌ 720p 单帧 ≈ 1.5MB,30fps ≈ 45MB/s → USB 2.0 带宽不够
-
-video_size 1280x720
────────────────────────────────────────────────────────
设置采集分辨率为 1280×720,即 720p。
720p 的像素数 = 92 万,仅为 1080p(207 万)的 44%。
在 RK3565 上,720p 软编码的 CPU 负载约 50~70%,
能稳定运行不重启,是当前性能和画质的最佳平衡点。
-
-framerate 30
────────────────────────────────────────────────────────
设置采集帧率为 30fps(每秒 30 帧)。
30fps 是视频流畅度的"黄金标准":
- 电影:24fps
- 普通视频/直播:30fps
- 游戏/体育直播:60fps
30fps 人眼感觉流畅自然,不会觉得卡顿。
-
-i /dev/video0
────────────────────────────────────────────────────────
指定输入设备路径为 /dev/video0。
在 Linux 系统中,摄像头被映射为 /dev/videoN 设备文件。
video0 通常是第一个 USB 摄像头。
可以通过 v4l2-ctl --list-devices 查看所有摄像头设备。
-
-c:v libx264
────────────────────────────────────────────────────────
指定视频编码器为 libx264(软件 H.264 编码器)。
-c:v = codec:video = 视频编码器
libx264 是目前最成熟、兼容性最好的 H.264 软件编码器。
所有设备(手机、电脑、电视)都支持 H.264 解码。
注意:这里使用的是软件编码,不是硬件编码。
你的 RK3565 有硬件编码器(MPP/VAAPI),但这里没有调用,
后面我们可以优化为硬件编码来大幅降低 CPU 负载。
-
-preset ultrafast
────────────────────────────────────────────────────────
设置编码速度为"极速"模式。
libx264 有多个预设(preset),从慢到快:
placebo → veryslow → slower → slow → medium → fast → faster → veryfast → faster → ultrafast
ultrafast 是"牺牲压缩率换取速度"的极端模式:
✅ 编码速度最快,CPU 占用最低
❌ 同样码率下画质最差(压缩率低)
因为 RK3565 CPU 算力有限,必须用 ultrafast 才能跑满 30fps。
-
-tune zerolatency
────────────────────────────────────────────────────────
优化编码器为"零延迟"模式。
直播场景要求"低延迟",编码器默认会为了画质而缓存多帧再编码,
这会引入几百毫秒到几秒的延迟。
zerolatency 告诉编码器:不要缓存,来了就编,编了就发。
适合直播、视频通话等实时场景。
-
-b:v 4M
────────────────────────────────────────────────────────
设置目标视频码率为 4Mbps(4兆比特每秒)。
-b:v = bitrate:video = 视频码率
码率决定了视频的清晰度和文件大小:
720p 的码率参考:
1Mbps → 模糊(有马赛克)
2Mbps → 可接受
4Mbps → 清晰(当前设置)
6Mbps → 非常清晰
8Mbps+ → 接近无损
4Mbps 是 720p 直播的"超清"标准,画质好且码率适中。
-
-maxrate 5M
────────────────────────────────────────────────────────
设置最大码率为 5Mbps。
当画面复杂(快速移动、大量细节)时,
固定码率会导致画面瞬间模糊。
maxrate 允许编码器临时突破目标码率(4M),
最高飙到 5M 来保住复杂画面的清晰度。
-
-bufsize 8M
────────────────────────────────────────────────────────
设置码率控制缓冲池大小为 8Mbps。
配合 maxrate 使用,告诉编码器:
"给你 8M 的缓冲空间,去平滑码率波动"。
编码器会在 8M 的范围内,让码率平滑变化,
避免瞬间码率暴增导致网络卡顿。
-
-profile:v high
────────────────────────────────────────────────────────
设置 H.264 编码档次为 High Profile。
H.264 有 3 个主要档次:
Baseline → 最基础,兼容性最好,压缩率最低
Main → 中间档
High → 压缩率最高,同样码率画质最好
几乎所有现代设备都支持 High Profile 解码,
所以用 High 可以在同样 4M 码率下获得更好画质。
-
-g 30
────────────────────────────────────────────────────────
设置 GOP(关键帧间隔)为 30 帧。
-g = GOP size = 两个关键帧(I帧)之间的帧数。
每 30 帧插入一个 I 帧,因为帧率是 30fps,
所以相当于每 1 秒一个关键帧。
I 帧的作用:
✅ 手机播放器拖动进度条时,能快速定位到画面
✅ 网络丢包时,下一个 I 帧能恢复画面
❌ I 帧数据量大(是普通帧的 5~10 倍)
-
-f rtsp
────────────────────────────────────────────────────────
指定输出格式为 RTSP 流。
-f = format = 输出容器格式
RTSP(Real Time Streaming Protocol)是实时流媒体传输协议,
广泛用于视频监控、直播推流。
手机 VLC 等播放器可以直接播放 RTSP 流。
-
-rtsp_transport tcp
────────────────────────────────────────────────────────
指定 RTSP 使用 TCP 传输(而非 UDP)。
TCP 传输的优点:
✅ 数据包完整到达,不会花屏、撕裂
✅ 适合局域网,延迟低
❌ 比 UDP 占用稍多带宽
UDP 传输的缺点:
❌ 丢包会导致画面花屏、马赛克
✅ 延迟更低
内网直播推荐 TCP,稳定可靠。
-
rtsp://127.0.0.1:8554/live
────────────────────────────────────────────────────────
推流的目标地址。
rtsp:// → 使用 RTSP 协议
127.0.0.1 → 本机(localhost)
:8554 → 端口号 8554(mediamtx 默认端口)
/live → 流的路径名
手机 VLC 播放时输入:rtsp://你的IP:8554/live 即可观看
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
数据流全景图
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌───────────────┐
│ USB 摄像头 │
│ 硬件压缩 MJPEG │
└───────┬───────┘
│
USB 2.0 传输 MJPEG 数据流
│
▼
┌───────────────┐
│ /dev/video0 │
│ V4L2 驱动层 │
└───────┬───────┘
│
▼
┌───────────────┐
│ FFmpeg 输入 │
│ -f v4l2 │
│ mjpeg 格式 │
└───────┬───────┘
│
▼
┌─────────────────────────────────────────────────┐
│ FFmpeg 处理流水线 │
│ │
│ ① MJPEG 解码 → 原始 YUV 帧 │
│ (CPU 解码 JPEG,占 1 个核) │
│ │
│ ② libx264 软件编码 → H.264 流 │
│ -preset ultrafast(最快编码) │
│ -b:v 4M(码率控制) │
│ -profile:v high(高压缩率) │
│ (CPU 编码,占 2~3 个核) │
│ │
│ ③ RTSP 封包输出 │
│ -f rtsp -rtsp_transport tcp │
└───────────────────────┬───────────────────────────┘
│
▼
┌───────────────┐
│ mediamtx │
│ RTSP 服务器 │
│ 127.0.0.1:8554 │
└───────┬───────┘
│
局域网 WiFi
│
▼
┌───────────────┐
│ 📱 手机 VLC │
│ 播放 RTSP 流 │
│ 720p@30fps │
└───────────────┘
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
RK3565 软编码 720p@30fps 资源占用预估
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CPU 占用 : 50~70%(4 核 A55 中 2~3 个核满载)
CPU 温度 : 60~70°C(有风扇散热下)
内存占用 : 150200MB
USB 带宽 : 1525Mbps(USB 2.0 极限 280Mbps,绰绰有余)
推流延迟 : 200500ms(局域网 TCP 传输)
画质 : 720p 清晰,手机上看和 1080p 几乎无区别
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
当前状态总结
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ 720p@30fps 软编码已稳定运行
✅ 画面清晰流畅,手机连接正常
✅ 不再重启,散热风扇工作正常
✅ 4Mbps 码率,画质/带宽/CPU 三者平衡
下一步优化方向:
① 尝试上 60fps 提升流畅度
② 调用硬件编码(RK3565 MPP)降低 CPU 负载
③ 尝试 1080p 低帧率软编码
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━