Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extract subtitles from .mkv files on Mac OS X

Extract Subtitles From .mkv

These instructions shall work on Mac OS X and Linux.

Install mkvtoolnix (Mac OS X)

Installation via Homebrew:

brew install mkvtoolnix

List content of the .mkv file

mkvmerge -i myFile.mkv

Example of the file content

File 'myFile.mkv': container: Matroska
Track ID 1: video (V_MPEG4/ISO/AVC)
Track ID 2: audio (A_DTS)
Track ID 3: subtitles (S_TEXT/UTF8)
Track ID 4: subtitles (S_TEXT/UTF8)
Chapters: 22 entries

Track ID 3 and 4 are subtitles.

Extract subtitles tracks into separate files

mkvextract tracks myFile.mkv 3:myFile1.srt 4:myFile2.srt

Enjoy!


Extract Multiple Files

In case you need this in batch for all files in a directory (works only if all files have the same subtitle Track IDs).

Make sure you use correct file extension (*.mkv) and track-ids (3)

Example:

for file in *.mkv; do
  sub=$(echo $file | sed 's/\.mkv$/.srt/'); 
  mkvextract tracks "${file}" 3:"${sub}"; 
done
@KarlZeo

This comment has been minimized.

Copy link

@KarlZeo KarlZeo commented Feb 17, 2018

Thinks.Help me a lot.

@soshial

This comment has been minimized.

Copy link

@soshial soshial commented Apr 7, 2018

Written really well, even for newbies.

@zhanshan

This comment has been minimized.

Copy link

@zhanshan zhanshan commented May 10, 2018

thank you, this helped a lot.

@chloebe

This comment has been minimized.

Copy link

@chloebe chloebe commented Jun 20, 2018

Amazing, thank you! I have almost no idea what I'm doing, but I managed to figure it out (like I barely know how to use the commands on the terminal app on my Mac). :)

@Joshfindit

This comment has been minimized.

Copy link

@Joshfindit Joshfindit commented Mar 2, 2019

Alternate:

  1. Install ffmpeg (for example, through brew install ffmpeg)
  2. ffmpeg -i video.mkv
  3. Look for Stream #<stream number>(eng): Subtitle: subrip where <stream number> is the stream number of the subtitle track. Eg: 0:2
  4. ffmpeg -i video.mkv -map <stream number> subs.srt (example: ffmpeg -i video.mkv -map 0:2 subs.srt)
@OBPremier

This comment has been minimized.

Copy link

@OBPremier OBPremier commented Aug 11, 2019

I'm trying this, but I keep getting the error:

-bash: syntax error near unexpected token `('

I guess it's because the file name contains parentheses ()? How can I solve this? Any help appreciated.

@pavelbinar

This comment has been minimized.

Copy link
Owner Author

@pavelbinar pavelbinar commented Aug 16, 2019

Hi guys, I forgot that even exists. Just better formatted @bmaeser notes :)
Anyway, I am quite happy for your appreciation.
Feel free to suggest any improvements.

@pavelbinar

This comment has been minimized.

Copy link
Owner Author

@pavelbinar pavelbinar commented Aug 16, 2019

I added useful notes "Extract Multiple Files" from @farzadshafiee

@LordNodens

This comment has been minimized.

Copy link

@LordNodens LordNodens commented Apr 8, 2020

Thanks a lot! That was really helpful!

@wyndelljackson

This comment has been minimized.

Copy link

@wyndelljackson wyndelljackson commented Apr 13, 2020

Hi I keep getting the message that Error: The file 'Episode_1.mkv' could not be opened for reading: open file error.

@wyndelljackson

This comment has been minimized.

Copy link

@wyndelljackson wyndelljackson commented Apr 13, 2020

@larryy

This comment has been minimized.

Copy link

@larryy larryy commented Apr 28, 2020

I did exactly as suggested. It extracted a file. The file ended in .srt because that's the filename I specified, but it's a 25MB binary file, not a plain text .srt file. I suspect it's a .sub file format. Here are the first couple of lines:

PG�9ÅÆ��������Ä�8���Ä��������˛�mPG�9ÅÆ������
���˛�m�á�îPG�9ÅÆ������B����ÄÄÄ��ÄÄ@��ÄÄ`��ÄÄø��ÄĘ��ÄÄ���ÄÄü��ÄÄ �ÄÄ0

