如何在带有文件排除列表的计划批处理文件中 运行 ffmpeg?

How to run ffmpeg in a scheduled batch file with a file exclusion list?

我将以下批处理文件创建到 运行 作为计划任务。它在我的主媒体文件夹中自动将音频编码为 AAC。一切正常,但现在我还需要做两件事:

  1. 完成后删除原件。
  2. 设置它以便下次 运行 时,它不会尝试转换已经转换的文件。

这可能吗?那看起来怎么样?有没有办法 "disregard" 包含 CONVERTED 的文件名?

for /r "C:\Users\USER\Desktop\TEST" %%a in ("*.mkv") do ffmpeg -i "%%a" -vcodec copy -acodec aac -ac 2 -ab 256K %%~dpnaCONVERTED.mkv

这可以通过以下批处理文件完成:

@echo off
for /F "eol=| delims=" %%I in ('dir "%UserProfile%\Desktop\TEST\*.mkv" /A-D-H /B /S 2^>nul ^| %SystemRoot%\System32\findstr.exe /E /I /L /V /C:CONVERTED.mkv 2^>nul') do (
    ffmpeg.exe -i "%%I" -vcodec copy -acodec aac -ac 2 -ab 256K "%%~dpnICONVERTED.mkv"
    if not errorlevel 1 del "%%I"
)

命令 FOR 在后台以 cmd.exe /C 启动的单独命令进程中执行(= 不可见)命令行:

dir "C:\Users\USER\Desktop\TEST\*.mkv" /A-D-H /B /S 2>nul | C:\Windows\System32\findstr.exe /E /I /L /V /C:CONVERTED.mkv 2>nul

所以后台没有控制台的命令进程window是第一个运行ning命令DIR输出

  • 所有非隐藏文件,因为 /A-D-H(属性不是目录且未隐藏)
  • 匹配通配符模式*.mkv
  • 因为 /B 只表示文件名
  • ,所以是裸格式
  • 在指定目录及其所有子目录中因为/S
  • 完整路径也是因为 /S
  • 处理STDOUT.
如果找不到任何 *.mkv 文件,

DIR 会输出一条错误消息。为处理 STDERR 而编写的错误消息通过使用 2>nul.

将其重定向到设备 NUL 来抑制

文件名由DIR逐行处理STDOUT输出全路径由|重定向处理STDIN 下一个命令 FINDSTR.

FINDSTR 在文件名列表中搜索

  • 比较字符串CONVERTED.mkv
  • 在行尾因为 /E
  • case-insensitive 因为 /I
  • 字面上是因为 /L
  • 并输出因为/V.
  • 的反转结果

这意味着 FINDSTR 输出行 not 以 case-insensitive 结尾,按字面解释比较字符串 CONVERTED.mkv 到忽略在先前执行批处理文件时已转换的 *.mkv 文件。

可能 FINDSTR 找不到任何符合搜索条件的行,因此输出一条错误消息来处理 STDERR 这通过使用 2>nul 将其重定向到设备 NUL.

来抑制

命令FOR捕获写入处理后台命令进程STDOUT的输出,这是的输出DIR 使用 FINDSTR 过滤,然后逐行处理此输出。

FOR 忽略空行。但这在这里并不重要,因为具有完整路径的文件名列表不包含空行。

以分号开头的行也会被 FOR 忽略,但此行为已通过 eol=| 修改为仅忽略以竖线开头的行。竖线在这里是不可能的,因为任何目录或文件都不能在名称中包含竖线。那么,具有完整路径的文件名也几乎不可能以分号开头。所以这里真的不需要eol=|

FOR with parameter /F 默认情况下使用 space 和水平制表符作为字符串分隔符将一行拆分为子字符串,并仅分配第一个 space/tab 分隔字符串到指定的循环变量 I。这种拆分行为在这里不需要,因为 的正文命令块中需要 FOR 始终是 MKV 文件的完整限定名称,即使路径或文件名包含 space 字符。出于这个原因,指定 delims= 来定义一个空的分隔符列表,该列表禁止将行拆分为子字符串。

ffmpeg.exe 被执行,我没有安装,所以我只能假设它在成功时以 0 退出,在错误时以任何大于 0 的值退出。

已执行的应用程序或命令的退出代码由 Windows 命令解释器分配给环境变量 ERRORLEVEL

IF 条件检查 ffmpeg.exe 是否退出 而不是 且值 大于或等于 1,即 0(或负值)表示成功。在这种情况下,输入文件被删除,以防止在此批处理文件的下一个 运行 上再次转换同一文件。

要了解使用的命令及其工作原理,请打开命令提示符 window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • dir /?
  • echo /?
  • findstr /?
  • for /?
  • if /?

另请阅读有关 Using Command Redirection Operators 的 Microsoft 文章,了解 2>nul| 的解释。重定向运算符 >| 必须在 FOR 命令行上使用脱字符 ^ 进行转义,以便在 Windows 时被解释为文字字符] 命令解释器在执行命令 FOR 之前处理此命令行,该命令在后台启动的单独命令进程中执行嵌入式命令行。