资讯动态

MediaMTX 定时抓帧快照:基于 runOnAvailable 钩子 + FFmpeg 的流截图方案

发布时间:2026/9/13 11:11:47 来源:尧图企业网站定制
MediaMTX 定时抓帧快照基于 runOnAvailable 钩子 FFmpeg 的流截图方案【免费下载链接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.项目地址: https://gitcode.com/GitHub_Trending/me/mediamtxMediaMTX 作为通用的实时媒体服务器本身不做视频解码但可以通过runOnAvailable钩子把流已就绪这个事件暴露给外部命令从而借助 FFmpeg 从 RTSP 拉流并周期性地抽取单帧画面保存为 JPG 快照。本文围绕 docs/2-features/13-extract-snapshots.md 中的方案完整讲解快照目录规划、抓帧命令、间隔控制、钩子生命周期与环境变量并结合仓库源码说明底层调用机制读完即可在自己的 MediaMTX 实例上落地一套按路径定时出图的监控截图流程。方案概览为什么用 runOnAvailable 而不是手动脚本runOnAvailable是 MediaMTX 提供的路径级钩子Hook当某个 path 上开始有可读的流时触发执行指定的外部命令当流不再可用时该命令会收到 SIGINT 被终止详见 钩子文档。这与本需求的契合点在于快照抓取逻辑完全在钩子命令里实现MediaMTX 只负责流一上线就拉起命令、流一下线就停掉命令无需解码任何视频数据抓帧用 FFmpeg 完成MediaMTX 不需要内置任何转码能力方案与媒体服务器只做分发的架构保持一致命令内部是一个while true循环天然支持以固定间隔如 10 秒反复抽帧直到流消失为止。因此该方案的核心是钩子负责生命周期、FFmpeg 负责抽帧、shell 循环负责定时三段式配合。基础配置完整的抓帧钩子示例在配置文件仓库根目录的 mediamtx.yml 即为其标准模板中把钩子写进pathDefaults可对所有 path 生效pathDefaults: runOnAvailable: | bash -c while true; do mkdir -p $(dirname snapshots/$MTX_PATH) ffmpeg -i rtsp://localhost:8554/$MTX_PATH -frames:v 1 -update true -y snapshots/$MTX_PATH.jpg sleep 10 done其中10就是两次快照之间的间隔秒数可按需调整。逐行拆解这段命令片段作用bash -c ...用 bash 执行多行脚本YAML 的\|块标量保留换行配合双引号字符串即可承载整个循环体mkdir -p $(dirname snapshots/$MTX_PATH)依据路径名创建对应目录。$MTX_PATH是钩子注入的环境变量值为 path 名可能含/如cam/gate因此先取dirname建目录避免 FFmpeg 因目录不存在而写入失败ffmpeg -i rtsp://localhost:8554/$MTX_PATH从本机 RTSP 服务默认端口 8554拉取与 path 同名的实时流作为输入-frames:v 1只解码输出 1 帧视频画面即抓一张图-update true让 image2 muxer 进入单图覆盖模式重复写入同一个文件时覆盖旧文件而不是自动追加编号如out-001.jpg、out-002.jpg-y输出文件已存在时直接覆盖配合循环中的重复抓帧保证快照始终是最新一帧snapshots/$MTX_PATH.jpg输出文件路径最终效果是snapshots/path名.jpg例如snapshots/cam/gate.jpgsleep 10抓完一帧后休眠 10 秒形成周期性的快照节奏这里有一个值得注意的细节RTSP 地址中的$MTX_PATH和输出文件名中的$MTX_PATH会同时被展开。MediaMTX 的钩子环境变量通过os.Expand注入见 internal/externalcmd/cmd.go 中的expandEnv实现因此同一变量可复用于拉流 URL、目录结构与文件名一个 path 对应一套完整快照。钩子的可用环境变量runOnAvailable触发时MediaMTX 会注入以下环境变量与 mediamtx.yml 中该钩子注释以及 钩子文档 的描述一致变量含义MTX_PATHpath 名称MTX_QUERY发布者携带的查询参数URL 编码MTX_SOURCE_TYPE流来源类型如rtsp、rtmp、webrtc、rtspPull等MTX_SOURCE_ID流来源的唯一 IDRTSP_PORTRTSP 服务端口G1、G2、…若 path 名是正则表达式则为各捕获组匹配到的内容其中MTX_SOURCE_TYPE与MTX_SOURCE_ID在源码中由钩子调用处显式注入见 internal/hooks/on_available.go可用来在快照文件名中区分不同来源的流。快照方案的关键参数与调优抓帧间隔sleep 10的值即间隔秒数。间隔越小快照越密集但会持续占用 FFmpeg 进程与网络带宽由于 FFmpeg 每次都要重新建立 RTSP 会话并解码到关键帧sleep过短如小于 1 秒意义不大一般监控场景取 530 秒较合理。帧选择与画质-frames:v 1取的是解码后输出的第一帧画面具体是哪一帧由推流端的关键帧间隔IDR 周期与 FFmpeg 解码节奏决定并不能保证是当前最新画面。若需要控制快照画质可追加-q:v参数指定 JPEG 质量如-q:v 2质量较高例如ffmpeg -i rtsp://localhost:8554/$MTX_PATH -frames:v 1 -q:v 2 -update true -y snapshots/$MTX_PATH.jpg输出格式-update true配合.jpg后缀是周期性覆盖单张图的标准写法。如果希望每次抓帧都保留历史可以把文件名改为带时间戳的格式注意此时不应使用-update trueffmpeg -i rtsp://localhost:8554/$MTX_PATH -frames:v 1 -y snapshots/$MTX_PATH-$(date %Y%m%d%H%M%S).jpg只对特定 path 生效pathDefaults会作用于所有 path若只想对某一路流抓帧可把钩子写在paths下对应的 path 条目中实现逐路定制间隔与目录paths: gate_cam: runOnAvailable: | bash -c while true; do mkdir -p snapshots/gate_cam ffmpeg -i rtsp://localhost:8554/gate_cam -frames:v 1 -update true -y snapshots/gate_cam.jpg sleep 5 done与钩子生命周期配套的配置项runOnAvailableRestart默认false见 mediamtx.yml 中runOnAvailableRestart: false。当命令在流存续期间意外退出时置为true会让 MediaMTX 自动重启命令从源码看重启前会有 5 秒的固定停顿见 internal/externalcmd/cmd.go 中的restartPause 5 * time.Second避免崩溃后高频重试。对于快照这种长时间循环任务建议保持默认false或自行在脚本内处理错误。runOnUnavailable流不可用消失、断流时执行的命令环境变量与runOnAvailable相同。在抓帧场景里可用它做收尾清理例如删除孤立的快照文件pathDefaults: runOnAvailable: | bash -c while true; do mkdir -p $(dirname snapshots/$MTX_PATH) ffmpeg -i rtsp://localhost:8554/$MTX_PATH -frames:v 1 -update true -y snapshots/$MTX_PATH.jpg sleep 10 done runOnUnavailable: rm -f snapshots/$MTX_PATH.jpg与旧的 runOnReady 的兼容历史版本中的runOnReady/runOnReadyRestart/runOnNotReady已废弃配置解析时会自动迁移到runOnAvailable/runOnAvailableRestart/runOnUnavailable见 internal/conf/path.go 的迁移逻辑旧配置仍可继续工作但新配置请使用runOnAvailable系列参数。源码视角runOnAvailable 钩子的实际触发链路runOnAvailable钩子在内核路径对象中随流上线被注册。在 internal/core/path.go 中可以看到调用点当流初始化成功、availableTime被记录之后MediaMTX 立即构造hooks.OnAvailableParams并调用hooks.OnAvailable返回的闭包即为后续用于流不可用时的回调。internal/hooks/on_available.go 中的实现进一步揭示了生命周期管理逻辑只要RunOnAvailable非空就以externalcmd.Cmd方式启动命令并按RunOnAvailableRestart决定是否自动重启Cmd.Restart字段命令运行期间日志会输出runOnAvailable command started退出时输出runOnAvailable command exited便于在日志中排查抓帧脚本异常返回的闭包被保存为onUnavailableHook当流不可用时先向运行中的抓帧命令发送 SIGINT对应钩子文档中流不再可用时以 SIGINT 终止命令的说明随后执行runOnUnavailable命令若配置。这个启动时注入环境变量、结束时发 SIGINT的机制正是抓帧循环能够流在就抓、流断就停的底层保证脚本里的sleep 10循环不会在无流时空转也不会在流恢复后残留多个 FFmpeg 进程。验证与排错配置完成后可通过以下步骤确认快照链路是否正常用任意方式向某个 path 推流如ffmpeg -re -i input.mp4 -c copy -f rtsp rtsp://localhost:8554/mypath或触发runOnInit/runOnDemand拉起静态源等待约一个sleep间隔后检查snapshots/mypath.jpg是否生成图片内容是否为流中最新画面在 MediaMTX 日志中查找runOnAvailable command started与若异常退出时的runOnAvailable command exited记录停止推流确认抓帧进程被 SIGINT 终止日志出现runOnAvailable command stopped若配置了runOnUnavailable验证其收尾命令是否按预期执行。常见问题快照目录不存在导致 FFmpeg 报错务必保留mkdir -p步骤、$MTX_PATH含子路径时输出文件名嵌套目录由dirname逻辑处理、以及-update true缺失导致生成带编号的递增文件而非单张覆盖图。小结通过runOnAvailable钩子 FFmpeg 的-frames:v 1 -update true组合MediaMTX 在不引入任何转码负担的前提下即可为任意 path 提供周期性单帧快照。该方案完全复用 MediaMTX 已有的钩子生命周期管理启动/终止/重启/环境变量注入配置仅需一段 shell 脚本同时支持按 path 定制、按来源区分、断流清理与历史留档等扩展是监控大屏、安防预览、封面生成等场景的轻量级截图方案。【免费下载链接】mediamtxReady-to-use Media-over-QUIC / SRT / WebRTC / RTSP / RTMP / LL-HLS / MPEG-TS / RTP live media server and media proxy that allows to read, publish, proxy, record and playback real-time video and audio streams.项目地址: https://gitcode.com/GitHub_Trending/me/mediamtx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价