Apparently mkvextract cannot convert subtitle format/codec, but just gives you whatever is in the Matroska file.

Going to try the ffmpeg suggestion. Usually ffmpeg is good about honoring the file extension you provide, if I remember right.

And just in case there are any doubts, here are the actual lines from the command-line session, except I've changed the filenames:

$ mkvmerge -i video.mkv
File 'video.mkv': container: Matroska
Track ID 0: video (MPEG-H/HEVC/h.265)
Track ID 1: audio (AC-3/E-AC-3)
Track ID 2: subtitles (HDMV PGS)
Chapters: 14 entries

$ mkvextract tracks video.mkv 2:subtitles.srt
Extracting track 2 with the CodecID 'S_HDMV/PGS' to the file 'subtitles.srt'. Container format: SUP
Progress: 100%

The lines of binary gibberish above are from subtitles.srt.


UPDATE: Nope, ffmpeg can't do it either. It notices the .srt extension and provides this helpful error message:
Subtitle encoding currently only possible from text to text or bitmap to bitmap

@BadRobot-cooked

This comment has been minimized.

Copy link

@BadRobot-cooked BadRobot-cooked commented May 6, 2020

Hi I keep getting the message that Error: The file 'Episode_1.mkv' could not be opened for reading: open file error.

Me too, file is not open. or in use

@pavelbinar

This comment has been minimized.

Copy link
Owner Author

@pavelbinar pavelbinar commented May 7, 2020

Hi Guys,
This is not a support channel.
This is just drop-in "snippet".

If you need help, please move into more appropriate place where you can actually get some help.
Try https://stackoverflow.com/

@OBPremier

This comment has been minimized.

Copy link

@OBPremier OBPremier commented May 7, 2020

@antonioreyna

This comment has been minimized.

Copy link

@antonioreyna antonioreyna commented Jun 22, 2020

I did exactly as suggested. It extracted a file. The file ended in .srt because that's the filename I specified, but it's a 25MB binary file, not a plain text .srt file. I suspect it's a .sub file format. Here are the first couple of lines:

