You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于事件动态录制RTSP视频流的FFmpeg实现方案问询

解决方案

针对你需要录制RTSP流中事件PTS前后10秒视频的需求,FFmpeg有几种低成本的适配方案,无需全量帧缓冲:

方案1:固定时长片段切割+事后拼接

预启动FFmpeg持续拉流,将视频按短时长(比如2秒)切割成小片段,同时记录每个片段对应的全局PTS范围,收到事件后匹配并拼接目标片段:

  1. 启动缓存FFmpeg进程(后台持续运行):
ffmpeg -i rtsp://your_rtsp_url -c copy -f segment -segment_time 2 -reset_timestamps 1 -strftime 1 "stream_cache/%Y%m%d_%H%M%S.mp4"
  • -segment_time 2:每2秒生成一个片段
  • -reset_timestamps 1:每个片段内部时间戳从0开始,方便后续拼接
  • -strftime 1:用时间戳命名片段,便于对应全局PTS
  1. 事件触发时,计算需要的时间范围(事件PTS-10到PTS+10),找出对应的缓存片段,用FFmpeg拼接并裁剪到精确时间:
ffmpeg -f concat -safe 0 -i <(printf "file '%s'\n" ./stream_cache/匹配的片段文件列表) -ss [片段内起始偏移] -to [片段内结束偏移] -c copy output.mp4
  • 可通过脚本自动匹配片段:比如利用片段命名包含的时间戳对应全局PTS,筛选出覆盖目标时间范围的所有片段
  • 优势:磁盘缓存成本低,可自动清理过期片段(比如只保留最近30秒的片段),实现简单

方案2:循环覆盖式MPEG-TS缓存流

利用MPEG-TS格式支持随机读取的特性,预启动FFmpeg将流输出到循环覆盖的TS文件,事件触发时直接截取:

  1. 启动循环缓存进程:
ffmpeg -i rtsp://your_rtsp_url -c copy -f mpegts -segment_wrap 30 -segment_time 1 "stream_cache/current_stream_%03d.ts"
  • -segment_wrap 30:最多保留30个1秒的TS片段,新片段会覆盖最旧的,自动控制缓存大小(这里是30秒)
  1. 事件触发时,根据全局PTS计算出在缓存流中的相对时间偏移,直接截取:
ffmpeg -i "concat:stream_cache/current_stream_*.ts" -ss [相对缓存起始的偏移秒数] -t 20 -c copy output.mp4
  • 缓存30秒完全覆盖事件前后10秒的需求,无需担心视频流走
  • 优势:TS格式截取无需重新编码,速度极快,循环覆盖无需手动清理

方案3:轻量级内存缓冲(适合小内存服务器)

如果不想用磁盘缓存,可利用FFmpeg的buffer滤镜在内存中缓存最近30秒的帧,不过需要结合外部控制触发录制:
预启动FFmpeg时,将流导入内存缓冲区,同时监听事件,事件触发时从缓冲区提取对应时间范围的帧进行封装。这种方式需要编写简单的控制逻辑,比如通过管道向FFmpeg发送指令,或者使用FFmpeg的zmq滤镜实现远程控制,复杂度稍高,但内存占用可控(缓存30秒1080P视频约几十MB)。

针对你的模拟代码调整建议

不要在事件触发时才启动FFmpeg,而是提前启动上述缓存进程;事件处理函数改为:

  1. 计算目标时间范围(event.pts-10 到 event.pts+10)
  2. 匹配缓存的片段/流
  3. 调用FFmpeg完成截取/拼接生成目标文件

内容的提问来源于stack exchange,提问作者ganjim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 15:11:23