【问题标题】:FFprobe command in a var in IF statementIF 语句中 var 中的 FFprobe 命令
【发布时间】:2018-04-09 11:52:35
【问题描述】:

我正在尝试设置一个批处理文件(当前在 CMD 提示符下测试)以在目录发生更改时运行。我有一个存储在变量“test”中的命令,它告诉我第一个音频编解码器是什么。如果不是 aa3,我计划用 ffmpeg 重新编码音频。我的第一个问题是,当我尝试使用我的 var 运行一个简单的 if 语句时,我得到一个错误。

set test=ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv"

当我运行 %test% 时,它会返回预期的结果。

如果我这样运行:

if %test% == "ac3" echo true

我明白了:

-v was unexpected at this time.

我的最终目标是在将某些内容添加到文件夹时获得类似的内容(还没有去当某些内容发生变化时...可能只是每天运行一次 idk):

set test=ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "%f"

set outpath=S:\Blu Ray\New folder\"%f"

for %f in (*.mkv) DO
    if %test% <> "ac3" (
        ffmpeg -i “%f” -vcodec copy -scodec copy -acodec ac3 -b:a 640k “%outpath%";
del "%f";
move "%outpath%" "s:\Blu Ray\")

任何帮助都会很棒

BD

【问题讨论】:

  • 您不能像使用 BASH 那样将命令的输出分配给批处理文件中的变量。您也不能将 与 IF 命令一起使用。您可能应该通过打开 cmd 提示符并键入:if /? 来阅读 IF 命令的帮助文件。此外,在进行 IF 比较时,您需要意识到这是一个真正的字符串比较。因此,报价需要在比较的每一侧才能成立。查看您的FOR 命令,您可能还想阅读相关帮助。它清楚地表明您需要在批处理文件中使用两个百分比符号。
  • 啊好吧。是的,我知道 %%,我说我正在 CMD 提示符下进行测试。谢谢
  • 另外,这并不能解释为什么我得到 -v 错误。即使我将 FFprobe 语句放在 if 语句中,我仍然会得到 -v 错误。
  • 因为您的变量测试没有引号。所以 if 命令从字面上看到你分配给变量 test 的整个字符串。它将 ffprobe 之后的空格视为必须比较的字符串的结尾。它尝试读取 -v 作为比较运算符。
  • 我以“%test%”的身份完成了它并得到了同样的结果。

标签: batch-file cmd ffmpeg ffprobe


【解决方案1】:

命令行

if %test% == "ac3" echo true

在执行IF命令之前由Windows命令解释器预处理

if ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv" == "ac3" echo true

双引号字符串之外的空格字符被解释为参数分隔符。因此,第一个参数用于命令 IF ffprobe,第二个参数是 -v,第三个参数是 error。

-v 用于命令 IF 未知运算符,结果是错误消息:

-v 这个时候出乎意料。

标准解决方案是将两个字符串双引号以进行比较,因为在双引号字符串中,空格字符以及 &amp;()[]{}^=;!'+,`~|&lt;&gt; 被解释为文字字符。

if "%test%" == "ac3" echo true

命令 IF 比较双引号字符串总是包含双引号作为字符串,并且从不在任何一侧使用双引号运行整数比较。

但在这种情况下使用if "%test%" == "ac3" echo true 也无法按预期工作,因为执行的命令行是:

if "ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv"" == "ac3" echo true

现在第一个 IF 参数是 "ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my,第二个参数是 movie 导致错误消息:

电影在这个时候出乎意料。

必须使用延迟的环境变量扩展,将包含双引号的字符串分配给环境变量,并使用 IF 命令与另一个字符串进行比较。

set "test=ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv""
setlocal EnableDelayedExpansion
if "!test!" == "ac3" echo true
endlocal

另请参阅Why is no string output with 'echo %var%' after using 'set var = text' on command line? 为什么使用set "test=..." 的答案并阅读this answer 以了解有关命令 SETLOCAL 和 ENDLOCAL 的详细信息。

但是,我们的目标是将控制台可执行文件ffprobe 的输出与字符串ac3 进行比较。
这需要使用 FOR。

for /F "delims=" %%I in ('ffprobe.exe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "my movie (2017).mkv" 2^>^&1') do if /I "%%I" == "ac3" echo true

命令 FOR 运行在'...' 之间指定的命令行,在单独的命令进程中以cmd.exe /C 在后台启动,而不打开窗口,并捕获写入的所有输出处理 STDOUT 用于逐行处理此输出,从而忽略空行和以分号开头的行。

2&gt;&amp;1 导致写入处理 STDERR 的ffprobe.exe 的输出也在后台命令进程中被重定向以处理 STDOUT 以便也被 为。

重定向运算符 &gt; 和 &amp; 必须在此处转义,两者都使用插入符号 ^ 在 Windows 命令解释器解析整个 FOR 命令行时首先被解释为文字字符。

我没有安装 ffprobe.exe,因此无法测试整个 FOR 命令行。但是 FOR 命令行应该在 ffprobe.exe 输出的情况下工作,实际上只是将 ac3 输出到 STDOUT 或 STDERR 而没有别的。用双引号括起来的ffprobe.exe 的输出与"ac3" 比较不区分大小写。

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

  • endlocal /?
  • for /?
  • if /?
  • set /?
  • setlocal /?

另请阅读有关 Using command redirection operators 的 Microsoft 文档。

【讨论】:

  • 有些东西还是没用。不过谢谢你非常详细的回复!!!
  • @bdrilling33 也许ac3 的输出带有额外的空白字符。您可以在 FOR 命令行上删除 "delims=" 并查看是否会改变某些内容。此外,我建议使用&gt;stdoutput.txt 2&gt;stderror.txt 的cmd 窗口中的参数运行ffprobe 并查看两个文本文件。哪个是空的?非空文本文件(ANSI、UTF-8、UTF-16)的编码是什么?非空文本文件是否包含空白字符(空格、制表符、空行)?
  • 我运行了 ffprobe.exe -v error -select_streams a:0 -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "My Movie (2017).mkv" >stdoutput。 txt 2>stderror.txt和stderror.txt是空的,另一个里面有ac3。
猜你喜欢
  • 2013-09-18
  • 2021-06-21
  • 2021-02-12
  • 1970-01-01
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多