如何用FFmpeg/FFmpeg-Python同时从多RTSP流定期保存快照?
实现多RTSP流快照采集与文件数量限制
可以通过FFmpeg原生命令或FFmpeg-Python实现需求,以下是具体方案:
一、FFmpeg原生实现
1. 单流快照+文件数量限制
利用FFmpeg的segment滤镜结合segment_wrap参数,可实现类似GStreamer的max-files效果,自动循环覆盖旧文件,无需额外清理脚本。命令示例:
# 处理单个RTSP流,每5秒存一张快照,最多保留10张(循环覆盖) ffmpeg -i rtsp://your-stream-url -filter:v "fps=0.2,segment=segment_time=5:segment_wrap=10" -f image2 ./stream-%02d.jpeg
fps=0.2:控制每5秒输出一张快照(1/5=0.2)segment_wrap=10:限制最多保留10个文件,达到数量后从第一个文件开始覆盖
2. 多流批量处理
针对10-60个RTSP流,推荐为每个流启动独立的FFmpeg进程(现代服务器可轻松承载),可通过shell脚本批量启动:
# 示例bash脚本:批量处理多个RTSP流 #!/bin/bash # 定义RTSP流列表 RTSP_STREAMS=( "rtsp://stream-1-url" "rtsp://stream-2-url" # ... 其他流地址 ) MAX_FILES=10 OUTPUT_DIR="./snapshots" mkdir -p $OUTPUT_DIR # 逐个启动FFmpeg进程 for idx in "${!RTSP_STREAMS[@]}"; do ffmpeg -i "${RTSP_STREAMS[$idx]}" -filter:v "fps=0.2,segment=segment_time=5:segment_wrap=$MAX_FILES" -f image2 "$OUTPUT_DIR/stream-$idx-%02d.jpeg" & done # 等待所有进程运行 wait
二、FFmpeg-Python实现
通过多线程为每个RTSP流创建独立的处理任务,结合segment滤镜实现文件数量限制:
import ffmpeg import threading import os def process_stream(source, output_prefix, max_files=10): # 创建输出目录 os.makedirs(os.path.dirname(output_prefix), exist_ok=True) output_pattern = f"{output_prefix}-%02d.jpeg" try: ( ffmpeg .input(source) .filter("fps", fps=1/5) # 每5秒一张快照 .filter("segment", segment_time=5, segment_wrap=max_files) # 限制文件数量 .output(output_pattern, format="image2") .run(quiet=True) ) except Exception as e: print(f"处理流 {source} 出错: {str(e)}") # 配置参数 RTSP_STREAMS = [ "rtsp://stream-1-url", "rtsp://stream-2-url", # ... 补充你的10-60个流地址 ] MAX_FILES_PER_STREAM = 10 OUTPUT_BASE_DIR = "./stream-snapshots" # 启动多线程处理 threads = [] for stream_idx, stream_url in enumerate(RTSP_STREAMS): output_prefix = f"{OUTPUT_BASE_DIR}/stream-{stream_idx}" thread = threading.Thread(target=process_stream, args=(stream_url, output_prefix, MAX_FILES_PER_STREAM)) threads.append(thread) thread.start() # 等待所有线程完成 for thread in threads: thread.join()
补充说明
- 如果需要保留最新N个文件而非循环覆盖,可在生成快照后通过脚本(Python/shell)定期清理旧文件:遍历输出目录,按文件修改时间排序,删除超过数量限制的最早文件。
- 多流处理时,若服务器资源有限,可适当调整线程/进程数量,或使用进程池控制并发数。
内容的提问来源于stack exchange,提问作者Haydn Morris
相关产品推荐
相关产品推荐

