录像链路先验证“写出文件、查到时间段、导出播放”,再增加计划和存储卷管理。下面用 MediaMTX 1.15.3 和 FFmpeg 做独立本地实验,不需要相机或数据库。

创建录像服务

下载对应系统的 MediaMTX,使用解压目录中的可执行文件。在一个空工作目录保存 record-demo.yml:

rtspAddress: 127.0.0.1:17554
rtspTransports: [tcp]
rtmp: false
hls: false
webrtc: false
srt: false
playback: true
playbackAddress: 127.0.0.1:19996
paths:
tutorial:
source: publisher
record: true
recordFormat: fmp4
recordPath: ./recordings/%path/%Y-%m-%d_%H-%M-%S-%f
recordPartDuration: 1s
recordSegmentDuration: 5s
recordDeleteAfter: 24h

在 PowerShell 启动,路径替换为自己的程序位置:

Terminal window
& 'D:\Tools\mediamtx\mediamtx.exe' .\record-demo.yml

保持终端运行。17554 用于 RTSP,19996 用于录像回放 HTTP;绑定 localhost 只供本机实验。配置设置 24 小时后自动删除实验录像,长期保存需求要单独确定保留策略。

recordPath 不手写扩展名,由 recordFormat 自动添加。分段时长是目标/最小切分条件之一,关键帧与流结束会影响实际长度。

发布十二秒测试画面

另开一个 PowerShell,执行:

Terminal window
ffmpeg -re -f lavfi -i "testsrc2=size=640x360:rate=25:duration=12" -an -c:v libx264 -preset ultrafast -pix_fmt yuv420p -g 50 -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:17554/tutorial

命令结束后,工作目录的 recordings/tutorial/ 中应有已完成的 MP4 分段。-re 按接近实时的速度读取测试源,不能用于证明机器最大编码吞吐量。

查询并导出

在 PowerShell 查询已存在的录像:

Terminal window
$segments = Invoke-RestMethod 'http://127.0.0.1:19996/list?path=tutorial'
$segments
if (-not $segments) { throw '没有已完成录像,请先检查服务日志' }
$start = [Uri]::EscapeDataString($segments[0].start)
curl.exe --fail --output replay.mp4 "http://127.0.0.1:19996/get?path=tutorial&start=$start&duration=5&format=mp4"
ffprobe -v error -show_entries format=duration:stream=codec_name,width,height -of json replay.mp4
ffmpeg -v error -i replay.mp4 -f null -

数组为空时先检查发布是否成功、record 是否启用、运行目录和服务日志,不继续访问 [0]。返回的 start 是时间点,放进 URL 时编码;duration 的单位是秒。导出会受关键帧边界影响,请求 5 秒不保证文件精确为 5 秒;本例实际导出约 6 秒,按 ffprobe 与实际画面核对。

最后用播放器打开 replay.mp4。能列出文件不等于能解码,解码成功也不等于画面时间段符合用户选择,需对照实际播放。

平台如何建立索引

按设备/通道/Profile 查询录像时,索引需要记录媒体路径、存储卷、文件路径、起止时间、状态和文件大小。正在写入、已完成、缺失、损坏要分别表示,删除文件后也要更新索引。

多盘切换影响新录像写入位置,不会自动移动旧录像。回放应查询跨卷索引;数据库关联更新也不能证明新卷已开始写入。NAS 掉线、剩余空间不足和断电恢复都需要单独验证。

下一篇:采样、结果与告警。参考:MediaMTX 录像、录像回放。