batch-file - 带有时间戳的ffmpeg jpg批处理脚本
问题描述
我目前有这个批处理脚本使用 ffmpeg 来缩放图像并放置在具有相同文件夹结构的新位置。如何在新缩放的 jpg 文件的文件名中包含原始 jpg 文件的时间戳?
这给出了名为 mH-S_IMG_0305 的文件
@echo off &setlocal
set /a nfile=0
echo Copying directory structure from %1 to %2 ...
xcopy /T "%~1" "%~2"
REM walk directory structure and convert each file in quiet mode
set "sourcefolder=%~1"
set "targetfolder=%~2"
for /R "%sourcefolder%" %%a in (*.JPG) do (
echo converting "%%~nxa" ...
set "sourcefile=%%~fa"
set "sourcepath=%%~dpa"
set "targetfile=%%~na.JPG"
setlocal enabledelayedexpansion
set "targetfolder=%targetfolder%!sourcepath:%sourcefolder%=!"
ffmpeg -v quiet -i "!sourcefile!" -vf scale=256x256 -q:v 1 -strftime 1 "!targetfolder!%Y-%m-%d_%H-%M-%S_!targetfile!"
endlocal
set /A nfile+=1
)
echo Done! Converted %nfile% file(s)
文件修改日期的工作版本:
@echo off &setlocal
set /a nfile=0
echo Copying directory structure from %1 to %2 ...
xcopy /T "%~1" "%~2"
REM walk directory structure and convert each file in quiet mode
set "sourcefolder=%~1"
set "targetfolder=%~2"
for /R "%sourcefolder%" %%a in (*.JPG) do (
echo converting "%%~nxa" ...
echo which has a timestamp of "%%~ta" ...
set "sourcefile=%%~fa"
set "sourcepath=%%~dpa"
set "targetfile=%%~na.JPG"
set "timestamp=%%~ta"
setlocal enabledelayedexpansion
set "timestamp=!timestamp: =_!"
set "timestamp=!timestamp::=-!"
set "timestamp=!timestamp:/=-!"
set "targetfolder=%targetfolder%!sourcepath:%sourcefolder%=!"
ffmpeg -v quiet -i "!sourcefile!" -vf scale=256x256 -q:v 1 "!targetfolder!!timestamp!_!targetfile!"
endlocal
set /A nfile+=1
)
echo Done! Converted %nfile% file(s)
使用 exiftool 尝试文件创建日期选项(这有效,但它经常停止,因此某处出现错误):
@echo off &setlocal
set /a nfile=0
echo Copying directory structure from %1 to %2 ...
xcopy /T "%~1" "%~2"
REM walk directory structure and convert each file in quiet mode
set "sourcefolder=%~1"
set "targetfolder=%~2"
for /R "%sourcefolder%" %%a in (*.JPG) do (
echo converting "%%~nxa" ...
echo which has a timestamp of "%%~ta" ...
set "sourcefile=%%~fa"
set "sourcepath=%%~dpa"
set "targetfile=%%~na.JPG"
set "timestamp=('exiftool -d %%Y%%m%%d_%%H%%M%%S -CreateDate %%~a')"
for /f "tokens=1,2 delims=x" %%a in ('exiftool -T -d %%Y%%m%%d_%%H%%M%%S -CreateDate "%%a"') do (
set "timestamp=%%a"
)
setlocal enabledelayedexpansion
set "targetfolder=%targetfolder%!sourcepath:%sourcefolder%=!"
ffmpeg -v quiet -i "!sourcefile!" -vf scale=256x256 -q:v 1 "!targetfolder!!timestamp!_!targetfile!"
endlocal
set /A nfile+=1
)
echo Done! Converted %nfile% file(s)
解决方案
for /R "%sourcefolder%" %%a in (*.JPG) do (
echo converting "%%~nxa" ...
echo which has a timestamp of "%%~ta" ...
set "sourcefile=%%~fa"
然后分析所需元素的“%%~ta”并酌情重新组装。在不知道您的日期/时间格式的情况下,精确的方向就变成了一本巨著。
好的,这是一具骷髅……甚至还不是万圣节!
@ECHO OFF
SETLOCAL
FOR /f "delims=" %%b IN ('dir /b /a-d *') DO (
SET "newfile=Y"
FOR /f "skip=4delims=" %%q IN ('dir /a-d /-c /tc "%%b"') DO IF DEFINED newfile (
SET "newfile="
ECHO %%~tb %%q
)
)
这应该产生一行格式
createdate createtime updatedate updatetime size name
对于每个文件。请注意,该/-c
选项会删除该size
字段中的千位分隔符 - 此处没有用,但将来可能有用。
所以 - 你已经证明你可以提取相关元素并重新组装它们。下一步是正确放置setlocal
家庭。
for /R "%sourcefolder%" %%a in (*.JPG) do (
set "timestamp=%%~ta"
set "timestamp=!timestamp: =_!"
... more timestamp manipulation etc ...
setlocal enabledelayedexpansion
set "targetfolder=%targetfolder%!sourcepath:%sourcefolder%=!"
ffmpeg -v quiet -i "!sourcefile!" -vf scale=256x256 -q:v 1 "!targetfolder!!timestamp!!targetfile!"
endlocal
set /A nfile+=1
)
应该
for /R "%sourcefolder%" %%a in (*.JPG) do (
set "timestamp=%%~ta"
setlocal enabledelayedexpansion
set "timestamp=!timestamp: =_!"
... more timestamp manipulation etc ...
set "targetfolder=%targetfolder%!sourcepath:%sourcefolder%=!"
ffmpeg -v quiet -i "!sourcefile!" -vf scale=256x256 -q:v 1 "!targetfolder!!timestamp!!targetfile!"
endlocal
set /A nfile+=1
)
因为!var!
参考仅在delayedexpansion
模式下有效。
那应该可以解决!timestamp!
问题
delayedexpansion
最好通过添加enabledelayedexpansion
第一setlocal
行(您的第一行)并完全删除剩余的setlocal
和endlocal
命令来完成整个任务。
当然,转换为 24 小时制时间(如果需要)并可能timestamp
以 (YY)YYMMDDHHSS 格式生成,因此生成的文件名按日期的字母顺序排列,这是一个小问题。
看...告诉你这是一本大部头...
@ECHO OFF
SETLOCAL
SET "fields=dd mm yyyy hh mn ampm"
FOR /r %%e IN (*) DO (
FOR %%b IN (c a w) DO (
FOR %%c IN (%fields%) DO SET "#%%b%%c="
FOR /f "tokens=1,2,3" %%u IN ('dir /a-d /t%%b /-c "%%e"^|findstr /v /b /c:" "^|findstr /i /e /c:" %%~nxe"') DO (
SET "filedata=%%u %%v %%w"
FOR %%y IN (/ - . : ",") DO CALL SET "filedata=%%filedata:%%~y= %%"
FOR /f "tokens=1*delims==" %%q IN ('set filedata') DO IF /i "%%q"=="filedata" FOR %%y IN (%%r) DO (
SET "placed="
FOR %%c IN (%fields%) DO IF NOT DEFINED placed IF NOT DEFINED #%%b%%c SET "#%%b%%c=%%y"&SET "placed=Y"
)
)
)
ECHO FOR %%e
SET #
ECHO ==========
)
我稍微调整了一下。
处理文件日期/时间数据的问题在于有多种格式,所有格式都乘以每个文件有三个不同的时间戳。因此这个片段。
外壳用于%%e
定义检查中的文件名。那里没有大问题。
下一步是用于控制正在处理的%%b
时间戳(创建、访问和写入)。
然后我们检查dir
清单。第一个findstr
处理以空格开头的行,第二个只选择以space文件名结尾的行,这应该可靠地检测到仅包含文件日期/时间数据的行。
该数据 afaaaa 将包含三组;日期、时间和安培/下午指示器。这些适用于%%u
和。将它们串在一起并分配给,然后用空格替换每个字段分隔符。结果将是从列表中检索的值的空格分隔列表。%%v
%%w
filedata
filedata
dir
我试图避免使用delayedexpansion
, 因此将=
其用作分隔符,只需将set
输出(格式filedata=fieldvaluelist
为 )分别标记为%%q
和%%r
。中的值%%q
匹配filedata
(如果存在类似变量filedataold
)然后处理%%r
。
这就是fields
进来的地方。它包含在您的机器上使用的序列中的字段名。我用dd/mm/yy hh:mn
. 美国用户通常会使用 dd-mm-yy hh:mn am/pm
.
%%r
将包含六个值。每个都依次分配给%%y
列表中的每个未定义变量fields
。placed
是一个标志,它确保候选人 in%%y
只被分配一次。
#cdd #cmm #cyyyy #chh #cmn #cmpm
因此,在我的机器上,文件的C create-dd 等的变量。
在典型的美国机器上,只需将fields
列表更改为mm dd yyyy hh mn ampm
,变量就会被适当地分配。
ampm
不应从fields
列表中省略。?ampm
如果不使用 am/pm,分配给的值将是垃圾(实际上是文件大小)。
该对象只是将所有时间戳数据抓取到单独的字段中。实际上使用这些数据完全是另一回事。程序员应了解 ampm 指标值是否有效以及字段是否可能包含前导零以进行进一步操作。
(至此结束第 2 卷)
推荐阅读
- firebase - Firestore,检查 valueChanges() 期间更改了哪些字段
- css - CSS:如何将一个 div 移到另一个上方?
- ios - 更新后无法打开 Realm Studio - Realm 文件当前在另一个进程中打开 - Mac 和 Realm Swift
- performance - 有效地循环子阵列
- c++ - libwebsockets:待处理的消息
- javascript - 如何使用 axios.delete() 请求发送 ID
- python - socket.io 回调中的 Flask 渲染模板
- javascript - 如何将包含json对象的文件格式化为json数组
- r - 在 R 中使用子集和最大函数
- tmux - 在 iterm2 或其他地方启动时的 tmux 颜色配置文件 (-2)