66

The problem is that videoplayers in Ubuntu have a problem with integrated central european subtitles.The solution is to extract them. Does anyone knows if there is a command in the terminal or a program to extract the subtitle from a mkv file?

3 Answers 3

91

Install mkvtoolnix with sudo apt-get install mkvtoolnix.

Run from terminal: mkvextract tracks <your_mkv_video> <track_numer>:<subtitle_file.srt>

Use mkvinfo to get information about tracks.

Using this utility you can extract any track, even audio or video.

6
  • 20
    do not use mkvinfo as it says things like "Track number: 2 (track ID for mkvmerge & mkvextract: 1)" which are confusing. use mkvmerge -i <filename>
    – gcb
    Apr 22, 2016 at 2:09
  • 1
    Also note that, as specified in the docs, mkvextract determines file output format by track type, not the given extension (so check the type as reported by mkvmerge -i <filename>). Jan 24, 2017 at 17:05
  • 1
    are data (bytes) of subtitles placed within all file container? because the bigger video file the slower it works... (500mb 1 gb 4gb .mkv file) I thought it would work much faster and I thought subtitles' bytes are placed at specific part of video container file but it seems ffmpeg or mkvextract reads all file and extract subtitles only after reading all file (it's very slow)
    – user25
    Jun 2, 2018 at 16:56
  • 7
    @gcb and how is it confusing if it says in English track ID for mkvmerge & mkvextract ? it's easy, just use that track ID for mkvextract or mkvmerge. Array's length and index of elements in programming is also confusing for you?
    – user25
    Jun 2, 2018 at 17:33
  • 1
    Why do you export all subtitles as "SRT". We do not know if they are graphical subtitles and we do not know the format (SUP, SUB, etc.).
    – mgutt
    Nov 22, 2019 at 22:36
18

Answer of Cornelius finally worked for me, but some things were not obvious.

Install mkvtoolnix

sudo apt-get install mkvtoolnix

Detect track numbers

mkvmerge -i some_movie.mkv

Sample output:

File 'some_movie.mkv': container: Matroska
Track ID 0: video (MPEG-4p10/AVC/h.264)
Track ID 1: audio (AC-3/E-AC-3)
Track ID 2: subtitles (SubRip/SRT)
Chapters: 12 entries
Global tags: 2 entries

Extract tracks

Syntax:

mkvextract tracks <your_mkv_video> <track_number>:<subtitle_file.srt>

Note, that you can't have any spaces between <track_number>: and <subtitle_file.srt>.

Example:

mkvextract tracks "some_movie.mkv" 2:some_movie_subs.srt
1
  • If any Mac users are here looking for how to install mkvtoolnix, it appears to be available in brew.
    – 2540625
    Oct 22, 2021 at 3:50
14

you can use mkvtoolnix .

sudo apt-get install mkvtoolnix

Another tip now because mkv files may contain many subtitles , so the tip is this script that you can search for the language you want , so for example if you want English it will download just English .

Script :

#!/bin/bash
# Extract subtitles from each MKV file in the given directory

# If no directory is given, work in local dir
if [ "$1" = "" ]; then
  DIR="."
else
  DIR="$1"
fi

# Get all the MKV files in this dir and its subdirs
find "$DIR" -type f -name '*.mkv' | while read filename
do
  # Find out which tracks contain the subtitles
  mkvmerge -i "$filename" | grep 'subtitles' | while read subline
  do
    # Grep the number of the subtitle track
    tracknumber=`echo $subline | egrep -o "[0-9]{1,2}" | head -1`

    # Get base name for subtitle
    subtitlename=${filename%.*}

    # Extract the track to a .tmp file
    `mkvextract tracks "$filename" $tracknumber:"$subtitlename.srt.tmp" > /dev/null 2>&1`
    `chmod g+rw "$subtitlename.srt.tmp"`


    # Do a super-primitive language guess: ENGLISH
    langtest=`egrep -ic ' you | to | the ' "$subtitlename".srt.tmp`
    trimregex=""



    # Check if subtitle passes our language filter (10 or more matches)
    if [ $langtest -ge 10 ]; then
      # Regex to remove credits at the end of subtitles (read my reason why!)
      `sed 's/\r//g' < "$subtitlename.srt.tmp" \
        | sed 's/%/%%/g' \
        | awk '{if (a){printf("\t")};printf $0; a=1; } /^$/{print ""; a=0;}' \
        | grep -iv "$trimregex" \
        | sed 's/\t/\r\n/g' > "$subtitlename.srt"`
      `rm "$subtitlename.srt.tmp"`
      `chmod g+rw "$subtitlename.srt"`
    else
      # Not our desired language: add a number to the filename and keep anyway, just in case
      `mv "$subtitlename.srt.tmp" "$subtitlename.$tracknumber.srt" > /dev/null 2>&1`
    fi
  done
done

Save this script nameyouwant.sh and make it executable

Now in terminal change directory to script folder and write ./nameyouwant.sh /pathtosave

5
  • Strange thing, it didn't worked for one video but by executing the commands given in the accepted answer it worked.
    – Hunsu
    Nov 1, 2014 at 18:50
  • Thanks for the nifty script. Could you add an explanation why you remove the credits at the end of the subtitles? That part of the script doesn't work for me and results in an empty srt file.
    – m000
    Jan 17, 2016 at 21:31
  • 1
    This answer seems to be taken from computernerdfromhell.com. The reason given for removing the credits is: "Dutch subtitlers have the habit of putting in their credits or shout-outs in the last few lines of the subtitles. Nothing wrong with that, except when it happens right after the last line spoken in the film. The film might go on for another 5 minutes, I don’t want the aproaching end to be given away by DaNoodleBrain giving shout-outs to BoogerGuzzler, so I remove them with another simple regex"
    – Dror S.
    Jan 25, 2016 at 15:16
  • very helpful i modified the script slightly to extract also the language code: gist.github.com/cinatic/…
    – cinatic
    Apr 30, 2022 at 21:26
  • Hi, just popping in to thank you for your excellent answer, and also to mention that I have highly tweaked the script and created a Gist for it: gist.github.com/FurloSK/7f52303a10ab7478e3cddfe4bcc50881
    – FurloSK
    Aug 3 at 13:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .