So I've been searching around to an answer to this and have been able to find very many similar cases, but unable to actually find an answer to what I'm trying to do.

I took a look at these two threads in particular:

Also Google'd around and read a bunch of man pages to no avail. (Doesn't mean the answers aren't there, I just couldn't find them!)

Anyway, with that preface out of the way, here's what I'm trying to do:

I have three folders (and a billion files) of this:

  • Show Name - S##E## - Title.mp4
  • Show Name - S##E## - Title.eng.srt

I'm trying to merge every .mp4 and .srt into just Show Name - S##E## - Title.mkv with the subtitles included in the file.

The problem with the first related thread that I linked is that it just turns the .mp4 into .mkv and doesn't merge the subtitles at all.


FOR %%A IN (*.mp4) DO "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%%~nA.mkv" "%%~A"

This creates the .mkv file, but doesn't include the subtitles. If I try to add "%%~dpnA.srt" or anything after "%%~A", I get a message saying: Error: The file 'C:\Users\xnaas\Desktop\test\Show Name - S##E## - Title.srt' could not be opened for reading: open file error. and similar. I geuss my biggest confusion here is I don't know what any of what I'm typing is doing. What is a ~ or nA doing?

The problem with the second link is that I don't know how to adapt it to be in batch form because I'm not sure how to do that with ffmpeg at all. I assume it's just another for loop, but I'm not all that familiar with it.

This is the only script I've used for ffmpeg (Linux now vs Windows above) before:

for f in *.mkv; do ffmpeg -i "$f" -c:v libx264 -preset medium -crf 18 -c:a copy "encoded/${f%.mkv}.mkv"; done

I'm sure it could probably be adapted, but I'm not sure how.

for f in *.mp4; do ffmpeg -i "$f" -c copy "test/${f%}.mkv"; done

That's the best I could come up with after a long while tinkering with it, but this obviously doesn't bring in the subtitle files and it names everything .mp4.mkv as well.

Sorry for the massive wall of crap up there. I look forward to any assistance/insight anyone can offer. Thank you!

  • I should add, I can use Bulk Rename Utility to remove .eng from every .srt file if needed. It doesn't need to be there, obviously.
    – xnaas
    Dec 16, 2016 at 21:59
  • Should also note: I don't care if the solution is done on Windows or in bash. I can use either. I just need...something. :)
    – xnaas
    Dec 16, 2016 at 22:06
  • To explain some of what's going on in the batch file, take a look at this: microsoft.com/resources/documentation/windows/xp/all/proddocs/…
    – heavyd
    Dec 16, 2016 at 22:07
  • Hmm...can't decide whether that created more questions than it answered or not, yet... :) Thank you for the info, though!
    – xnaas
    Dec 16, 2016 at 22:13
  • That definitely did it. Now I can just mess around with flags and get the rest of the details worked out. You should post your answer separately so I can mark it. :)
    – xnaas
    Dec 16, 2016 at 23:39

2 Answers 2


I'll try to explain how the batch parameters that are given here are being applied to the script you gave.

The basic parameter in the FOR loop is %%A. The %%A is modified in the following ways:

  • "%%~nA.mkv" is removing the quotes (~) and using just the filename (n).
  • "%%~A" is just removing any quotes (~)

I think your final command should end up as:

FOR %%A IN (*.mp4) DO "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%%~nA.mkv" "%%~A" "%%~nA.eng.srt"

Following worked for me, it kept the language en

Make sure the srt and mp.4 have the exact same name, besides the extension.

FOR %%A IN (*.mp4) DO "C:\Program Files\MKVToolNix\mkvmerge.exe" -o "%%~nA.mkv" "%%~A" "%%~nA.srt" --default-language en --language 1:en

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.