Can MKVToolNix Extract movie subtitle to .srt file?

When I have a movie file (H.264 in .mkv or .mp4 format) that contains subtitles, I want to extract only the subtitle from the movie file. MKVToolNix can extract the subtitle, but it does it into an .mks file, which is not recognized as a subtitle file by the hardware and software players I use. It seems to only recognized by MKVToolNix itself for remuxing.

Is there a way to get MKVToolNix to extract the subtitles into an .srt file, which can be recognized by hardware and software players?

The command-line program mkvmerge always creates Matroska files. As the GUI’s “Multiplexer” tool is using mkvmerge under the hood, it will always create Matroska files as well. Even if all you select is a single subtitle track, the resulting file will still be a Matroska file.

If you want to get content out of Matroska, you can use the command-line program mkvextract, which is also part of the MKVToolNix package. The GUI doesn’t have a frontend for it yet, though. There are several third-party GUIs for it available that you can use.

Now in order to answer your actual question: yes, there is, via mkvextract which can extract text subtitles from Matroska files into corresponding text formats.

If you’re using Windows, here’s a batch file I use that uses mkvmerge and mkvextract to look at all mkv files in the current folder (I use a working folder); it’s easiest if the mkvmerge and mkvextract executables are also in that same folder.

ECHO Extracting all .mkv subtitle tracks in current folder.
ECHO.
ECHO.
FOR %%A IN (*.mkv) DO (
FOR /F %%I IN ('mkvmerge --identify "%%A" ^| FIND /C "Track ID"') DO (
IF %%I GTR 0 (
ECHO Analyzing "%%~nxA"
FOR /L %%T IN (0,1,%%I) DO (
mkvmerge.exe --identify "%%~dpnxA" | FIND /C "Track ID %%T: subtitles">NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks "%%~dpnxA" %%T:"%%~dpnA-ID%%T".srt
)
)
ECHO.
ECHO.
))
ECHO.
ECHO.
ECHO Finished extracting srt subtitles.....
PAUSE```

Thanks! That did the job.

Glad it worked for you.

I put 2 .mkv files in the MKVToolNix folder. They are namned MH and ULB.

What am I doing wrong? ::

batchFile

This is the output I get.

Microsoft Windows [Version 10.0.19045.3693]
(c) Microsoft Corporation. Med ensamrätt.

C:\Program Files\MKVToolNix>extractmkv

C:\Program Files\MKVToolNix>ECHO Extracting all .mkv subtitle tracks in current folder.
Extracting all .mkv subtitle tracks in current folder.

C:\Program Files\MKVToolNix>ECHO.

C:\Program Files\MKVToolNix>ECHO.

C:\Program Files\MKVToolNix>FOR %A IN (*.mkv) DO (FOR /F %I IN (‘mkvmerge --identify “%A” | FIND /C “Track ID”’) DO (
IF %I GTR 0 (
ECHO Analyzing “%~nxA”
FOR /L %T IN (0 1 %I) DO (
mkvmerge.exe --identify “%~dpnxA” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “%~dpnxA” %T:“%~dpnA-ID%T”.srt
)
)
ECHO.
ECHO.
) )

C:\Program Files\MKVToolNix>(FOR /F %I IN (‘mkvmerge --identify “MH.mkv” | FIND /C “Track ID”’) DO (
IF %I GTR 0 (
ECHO Analyzing “MH.mkv”
FOR /L %T IN (0 1 %I) DO (
mkvmerge.exe --identify “C:\Program Files\MKVToolNix\MH.mkv” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “C:\Program Files\MKVToolNix\MH.mkv” %T:“C:\Program Files\MKVToolNix\MH-ID%T”.srt
)
)
ECHO.
ECHO.
) )

C:\Program Files\MKVToolNix>(
IF 0 GTR 0 (
ECHO Analyzing “MH.mkv”
FOR /L %T IN (0 1 0) DO (
mkvmerge.exe --identify “C:\Program Files\MKVToolNix\MH.mkv” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “C:\Program Files\MKVToolNix\MH.mkv” %T:“C:\Program Files\MKVToolNix\MH-ID%T”.srt
)
)
ECHO.
ECHO.
)

C:\Program Files\MKVToolNix>(FOR /F %I IN (‘mkvmerge --identify “ULB.mkv” | FIND /C “Track ID”’) DO (
IF %I GTR 0 (
ECHO Analyzing “ULB.mkv”
FOR /L %T IN (0 1 %I) DO (
mkvmerge.exe --identify “C:\Program Files\MKVToolNix\ULB.mkv” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “C:\Program Files\MKVToolNix\ULB.mkv” %T:“C:\Program Files\MKVToolNix\ULB-ID%T”.srt
)
)
ECHO.
ECHO.
) )

C:\Program Files\MKVToolNix>(
IF 0 GTR 0 (
ECHO Analyzing “ULB.mkv”
FOR /L %T IN (0 1 0) DO (
mkvmerge.exe --identify “C:\Program Files\MKVToolNix\ULB.mkv” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “C:\Program Files\MKVToolNix\ULB.mkv” %T:“C:\Program Files\MKVToolNix\ULB-ID%T”.srt
)
)
ECHO.
ECHO.
)

C:\Program Files\MKVToolNix>ECHO.

C:\Program Files\MKVToolNix>ECHO.

C:\Program Files\MKVToolNix>ECHO Finished extracting srt subtitles…
Finished extracting srt subtitles…

C:\Program Files\MKVToolNix>PAUSE 'PAUSE’ is not recognized as an internal or external command,
operable program or batch file.
C:\Program Files\MKVToolNix>

It’s not clear what issue you’re trying to report. If it’s simply the error message about the ‘PAUSE’ command at the end of output, I’m uncertain why that’s happening, as ‘PAUSE’ is definitely a Windows/DOS command and has been for decades, and I cannot reproduce that same error.

If the issue is that you’re not getting any subtitles extracted, then that could be due to one of the the following:

  1. The mkv file(s) do not contain any srt subtitles.
  2. As you’re using C:\Program Files\ as your ‘working’ folder, Windows may not let you create files in that folder. It’s usually better to stay away from WIndows System-type folders and use either a working folder in My Documents or else a working folder on a secondary drive (Drive D, etc.)

I’ve attached output from a test file for illustration purposes, with a DIR command added at the end of the batch file to show that the subtitle was extracted and an srt file was created (and no error message on ‘PAUSE’!)

Please try this in a different, non-Windows System folder and see if that works.


D:\Sub_Rip>REM  @ECHO OFF

REM TEST FILE.mkv is a 3GB file in mkv container with one (1) subtitle track
REM with MediaInfo reporting the subtitle as:  Codec ID/Info: UTF-8 Plain Text

D:\Sub_Rip>ECHO Extracting all .mkv subtitle tracks in current folder.
Extracting all .mkv subtitle tracks in current folder.

D:\Sub_Rip>ECHO.

D:\Sub_Rip>ECHO.

D:\Sub_Rip>FOR %A IN (*.mkv) DO (FOR /F %I IN ('mkvmerge --identify "%A" | FIND /C "Track ID"') DO (
IF %I GTR 0 (
ECHO Analyzing "%~nxA"
 FOR /L %T IN (0 1 %I) DO (
mkvmerge.exe --identify "%~dpnxA"   | FIND /C "Track ID %T: subtitles" 1>NUL
 IF NOT ERRORLEVEL 1 mkvextract.exe tracks "%~dpnxA" %T:"%~dpnA-ID%T".srt
)
)
 ECHO.
 ECHO.
) )

D:\Sub_Rip>(FOR /F %I IN ('mkvmerge --identify "TEST FILE.mkv" | FIND /C "Track ID"') DO (
IF %I GTR 0 (
ECHO Analyzing "TEST FILE.mkv"
 FOR /L %T IN (0 1 %I) DO (
mkvmerge.exe --identify "D:\Sub_Rip\TEST FILE.mkv"   | FIND /C "Track ID %T: subtitles" 1>NUL
 IF NOT ERRORLEVEL 1 mkvextract.exe tracks "D:\Sub_Rip\TEST FILE.mkv" %T:"D:\Sub_Rip\TEST FILE-ID%T".srt
)
)
 ECHO.
 ECHO.
) )

D:\Sub_Rip>(
IF 3 GTR 0 (
ECHO Analyzing "TEST FILE.mkv"
 FOR /L %T IN (0 1 3) DO (
mkvmerge.exe --identify "D:\Sub_Rip\TEST FILE.mkv"   | FIND /C "Track ID %T: subtitles" 1>NUL
 IF NOT ERRORLEVEL 1 mkvextract.exe tracks "D:\Sub_Rip\TEST FILE.mkv" %T:"D:\Sub_Rip\TEST FILE-ID%T".srt
)
)
 ECHO.
 ECHO.
)
Analyzing "TEST FILE.mkv"

D:\Sub_Rip>(
mkvmerge.exe --identify "D:\Sub_Rip\TEST FILE.mkv"   | FIND /C "Track ID 0: subtitles" 1>NUL
 IF NOT ERRORLEVEL 1 mkvextract.exe tracks "D:\Sub_Rip\TEST FILE.mkv" 0:"D:\Sub_Rip\TEST FILE-ID0".srt
)

D:\Sub_Rip>(
mkvmerge.exe --identify "D:\Sub_Rip\TEST FILE.mkv"   | FIND /C "Track ID 1: subtitles" 1>NUL
 IF NOT ERRORLEVEL 1 mkvextract.exe tracks "D:\Sub_Rip\TEST FILE.mkv" 1:"D:\Sub_Rip\TEST FILE-ID1".srt
)

D:\Sub_Rip>(
mkvmerge.exe --identify "D:\Sub_Rip\TEST FILE.mkv"   | FIND /C "Track ID 2: subtitles" 1>NUL
 IF NOT ERRORLEVEL 1 mkvextract.exe tracks "D:\Sub_Rip\TEST FILE.mkv" 2:"D:\Sub_Rip\TEST FILE-ID2".srt
)
Extracting track 2 with the CodecID 'S_TEXT/UTF8' to the file 'D:\Sub_Rip\TEST FILE-ID2.srt'. Container format: SRT text subtitles
Progress: 100%

D:\Sub_Rip>(
mkvmerge.exe --identify "D:\Sub_Rip\TEST FILE.mkv"   | FIND /C "Track ID 3: subtitles" 1>NUL
 IF NOT ERRORLEVEL 1 mkvextract.exe tracks "D:\Sub_Rip\TEST FILE.mkv" 3:"D:\Sub_Rip\TEST FILE-ID3".srt
)


D:\Sub_Rip>ECHO.

D:\Sub_Rip>ECHO.

D:\Sub_Rip>ECHO Finished extracting srt subtitles.....
Finished extracting srt subtitles.....

REM Added the DIR to show that subtitles were created in the working folder
D:\Sub_Rip>DIR *.srt
 Volume in drive D is DATA-D
 Volume Serial Number is B6FE-DA65

 Directory of D:\Sub_Rip

11/19/2023  12:57 PM            65,539 TEST FILE-ID2.srt
               1 File(s)         65,539 bytes
               0 Dir(s)  444,837,851,136 bytes free

D:\Sub_Rip>PAUSE
Press any key to continue . . .

OK, I’ve made three mistakes (just for starters).

  1. I did run it in the MKVToolNix folder in a Windows System folder.
  2. I thought it could extract any subtitle, no matter what type.
  3. I thought it could extract any number of subtitles in the mkv file.

So I downloaded a portable version and copied a mkv file named SM there. Media Info reports it like this:

ID : 3
Format : UTF-8
Codec ID : S_TEXT/UTF8
Codec ID/Info : UTF-8 Plain Text
Duration : 48 min 55 s
Bit rate : 0 b/s
Frame rate : 0.001 FPS
Count of elements : 2
Stream size : 104 Bytes (0%)
Default : Yes
Forced : No

Then I ran the bat file with this result. (No .srt file came out of it.)

Microsoft Windows [Version 10.0.19045.3693]
(c) Microsoft Corporation. Med ensamrätt.

S:\mkvtoolnix>extractmkv.bat

S:\mkvtoolnix>ECHO Extracting all .mkv subtitle tracks in current folder.
Extracting all .mkv subtitle tracks in current folder.

S:\mkvtoolnix>ECHO.

S:\mkvtoolnix>ECHO.

S:\mkvtoolnix>FOR %A IN (*.mkv) DO (FOR /F %I IN (‘mkvmerge --identify “%A” | FIND /C “Track ID”’) DO (
IF %I GTR 0 (
ECHO Analyzing “%~nxA”
FOR /L %T IN (0 1 %I) DO (
mkvmerge.exe --identify “%~dpnxA” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “%~dpnxA” %T:“%~dpnA-ID%T”.srt
)
)
ECHO.
ECHO.
) )

S:\mkvtoolnix>(FOR /F %I IN (‘mkvmerge --identify “SM.mkv” | FIND /C “Track ID”’) DO (
IF %I GTR 0 (
ECHO Analyzing “SM.mkv”
FOR /L %T IN (0 1 %I) DO (
mkvmerge.exe --identify “S:\mkvtoolnix\SM.mkv” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “S:\mkvtoolnix\SM.mkv” %T:“S:\mkvtoolnix\SM-ID%T”.srt
)
)
ECHO.
ECHO.
) )

S:\mkvtoolnix>(
IF 0 GTR 0 (
ECHO Analyzing “SM.mkv”
FOR /L %T IN (0 1 0) DO (
mkvmerge.exe --identify “S:\mkvtoolnix\SM.mkv” | FIND /C “Track ID %T: subtitles” 1>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “S:\mkvtoolnix\SM.mkv” %T:“S:\mkvtoolnix\SM-ID%T”.srt
)
)
ECHO.
ECHO.
)

S:\mkvtoolnix>ECHO.

S:\mkvtoolnix>ECHO.

S:\mkvtoolnix>ECHO Finished extracting srt subtitles…
Finished extracting srt subtitles…

S:\mkvtoolnix>PAUSE 'PAUSE’ is not recognized as an internal or external command,
operable program or batch file.
S:\mkvtoolnix>

I still can’t reproduce this error, everything runs as expected. Still do not understand the error on the ‘PAUSE’ command, that makes no sense.
Instead of your captured output, can you post the actual batch file contents to ensure that you have those commands correct? With that information I’ll run against a test file with the exact batch file commands you’re using to see what the results are.

I don’t know, but could it be that my text editor TextPad does something with the characters that causes the PAUSE error.

ECHO Extracting all .mkv subtitle tracks in current folder.
ECHO.
ECHO.
FOR %%A IN (*.mkv) DO (
FOR /F %%I IN (‘mkvmerge --identify “%%A” ^| FIND /C “Track ID”’) DO (
IF %%I GTR 0 (
ECHO Analyzing “%%~nxA”
FOR /L %%T IN (0,1,%%I) DO (
mkvmerge.exe --identify “%%~dpnxA” | FIND /C “Track ID %%T: subtitles”>NUL
IF NOT ERRORLEVEL 1 mkvextract.exe tracks “%%~dpnxA” %%T:“%%~dpnA-ID%%T”.srt
)
)
ECHO.
ECHO.
))
ECHO.
ECHO.
ECHO Finished extracting srt subtitles…
PAUSE```

That could be it, not just with the ‘PAUSE’ error, but when I copied/pasted this into notepad, saved as a batch file and ran it, it closed immediately, so it’s not running. I think you’re right that your text editor is introducing characters that Windows/DOS can’t handle or recognize. If you try it in Notepad or a similar editor that uses just plain text it should work. Hope that’s the case and that it will finally work for you.

I’ve tried many different approaches now and nothing works, and I think I’ll stop here while at the same time thank you for your engagement.

As I said earlier, I thought it would work for all types of subtitles and regardless of how many, so there is need for me to have this. Don’t have too many of this particular user case.

Not certain why isn’t working; it did for the OP, and I’ve had this working for a few years now, no issues or failures. Sorry this didn’t go for you, but Good Luck with other attempts in the future.

is there a way to edit this to run recursively?