PG�9ÅÆ��������Ä�8���Ä��������˛�mPG�9ÅÆ������
���˛�m�á�îPG�9ÅÆ������B����ÄÄÄ��ÄÄ@��ÄÄ`��ÄÄø��ÄĘ��ÄÄ���ÄÄü��ÄÄ �ÄÄ0

Apparently mkvextract cannot convert subtitle format/codec, but just gives you whatever is in the Matroska file.

Going to try the ffmpeg suggestion. Usually ffmpeg is good about honoring the file extension you provide, if I remember right.

And just in case there are any doubts, here are the actual lines from the command-line session, except I've changed the filenames:

$ mkvmerge -i video.mkv
File 'video.mkv': container: Matroska
Track ID 0: video (MPEG-H/HEVC/h.265)
Track ID 1: audio (AC-3/E-AC-3)
Track ID 2: subtitles (HDMV PGS)
Chapters: 14 entries

$ mkvextract tracks video.mkv 2:subtitles.srt
Extracting track 2 with the CodecID 'S_HDMV/PGS' to the file 'subtitles.srt'. Container format: SUP
Progress: 100%

The lines of binary gibberish above are from subtitles.srt.

UPDATE: Nope, ffmpeg can't do it either. It notices the .srt extension and provides this helpful error message:
Subtitle encoding currently only possible from text to text or bitmap to bitmap

you solved this?

@ghost

This comment has been minimized.

Copy link

@ghost ghost commented Jun 26, 2020

I use zsh on my Catalina and I'm getting:

zsh: command not found: mkvmerge

My solution: I had the GUI MKVToolNix installed (v47) (via DMG install), so I did like this:

/Applications/MKVToolNix-47.0.0.app/Contents/MacOS/mkvmerge -i myFile.mkv

and

/Applications/MKVToolNix-47.0.0.app/Contents/MacOS/mkvextract tracks myFile.mkv 3:myFile1.srt 4:myFile2.srt

Worked.

@pavelbinar

This comment has been minimized.

Copy link
Owner Author

@pavelbinar pavelbinar commented Jul 18, 2020

https://stackoverflow.com/ is better place for this type of support requests / discussion.

@breezybrea

This comment has been minimized.

Copy link

@breezybrea breezybrea commented Jul 19, 2020

I have the same issue as @larryy and @antonioreyna. Any updates or solves?

@pedrobotton

This comment has been minimized.

Copy link

@pedrobotton pedrobotton commented Aug 14, 2020

I have the same issue as @larryy and @antonioreyna. Any updates or solves?

I was dealing with the same problem and what worked for me was just simplify the name of the mkv file, removing the brackets that it was and everything worked well

@sunsetrunner

This comment has been minimized.

Copy link

@sunsetrunner sunsetrunner commented Dec 14, 2020

Works on M1 Mac mini. You just need to fire up Terminal in Rosetta 2 mode before remote installing brew. Don't forget to set a folder location for extracted SRT files. Otherwise it'll just save them under main User directory. Thanks for sharing.

@larryy

This comment has been minimized.

Copy link

@larryy larryy commented Dec 14, 2020

If the tool is installed and in your $PATH it will run. The name of the file is irrelevant to the .srt subtitle problem. Unfortunately, there are multiple issues being discussed, not all having to do with subtitles.

That said, trying to extract text subtitles, like .srt, from a .mkv file that has bitmap subtitles won't work, whether from the command line or using a GUI utility like mkvToolnix. mkvToolnix will extract bitmap subtitles to a .mks file, and I suspect that's what this tool is doing as well. Either this tool or ffmpeg would have to implement OCR to convert bitmap subtitles to text subtitles. Sadly, neither one does, but it's kind of understandable, since open source OCR tools are not very good without a language model of some kind. There's a Mac application called Subtitle Extractor in the App Store that does this, but it has no language model, so it will make silly mistakes like replacing "silly" with "sil/y", "I'm" with "I 'm", "with" as "With", "won't" as "won 't" and on and on. It gets enough right that you could probably fix it by hand, but it would be tedious because there are a lot of errors. Better than nothing, I guess.

Consider it a complex feature request I guess, to implement OCR with a language model to convert bitmap subtitles to text subtitles.

@victornpb

This comment has been minimized.

Copy link

@victornpb victornpb commented Dec 31, 2020

Extract subtitles from MKV on all subdirectories

extract_subtitles.py

from os import walk
import subprocess
import re
from os import path

tool_path = "/Applications/MKVToolNix-51.0.0.app/Contents/MacOS/"
dir = "./"

def find_files(dir, ext):
    file_list = []
    for (dirpath, dirnames, filenames) in walk(dir):
        for filename in filenames:
            if filename.endswith(ext) and not filename.startswith('._'):
                file_list.append(dirpath + '/' + filename)
    file_list.sort()
    return file_list

for file in find_files(dir, ".mkv"):
    basename = file.replace(".mkv", "")
    
    if path.exists(basename+".srt") or path.exists(basename+".ssa"):
        print("Already Exist, skipping...", basename)
        continue

    # Find subtitle track
    result = subprocess.run([tool_path + "mkvmerge", "-i", file], stdout=subprocess.PIPE, check=True)
    
    # SubRip .srt
    srt_track = re.search(r'Track ID (\d+): subtitles \(SubRip/SRT\)', str(result.stdout)) 
    if srt_track:
        srt_track = "{}:{}.{}".format(srt_track.group(1), basename, "srt")

    # SubStation Alpha .ssa
    ssa_track = re.search(r'Track ID (\d+): subtitles \(SubStationAlpha\)', str(result.stdout)) 
    if ssa_track:
        ssa_track = "{}:{}.{}".format(ssa_track.group(1), basename, "ssa")

    if not srt_track and not ssa_track:
        print('No SRT track found!', file, str(result.stdout))
        continue


    # Extract SRT
    subprocess.run(list(filter(None, [tool_path+"mkvextract", "tracks", file, srt_track, ssa_track])), check=True)

print("Finished!");

then run on terminal like:

python3 extract_subtitles.py
@victorboykocom

This comment has been minimized.

Copy link

@victorboykocom victorboykocom commented Jan 11, 2021

same issue exactly with an srt file of over 10MB with binary data.
SAD!

@victorboykocom

This comment has been minimized.

Copy link

@victorboykocom victorboykocom commented Jan 11, 2021

There's a Mac application called Subtitle Extractor in the App Store that does this

Thank you for this @larryy ! I needed an SRT to translate subtitles into another language and needed precise time codes, this app does it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment