返回文章
FFmpeg音视频RTSP嵌入式故障排查

FFmpeg 原始视频、RTSP、转码与服务集成

FFmpeg 实战使用:原始视频、RTSP、转码与服务集成 本文按 FFmpeg 整理(原请求中的 “Ffmppe” 按常见拼写误差处理)。重点记录在摄像头、嵌入式设备和 BinBot 服务中的可复用做法。 1. 工具分工 ffmpeg :读取输入、解码、滤镜处理、编码并输出文件或流。 ffprobe :只读探测媒体元

2026年9月30日阅读约 8 分钟0 条评论

FFmpeg 实战使用:原始视频、RTSP、转码与服务集成

本文按 FFmpeg 整理(原请求中的 “Ffmppe” 按常见拼写误差处理)。重点记录在摄像头、嵌入式设备和 BinBot 服务中的可复用做法。

1. 工具分工

  • ffmpeg:读取输入、解码、滤镜处理、编码并输出文件或流。
  • ffprobe:只读探测媒体元数据,适合确认编码、分辨率、帧率、时长和流数量。
  • ffplay:快速预览,尤其适合排查原始视频的像素格式、分辨率和帧率是否匹配。

先确认安装和编解码器:

ffmpeg -version
ffprobe -version
ffmpeg -encoders | grep -E 'libx264|aac|libopus'

容器或服务进程中不要只依赖 PATH。配置文件中显式指定绝对路径,例如:

ffmpeg_path = "/usr/bin/ffmpeg"

2. 原始 YUV 视频预览

原始 .yuv 文件没有容器元数据,播放器不知道像素格式、尺寸和帧率,三个参数必须由采集端或驱动确认。

YUYV422

ffplay   -f rawvideo   -pixel_format yuyv422   -video_size 640x480   -framerate 30   -i video.yuv

NV16

ffplay   -f rawvideo   -pixel_format nv16   -video_size 640x480   -framerate 10   -i video.yuv   -vf format=yuv420p

-pixel_format 是 ffplay 的输入参数;用 ffmpeg 处理 rawvideo 时通常写成 -pix_fmt:

ffmpeg   -f rawvideo   -pix_fmt nv16   -video_size 640x480   -framerate 10   -i video.yuv   -c:v libx264   -preset ultrafast   -crf 23   -pix_fmt yuv420p   output.mp4

原始视频排错规律

  • 画面有明显色偏:优先检查 yuyv422、nv12、nv16 是否选错。
  • 画面倾斜、撕裂或滚动:检查宽高和每行 stride,确认文件是否包含 padding。
  • 播放速度不对:检查 -framerate;rawvideo 不携带时间戳。
  • 播放器提示输入不足:检查文件大小是否满足
    帧数 × 每帧字节数,并确认采集是否被截断。
  • 兼容性差:编码 H.264 后补 -pix_fmt yuv420p,多数浏览器和硬件播放器更容易解码。

可以用 ffprobe 带上同样的原始视频参数做基础检查:

ffprobe -v error   -f rawvideo   -pixel_format yuyv422   -video_size 640x480   -framerate 30   -show_entries frame=pkt_size   -of default=noprint_wrappers=1   video.yuv

3. RTSP 摄像头流

嵌入式摄像头链路中,优先使用 TCP 传输,避免无线或交换网络丢包造成花屏:

ffprobe -v error   -rtsp_transport tcp   -show_entries stream=codec_name,width,height,avg_frame_rate   <camera-rtsp-url>

抓取一帧作为设备或 UI 参考图:

ffmpeg -y   -rtsp_transport tcp   -i <camera-rtsp-url>   -frames:v 1   camera-reference.jpg

排查 RTSP 时按顺序确认:

  1. 设备端服务是否在运行。
  2. TCP 端口是否可达。
  3. ffprobe 是否能拿到 codec、宽高和帧率。
  4. 再用 ffmpeg 解码少量帧,避免把网络问题误判为编码问题。

