RTSP 拉流与录制:IPC 摄像头本地录像完整方案

RTSP 拉流与录制:IPC 摄像头本地录像完整方案

RTSP 拉流与录制:IPC 摄像头本地录像完整方案

做 IPC 摄像头、无人售货柜、安防监控,RTSP 拉流和录制是基本功。这篇讲清楚:怎么稳定拉流、怎么存成文件、怎么按时间分片、断线怎么自动重连、延迟怎么优化——全是实际项目里踩过的坑。

大家好,我是黒漂技术佬。

之前写 IPC 摄像头专栏的时候,很多人问 RTSP 拉流的问题:拉流花屏怎么办?怎么 24 小时录像?断网了怎么自动重连?录像文件太大怎么办?

这些问题 FFmpeg 都能解决,但参数没配对的话,不是不稳定就是延迟高。这篇把我做售货柜项目积累的 RTSP 拉流录制经验全部分享出来。


一、RTSP 基础

RTSP(Real Time Streaming Protocol)是网络摄像头最常用的流媒体协议。IPC 摄像头基本上都支持。

常见 RTSP 地址格式

不同品牌地址不一样,常见的:

# 海康威视rtsp://用户名:密码@IP:554/h264/ch1/main/av_stream# 大华rtsp://用户名:密码@IP:554/cam/realmonitor?channel=1&subtype=0# 华天龙(我项目里用的)rtsp://用户名:密码@IP:554/stream1# 通用格式rtsp://用户名:密码@IP:554/live

先测试流能不能打开

用 ffplay 先试一下,确认地址和账号密码对不对:

ffplay rtsp://admin:123456@192.168.1.100:554/stream1

能弹出画面就说明通了。


二、最简单的拉流录制

直接存成 MP4

ffmpeg-irtsp://地址-ccopy output.mp4

-c copy直接复制流,不重新编码,CPU 占用极低。

存成 MKV(推荐 24 小时录制)

ffmpeg-irtsp://地址-ccopy output.mkv

为什么推荐 MKV?MP4 的元数据在文件末尾,录制中断(断电、断网)文件会损坏。MKV 是流式封装,断了也能播放前面的内容。

💡 做无人值守的 24 小时录像,一律用 MKV 或 TS 格式,别用 MP4——哪天断电了,录了十几个小时的文件直接废了。


三、按时间分片录制

24 小时录像存成一个文件太大,不方便管理和检索,按时间分片:

每小时一个文件

ffmpeg-irtsp://地址-ccopy-fsegment-segment_time3600-strftime1"record/%Y%m%d_%H%M%S.mkv"
  • -f segment:分段输出
  • -segment_time 3600:每 3600 秒(1小时)切一个文件
  • -strftime 1:文件名用时间格式
  • %Y%m%d_%H%M%S:年月日_时分秒,比如20260702_143000.mkv

每天一个文件夹 + 每小时一个文件

ffmpeg-irtsp://地址-ccopy-fsegment-segment_time3600-strftime1"record/%Y%m%d/%H%M%S.mkv"

自动按日期建文件夹,里面是每小时的文件。

重置时间戳

分片的时候加上-reset_timestamps 1,每个分片的时间戳从 0 开始,播放器拖动进度条更准:

ffmpeg-irtsp://地址-ccopy-fsegment-segment_time3600-reset_timestamps1-strftime1"record/%Y%m%d_%H%M%S.mkv"

四、按大小分片

每 100MB 切一个文件

ffmpeg-irtsp://地址-ccopy-fsegment-segment_size100M-strftime1"record/%Y%m%d_%H%M%S.mkv"

-segment_size 100M每个文件最大 100MB。

实际项目里一般按时间分片为主,大小作为辅助限制。


五、只录视频 / 只录音频

# 只录视频(不要音频)ffmpeg-irtsp://地址-c:vcopy-anoutput.mkv# 只录音频(不要视频)ffmpeg-irtsp://地址-vn-c:acopy output.aac

-an去掉音频,-vn去掉视频。

有些摄像头音频有杂音或者不需要录音,加上-an省空间。


六、拉流参数优化:稳定、低延迟

默认参数拉流可能会卡、花屏、延迟高,调这几个参数。

1. 传输协议:TCP vs UDP

# TCP 传输(推荐)ffmpeg-rtsp_transporttcp-irtsp://地址...# UDP 传输(默认)ffmpeg-rtsp_transportudp-irtsp://地址...
  • UDP:速度快、延迟低,但丢包就花屏
  • TCP:可靠不丢包,但有延迟,网络差的时候会卡

实际项目建议用 TCP,稳定最重要。售货柜的摄像头我全部用 TCP,偶尔网络波动也不会花屏。

2. 超时设置

ffmpeg-rtsp_transporttcp-stimeout5000000-irtsp://地址...

-stimeout 5000000超时 5 秒(单位微秒),连不上就退出,不会一直卡着。

3. 缓冲区大小

ffmpeg-rtsp_transporttcp-buffer_size1024000-irtsp://地址...

网络抖动大的话,加大缓冲区,减少卡顿。

4. 降低延迟

做实时预览、远程开门这种需要低延迟的场景:

ffmpeg-rtsp_transporttcp-fflagsnobuffer-flagslow_delay-irtsp://地址...
  • -fflags nobuffer:不缓冲,收到就解码
  • -flags low_delay:低延迟模式

代价是抗抖动能力下降,网络不好容易卡。

5. 跳过损坏帧

流偶尔有坏数据,FFmpeg 可能直接报错退出。加上:

ffmpeg-err_detectignore_err-irtsp://地址...

