2

I have a folder containing different video and subtitle types, with each set of videos and subtitles having the same file name, and some videos with no subtitles. For example,

video01.mp4

video01.srt

video02.mkv

video02.srt

video03.mp4

video03.sub and .idx

video04.mkv

video05.mkv

video05.sub and .idx

video06.mp4

video06.srt

video06.sub and .idx

and so on. The example above uses only two types of videos (mp4 and mkv) and subtitles (srt and sub/idx). Notice that video06 has two types of subtitles (srt and sub/idx) while video04 has no subtitles.

Is it possible to make a batch file that will go over the folder and mkvmerge any video type (mkv or mp4 in this case) with any available subtitles (in this case, srt, sub/idx, or both), and output to an mkv that will be written in another folder? Given the example above,

video01.mp4 and video01.srt will be merged using mkvmerge and the output, video01.mkv, will be written to a new folder

Hopefully, I can add other video types (like avi) to the code if needed.

2

This should do what you're after. Save it as "mkvmerger.bat" and put it in the path along with mkvmerge.exe

I wrote this originally to do something very similar with ffmpeg. This basically looks for files of a handful specific file types (avi,m4v,mkv,mp4,mpeg,mpegts,mpg) and passes them back into mkvmerger which then checks for files with the same base name but different specific extensions (srt,idx,sub,ogg,mp3,aac) and then adds those to the argument list. Then it's all passed to mkvmerge to actually do the work. I don't use mkvmerge, so I don't know if you'll need to pass both the idx & sub, so try it as is and if you have problems try it with only one or the other (remove the line that misbehaves).

@ECHO OFF
::'===========================================================
:: mkvmerger.bat
:: mkvmerge recipe. 
::
:: Written by Shawn K. Hall
:: 
::'===========================================================
::setlocal enableDelayedExpansion
::'===========================================================
where /q mkvmerge.exe
IF NOT "%errorlevel%"=="0" GOTO nomkvmerge
::'===========================================================


::'===========================================================
:input
::'===========================================================
:: defaults
IF "%mkvTargetDir%"=="" SET mkvTargetDir=Done\
IF "%~1"=="" GOTO all
GOTO next
::'===========================================================


::'===========================================================
:next
IF /I "%~1"=="*"                    SHIFT&&GOTO all
IF /I "%~1"=="all"                  SHIFT&&GOTO all
IF /I "%~1"==""                     GOTO done
SET inparam=%~1
IF "%~1"==""                        GOTO none
SET "inparam2=%inparam:^*=%"
IF NOT "%inparam2%"=="%inparam%"  SHIFT&&GOTO many
SET inparam2=
GOTO process
::'===========================================================


::'===========================================================
:all
FOR %%x IN ("avi" "m4v" "mkv" "mp4" "mpeg" "mpegts" "mpg") DO (
  IF EXIST *.%%x FORFILES /M *.%%x /c "cmd /c CALL mkvmerger.bat ^"@file^""
)
GOTO next
::'===========================================================


::'===========================================================
:many
IF EXIST "%inparam%" FORFILES /M %inparam% /c "cmd /c CALL mkvmerger.bat ^"@file^""
GOTO next
::'===========================================================


::'===========================================================
:destexists
ECHO. The destination file already exists:
ECHO.   "%mkvTarget%"
ECHO. Are you sure you haven't already processed this file^?
ECHO.
GOTO done
::'===========================================================


::'===========================================================
:none
ECHO. Error: You must pass the source video file or "^*" as an argument.
ECHO.
GOTO done
::'===========================================================


::'===========================================================
:nomkvmerge
ECHO. Error: mkvmerge is either not installed or is not in the path.
ECHO.
GOTO done
::'===========================================================


::'===========================================================
:process
SET "mkvSources=%~1"
SET mkvTarget=
SET "mkvTargetName=%~n1"
SET mkvTargetExt=.mkv
SET "mkvTarget=%mkvTargetDir%\%mkvTargetName%%mkvTargetExt%"
IF EXIST "%mkvTarget%" GOTO destexists
IF NOT EXIST "%mkvTargetDir%" MKDIR "%mkvTargetDir%"
ECHO.
ECHO.Starting with "%mkvTarget%"
:processing
IF EXIST "%mkvTargetName%.srt" SET "mkvSources=%mkvSources% %mkvTargetName%.srt"
IF EXIST "%mkvTargetName%.idx" SET "mkvSources=%mkvSources% %mkvTargetName%.idx"
IF EXIST "%mkvTargetName%.ogg" SET "mkvSources=%mkvSources% %mkvTargetName%.ogg"
IF EXIST "%mkvTargetName%.mp3" SET "mkvSources=%mkvSources% %mkvTargetName%.mp3"
IF EXIST "%mkvTargetName%.aac" SET "mkvSources=%mkvSources% %mkvTargetName%.aac"
mkvmerge.exe -o "%mkvTarget%" %mkvSources%
:processingDone
ECHO.Done with "%mkvTarget%"
ECHO.
GOTO done
::'===========================================================


::'===========================================================
:done
  • 1
    Thank you for the help. I experienced errors when I read files like "I am Happy.mp4" and "I am Happy.srt" and fixed it by adding quotation marks to "%~1" and each of the "mkvTargetName%." variables. I also found out that mkvmerge needs to load only the idx file in sub/idx sets. Again, I appreciate the support. – Anton Nov 28 '18 at 12:39
  • awesome, glad it helped. – shawn Dec 5 '18 at 18:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.