【问题标题】:Remux MKV removing subtitles and unwanted audio tracks using mkvmerge in batch fileRemux MKV 在批处理文件中使用 mkvmerge 删除字幕和不需要的音轨
【发布时间】:2021-02-16 22:55:26
【问题描述】:

我正在创建一个 Windows 批处理文件来查找文件夹中的所有 mkv 文件,检查它是否有多个音轨和字幕。如果是这样,请删除除 ENG 和 UND 之外的所有字幕和所有音轨。但是,当我运行批处理文件时它崩溃了?我不知道为什么它开始这样做。加上变量之前没有设置。干净总是假的。请帮忙。

@echo on
setlocal ENABLEDELAYEDEXPANSION

set rootfolder="C:\Users\User\Desktop\mov"
set "clean=false"

echo Enumerating all MKVs under %rootfolder%

for /r %rootfolder% %%a in (*.mkv) do (   
 for /f %%s in ('mkvmerge -i "%%a" ^| find /c /i "subtitles"') do (
  if NOT [%%s]==[0] (
   set "clean=true"
  )
)

for /f %%b in ('mkvmerge -i "%%a" ^| find /c /i "audio"') do (
 if [%%b]gtr[1] (
  set "clean=true"
 )
)
        
if %clean%=="true" (
 mkvmerge -o "%%~dpna (clean)%%~xa" -a und,eng -s und,eng --no-subtitles "%%a"
)
)
echo Done
pause

【问题讨论】:

  • 请不要在帖子中使用标签,因为这会使遵循格式变得更加困难。我相信我已经修好了。无关结论:最后的)是多余的。
  • 抱歉格式化。我已经删除了最后一个)。批处理文件仍然崩溃。我添加了一个暂停,发现它在第一个 for 循环时崩溃了。

标签: batch-file subtitle audiotrack mkv


【解决方案1】:

很遗憾,您没有提及任何错误消息,所以我所能做的就是提供一些(我希望是建设性的)批评。

set rootfolder="C:\Users\User\Desktop\mov"
set "clean=false"

在这个标签上通常首选第二种格式,所以

set "rootfolder=C:\Users\User\Desktop\mov"

这允许在必要时轻松插入引号。它还可以防止您在代码中使用的终端空格和制表符。正如您编写的那样,任何尾随空格或制表符都将包含在分配给rootfolder 的值中,并可能导致混乱 - 由不可见字符引起的工作时间。一次被咬,两次害羞。

clean 显然被用作布尔值。就个人而言,我建议您 look here 使用布尔变量。这种用法的优点是它可以在code blocks(带括号的语句)中工作,而无需调用delayedexpansion

echo Enumerating all MKVs under %rootfolder%

for /r %rootfolder% %%a in (*.mkv) do (   

这两行中的%rootfolder% 需要为"quoted"

  if NOT [%%s]==[0] (

嗯。记住语法if [not] string==string

 if [%%b]gtr[1] (

然后在这里申请 - 我相信你的问题是常驻的。

这是if string (的格式,所以cmd应该反对,因为运算符无效((

正确的格式是

 if [%%b] gtr [1] (

或者最好

 if "%%b" gtr "1" (

或者最好是

 if %%b gtr 1 (

这里的问题是gtr(或字母比较运算符系列的任何其他成员)对任何随机字母字符串都没有意义。以if sequins equ acceptable ( 为例。 sequins 显然是 neq acceptable,但是使用您使用的语法,它将是 if sequinsequacceptable ( 应该解释为 if s equ insequacceptable (if sequins equ acceptable ( 吗?

第二种形式更好。它允许比较包含空格的字符串。但是有一个问题。 if "123" gtr "2" 将被评估为 FALSE,因为比较是按字母顺序进行的; "1" 小于 "2" 所以结果是 FALSE

因此是第三种形式,它对数字比较有效(但如果 either 操作数中的一个为非数字,则将被解释为字符串形式。

【讨论】:

    【解决方案2】:

    这里有两个问题。

    正如您所发现的,其中一个问题是第一个 for() 循环缺少一个 )。你有 for( for( if( ) ):

    for /r %rootfolder% %%a in (*.mkv) do (   
     for /f %%s in ('mkvmerge -i "%%a" ^| find /c /i "subtitles"') do (
      if NOT [%%s]==[0] (
       set "clean=true"
      )
    )
    

    应该是:

    for /r %rootfolder% %%a in (*.mkv) do (   
     for /f %%s in ('mkvmerge -i "%%a" ^| find /c /i "subtitles"') do (
      if NOT [%%s]==[0] (
       set "clean=true"
      )
     )
    )
    

    由于第一个 for 循环没有被关闭,它导致脚本的其余部分被包含在其中,这就是为什么 %clean% 永远不会为真,因为它没有展开,所以总是等于在读取初始 for 循环之前给出的值,在这种情况下为 false。

    不过,这只是让它意外地工作。 (编辑:在看了这个之后才意识到你确实打算让所有东西都落在最初的 for 循环之下,并且缩进刚刚关闭。所以最后的“额外”)并不是不需要的,并且只删除它情况更糟。这就是为什么正确的缩进很重要。尽管如此,如前所述,%clean% 将始终为 false,因为它位于 for 循环中,因此它需要是 !clean!。同样,这只会导致它无法按预期工作,并且与崩溃无关。)实际上导致它崩溃的问题是行

    if [%%b]gtr[1] (
    

    这是不正确的语法,不被视为完整的 if 语句,因此使用 ( 来打开语句的“then”部分被视为错误。它应该是

    if [%%b] gtr [1] (
    

    甚至可能

    if %%b gtr 1 (
    

    因为这里不需要方括号,我不确定它们是否会引起问题。

    您的代码给出了“(此时意外”的错误,这将为您提供有关问题的很大线索。正如@Magoo 所提到的,您没有提供任何错误消息,但是在调试时您需要注意并使用它们。

    另外,您不需要打开回声。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-27
      • 1970-01-01
      • 2018-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      相关资源
      最近更新 更多