4. HLS 或转发链路验证

链路验证不需要保存输出文件,直接解码到空输出即可:

ffmpeg -hide_banner -loglevel error   -i <hls-playlist-url>   -frames:v 30   -f null -

命令成功只能说明 FFmpeg 能拉取并解码这段媒体;浏览器仍可能受跨域、MIME 类型、HLS.js 支持或网络可达性影响,需要单独检查播放页面和 .m3u8 响应。

5. GIF 规范化的工程做法

上传 GIF、PNG、JPEG 或 WebP 后,如果下游 UI 只接受固定 GIF 规格,可以统一转成 216x216、12.5 FPS,并保留透明背景:

ffmpeg -hide_banner -loglevel error -y   -i input.gif   -filter_complex   "fps=12.5,scale=216:216:force_original_aspect_ratio=decrease:flags=lanczos,pad=216:216:(ow-iw)/2:(oh-ih)/2:color=black@0.0,split[s0][s1];[s0]palettegen=reserve_transparent=1[p];[s1][p]paletteuse=dither=sierra2_4a"   -f gif normalized.gif

服务端集成时要同时做好这些保护:

  • 先限制上传大小,再落盘。
  • 校验文件头,不要只相信扩展名。
  • 使用参数数组调用 subprocess,不要拼接 shell 字符串。
  • 设置超时,并检查返回码、目标文件存在性和最小文件大小。
  • 通过临时文件写入,成功后再 os.replace 为最终文件。
  • 无论成功或失败都清理输入和中间文件。
  • 对生成后的 GIF 再次检查大小,防止转码放大绕过限制。

6. RTSP 转 MJPEG 给浏览器

浏览器不能直接消费所有 RTSP 流时,可以由服务端启动受控的 FFmpeg 子进程:

ffmpeg -hide_banner -loglevel error   -rtsp_transport tcp   -i <camera-rtsp-url>   -an   -r 8   -q:v 5   -f mpjpeg   -boundary_tag binbotframe   pipe:1

HTTP 响应使用:

Content-Type: multipart/x-mixed-replace; boundary=binbotframe

服务端要在首个视频块到达前设置启动超时;客户端断开、取消请求或读取异常时终止子进程,否则会留下孤儿 FFmpeg 进程和持续占用的 RTSP 连接。

7. 常用参数速查

参数 作用 经验
-f rawvideo 声明输入是裸视频 必须配合像素格式、尺寸、帧率
-pix_fmt / -pixel_format 指定像素格式 ffmpeg 常用 -pix_fmt,ffplay 常用 -pixel_format
-video_size 640x480 / -s 640x480 指定尺寸 尽量使用采集端真实输出尺寸
-framerate 30 / -r 30 输入或输出帧率 输入 rawvideo 时要放在输入参数区域
-c:v libx264 H.264 编码 兼容性和体积通常较平衡
-preset ultrafast 编码速度档位 低延迟或嵌入式转码优先,文件会更大
-crf 23 恒定质量 数值越小质量越高、体积越大
-rtsp_transport tcp RTSP 使用 TCP 网络不稳定时优先尝试
-frames:v 1 只输出一帧 适合抓图和健康检查
-f null - 丢弃输出 适合验证能否持续解码

8. 最小排错清单

  1. 用 ffprobe 先确认输入流,不要直接猜参数。
  2. 原始视频先用 ffplay 预览,再开始编码。
  3. 把输入参数和输出参数分开看,特别是 -r、-pix_fmt 和 -f。
  4. 需要浏览器播放时,优先输出 H.264 + yuv420p,或由服务端转 MJPEG/HLS。
  5. 服务端记录 FFmpeg 的退出码和最后一段 stderr,但不要把完整输入 URL 中的敏感查询参数写入日志。
  6. 对每个长时间运行的 FFmpeg 进程设置超时、取消处理和资源回收。

Discussion

评论

0 条已通过审核

留下评论

友善交流,请勿发布广告或无关内容。