MKVMERGE & cmd 批量合并视频和字幕

MKVMERGE & cmd 批量合并视频和字幕

我的情况:

我在一个文件夹中有多个 mkv 文件和单独但对应的 srt 文件,我想将它们混合在一起。

我只对当前目录中的文件感兴趣,并且我正在从 Win10 x64 上的 cmd 窗口运行脚本。

我想将生成的混合文件写入原始目录下的一个新的子目录中。

例子:

  • 视频1.mkv
  • 字幕1.srt
  • 视频2.mkv
  • 字幕2.srt
  • 视频3.mkv
  • 字幕3.srt

我发现了一个带有脚本的线程,它基本上可以完成我想做的事情:https://forum.videohelp.com/threads/365907-MKVMERGE-Batch-Muxing-multiple-audio-and-su...ks#post2407646

我已将该脚本修改为:

for %%a in (.) do call :set_file_names
:set_file_names
    set "output_name="
    set "input_name="
    set "subtitle_name="
    for %%m in (*.mkv) do set "output_name=%%~dpmtemp\%%~nxm" & set "input_name=%%~nxm"
    for %%m in (*.srt) do set "subtitle_name=%%~nxm" & call :mux
:mux
    echo ***** Starting MKVmerge *****
    "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%output_name%" --language 0:eng --default-track-flag 0:yes --audio-tracks 1 --language 1:eng --default-track-flag 1:yes "%input_name%" --language 0:eng --track-name 0:English "%subtitle_name%"

我的问题是设置 mkv 文件名的行总是导致最后一个(在我的示例中是第三个)文件名。

它正确地迭代了字幕文件名并生成:

  • 视频3.mkv + 字幕1.srt
  • 视频3.mkv + 字幕2.srt
  • 视频3.mkv + 字幕3.srt

我确信有一个简单的解决方法,但作为批处理文件新手,这对我来说并不明显!

有人可以帮忙吗?

更新#1:根据@stephan的评论,我的脚本现在看起来像这样,而且我似乎更接近答案,但它仍然不起作用:

for %%M in (*.mkv) do (
    for %%S in (%%~n_*.srt) do (
        "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%%~dpMtemp\%%~nxM" "%%~nxM" "%%~nxS"
    )
)

执行后,会产生 3 个 mkvmerge 结果,其中有正确的 mkv 文件,但没有任何 srt 文件。脚本似乎没有正确获取 srt 文件名? 脚本结果的屏幕截图 有什么建议么?

答案1

因此,另一个论坛上的某个人给出了一个对我有用的答案:

@echo off
set /a "outernum=0"
for %%m in (*.mkv) do set "output_name=%%~dpmtemp\%%~nxm" & set "input_name=%%~nxm" & call :inner
exit /b

:inner
    set /a "innernum=0"
    for %%m in (*.srt) do set "subtitle_name=%%~nxm" & call :mux
    set /a "outernum+=1"
    exit /b

:mux
    if %outernum% equ %innernum% (
        echo ***** Starting MKVmerge *****
        "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%output_name%" "%input_name%" "%subtitle_name%"
    )
    set /a "innernum+=1"

答案可以在这里的上下文中看到

答案2

你不需要循环.mkv遍历.srt文件。只需遍历文件.mkv并让脚本搜索匹配项srt(很简单,因为.srt以相同的标题开头)。

未经测试,因此您可能需要进行一些调整(我对语法一无所知mkvmerge)。

@echo off
for %%M in (*.mkv') do (
  for %%S in (%%~nM_*.srt) do (
    "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%%~dpMtemp\%%~nxM" --language 0:eng --default-track-flag 0:yes --audio-tracks 1 --language 1:eng --default-track-flag 1:yes "%%M" --language 0:eng --track-name 0:English "%%S"
  )
)

注意:如果您有不同的.srt文件(不同的语言),这将尝试创建多个具有相同名称的输出文件(不知道 mkvmerge 在这种情况下会如何表现)

答案3

@echo off 
setlocal enabledelayedexpansion
cd /d "%~dp0" && 2>nul mkdir "%~dp0temp"

set "_mkv="C:\Program Files\MKVToolNix\mkvmerge.exe""
set "_arg_0=--verbose --priority higher --default-track-flag 0:yes --track-name 0:_SRT_"
set "_arg_1= --language 0:eng File_SRT --flush-on-close --disable-track-statistics-tags"

for %%i in =;(*.mkv);= do for %%I in =;("%%~ni*.srt");= do echo\"%%~nxI" | 2>nul findstr /i _CC\.srt >nul && =;(
     !_mkv! -o ".\temp\%%~nxi" ".\%%~nxi" !_arg_0:_SRT_=ClosedCaption! !_arg_1:File_SRT=".\%%~nxI"! | findstr ':
    );= || !_mkv! -o ".\temp\%%~nxi" ".\%%~nxi" !_arg_0:_SRT_=English! !_arg_1:File_SRT=".\%%~nxI"! | findstr ':
       
endlocal && goto :eof

文件:

video1.mkv
video1_OS_English_CC.srt
video2.mkv
video2_OS_English.srt

命令行:

"C:\Program Files\MKVToolNix\mkvmerge.exe" -o ".\temp\video1.mkv" ".\video1.mkv" --verbose --priority higher --default-track-flag 0:yes --track-name 0:ClosedCaption --language 0:eng ".\video1_OS_English_CC.srt" --flush-on-close --disable-track-statistics-tags
"C:\Program Files\MKVToolNix\mkvmerge.exe" -o ".\temp\video2.mkv" ".\video2.mkv" --verbose --priority higher --default-track-flag 0:yes --track-name 0:English --language 0:eng ".\video2_OS_English.srt" --flush-on-close --disable-track-statistics-tags

输出:

'.\video1.mkv': Using the demultiplexer for the format 'Matroska'.
'.\video1_OS_English_CC.srt': Using the demultiplexer for the format 'SRT subtitles'.
'.\video2.mkv': Using the demultiplexer for the format 'Matroska'.
'.\video2_OS_English.srt': Using the demultiplexer for the format 'SRT subtitles'.

答案可以在这里的上下文中看到

相关内容