首页 > 解决方案 > 带有时间戳的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)

标签: batch-fileffmpeg

解决方案


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行(您的第一行)并完全删除剩余的setlocalendlocal命令来完成整个任务。

当然,转换为 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%%wfiledatafiledatadir

我试图避免使用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列表中的每个未定义变量fieldsplaced是一个标志,它确保候选人 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 卷)


推荐阅读