小米摄像头文件默认是一分钟一分钟的单独文件,视频存储在NAS,想合并成一个视频,虽然有工具合并,但是会导致文件非常大,找了好久找到个能用的,亲测可用,分享给有需要的人,代码和原理来自贴吧,就不在这放链接了
此方法不是直接复制的内存卡视频,而是选择存储在NAS保存在NAS中的文件结构,文件结构如下图:
代码需要ffmpeg环境支持,教程一搜一大推(直接搜“Windows搭建ffmpeg环境”),不做赘述,记得要下载Release builds文件,下载地址:https://www.gyan.dev/ffmpeg/builds/
代码说明如下:
1、复制代码
2、新建文本文档 -粘贴代码-另存为-文本格式改为ANSI-后缀名改为bat
3、将bat文件放在视频记录“小时文件夹”同级,双击运行
代码实现功能:
1、将“小时文件夹”内的所有1分钟时长的监控视频,合并成一个文件,文件名字为“年月日_时分秒.mov”(分秒依据“小时文件夹”内第一个文件获取),并将文件临时存放在“小时文件夹”同级,然后程序会有10分钟延时,按任意按键可继续,目的是在此期间检查合并是否正常。
2、然后继续依据mov文件名的“年月日”创建年\月\日文件夹,将所有mov文件移动到对应的文件夹中。
@echo off & setlocal EnableDelayedExpansion
for /f "delims=" %%a in ('dir /ad/b') do (
set name=%%a
set name=%cd%\!name:~,8!_!name:~-2!
set var=%cd%\%%a
set var=!var:\\=\!
echo !var!
cd "!var!"
for /f %%s in ('dir /b "*.mp4"') do (
echo file %%s >> files.txt
)
set /p ms=<"files.txt"
set name=!name!!ms:~5,2!!ms:~8,2!
ffmpeg -f concat -i files.txt -c copy !name!.mov
del files.txt
echo !name!.mov 已生成。
cd ..
)
TIMEOUT /T 600
for /f "delims=" %%z in ('dir /b *.mov') do (
set b=%%z
set c=!b:~,4!
set d=!b:~4,2!
set e=!b:~6,2!
echo %%z" "!c!\!d!\!e!
if not exist "%cd%\!c!\!d!\!e!" md "%cd%\!c!\!d!\!e!"
move "%%z" "!c!\!d!\!e!"
echo %%z 成功移动至 !c!\!d!\!e! 文件夹!
)pause
运行生成结果如下(还在运行中,按小时文件已生成):
如果是直接拔出内存卡处理,可参考此开源项目:https://github.com/tasy5kg/MiCameraVideoExporter,摄像头不好拿,故未测试,有需要的可以试试看
经过不断优化,脚本代码如下:
#!/bin/bash
export PATH=/mnt/user/backup/xiaomi_camera_videos/ffmpeg-7.0.2-amd64-static:/bin:/sbin:/usr/bin:/usr/sbin
shopt -s nullglob
cd /mnt/user/backup/xiaomi_camera_videos/111
# 获取当前日期(与文件名格式一致)
current_date=$(date +%Y%m%d) # 新增:获取YYYYMMDD格式的当天日期
# 生成分组文件时跳过当天文件
for file in *_*_*.mp4; do
file_date=$(echo "$file" | cut -d_ -f2 | cut -c1-8) # 从文件名提取日期
# 新增:跳过当天日期的文件
if [[ "$file_date" == "$current_date" ]]; then
echo "跳过当天文件: $file"
continue
fi
# 安全转义单引号并写入分组文件
printf "file '%s'\n" "$(echo "$file" | sed "s/'/'\\\\''/g")" >> "group_${file_date}.txt"
done
# 合并视频并清理(自动排除当天分组)
for list in group_*.txt; do
date=$(echo "$list" | cut -d_ -f2 | cut -d. -f1)
# 新增:二次验证日期(可选)
if [[ "$date" == "$current_date" ]]; then
echo "警告:发现意外生成的当天分组文件 $list,已跳过"
continue
fi
if ffmpeg -f concat -safe 0 -i "$list" -c copy "merged_${date}.mp4" -y; then
while IFS= read -r line; do
filename=$(echo "$line" | sed -n "s/^file '\(.*\)'$/\1/p")
[[ -f "$filename" ]] && rm -f -- "$filename"
done < "$list"
fi
rm -f -- "$list"
done
原文链接:https://www.52pojie.cn/forum.php?mod=viewthread&tid=1725406
文章评论