我的情况:
我在一个文件夹中有多个 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'.