遇到错误忽略,继续跑。


七、断线自动重连

FFmpeg 本身不会自动重连,断网了就退出。需要自己写脚本循环。

Windows PowerShell 脚本

while($true){ffmpeg-rtsp_transport tcp-stimeout 5000000 `-i"rtsp://admin:123456@192.168.1.100:554/stream1"`-ccopy-f segment-segment_time 3600-reset_timestamps 1 `-strftime 1"record/%Y%m%d_%H%M%S.mkv"Write-Host"断线了,3秒后重连..."Start-Sleep3}

Linux / macOS Shell 脚本

#!/bin/bashwhiletrue;doffmpeg-rtsp_transporttcp-stimeout5000000\-i"rtsp://admin:123456@192.168.1.100:554/stream1"\-ccopy-fsegment-segment_time3600-reset_timestamps1\-strftime1"record/%Y%m%d_%H%M%S.mkv"echo"断线了,3秒后重连..."sleep3done

重连的几个注意点

  1. 加延迟:别立刻重连,等个 3-5 秒,不然网络还没恢复又失败
  2. 加超时-stimeout必须加,不然卡着不动
  3. 日志记录:生产环境把输出写到日志文件,方便排查问题
  4. 分段文件名用时间戳:重连后不会覆盖之前的文件

八、边录边转码(降低存储占用)

直接-c copy存的是摄像头原始码流,可能码率很高、占空间大。如果存储空间紧张,可以边拉边转码压缩。

H.264 压缩录制

ffmpeg-irtsp://地址-vcodeclibx264-crf28-acodecaac-b:a64k-fsegment-segment_time3600"record/%Y%m%d_%H%M%S.mp4"

代价是 CPU 占用高,需要机器性能够。

硬件加速录制(RK3588 推荐)

售货柜用的 RK3588,硬编码几乎不占 CPU:

ffmpeg-irtsp://地址-vcodech264_rkmpp-b:v1M-acodeccopy-fsegment-segment_time3600"record/%Y%m%d_%H%M%S.mp4"

硬件加速后面专门一篇细讲。


九、拉流 + 实时抽帧(不存视频)

只需要定时抽帧做 AI 识别,不需要存录像:

ffmpeg-rtsp_transporttcp-irtsp://地址-vffps=1frames/%04d.jpg

售货柜项目里,待机状态就每秒抽一帧跑 YOLO 检测,有人拿东西的时候才触发完整识别流程。

抽帧 + 推流同时进行

一边存文件,一边抽帧做分析,用 tee 或者 filter_complex 分流。


十、多路摄像头同时录制

多个摄像头,写个脚本循环启动,或者一条命令多个输入:

ffmpeg\-irtsp://摄像头1地址\-irtsp://摄像头2地址\-map0-ccopy-fsegment-segment_time3600"cam1/%Y%m%d_%H%M%S.mkv"\-map1-ccopy-fsegment-segment_time3600"cam2/%Y%m%d_%H%M%S.mkv"

-map 0选第一个输入,-map 1选第二个,分别输出。

但更推荐每个摄像头单独起一个 FFmpeg 进程——一路挂了不影响其他路,也好管理。


十一、实际踩过的坑

坑 1:录制的 MP4 文件损坏打不开

原因:MP4 的 moov atom 在文件末尾,异常退出没写进去。
解决:用 MKV 或 TS 格式录制,或者录制完后用ffmpeg -i input.mp4 -c copy fixed.mp4修复。

坑 2:花屏、绿屏、马赛克

原因:UDP 丢包,或者关键帧间隔太大。
解决:

  • 改用 TCP 传输:-rtsp_transport tcp
  • 摄像头设置里把关键帧间隔改小(比如 1 秒一个 I 帧)

坑 3:延迟越来越大

原因:FFmpeg 默认有缓冲,累积延迟。
解决:加-fflags nobuffer -flags low_delay -framedrop,丢帧保延迟。

坑 4:音视频不同步

原因:摄像头的时间戳有问题,或者网络抖动。
解决:加-vsync cfr统一视频帧率,或者-async 1校正音频。

坑 5:FFmpeg 进程挂了没人知道

解决:

  • 写个守护脚本,进程没了自动拉起来
  • 定期检查录像文件有没有更新
  • 生产环境配合监控告警

十二、我项目里用的完整命令

售货柜 IPC 摄像头 24 小时录制的完整命令:

ffmpeg-rtsp_transporttcp\-stimeout10000000\-err_detectignore_err\-i"rtsp://admin:密码@192.168.1.200:554/stream1"\-ccopy\-fsegment\-segment_time1800\-segment_formatmatroska\-reset_timestamps1\-strftime1\"/data/record/cabinet01/%Y%m%d/%H%M%S.mkv"

参数说明:

  • TCP 传输,10 秒超时
  • 忽略错误继续运行
  • 每 30 分钟一个文件
  • MKV 格式,断电不损坏
  • 按日期建文件夹,文件名带时间戳

外面再套一层自动重连的脚本,稳定跑几个月没问题。


十三、本篇小结

  • 录制优先用 MKV 格式,异常退出不损坏
  • -c copy直接复制流,CPU 占用最低
  • -f segment按时间/大小分片,方便管理
  • -rtsp_transport tcp更稳定,UDP 延迟低但易花屏
  • 断线重连需要自己写脚本循环
  • 生产环境:超时 + 错误忽略 + 自动重连 + 日志监控

下一篇讲HLS/DASH 切片:直播和点播的切片生成,怎么把视频转成 m3u8 放到网页上播放。

我是黒漂技术佬。