Skip to content

Instantly share code, notes, and snippets.

@kampfgnu
Last active March 13, 2024 05:19
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kampfgnu/bb7be04b624ed5ddf65d6e7c54f9ce2e to your computer and use it in GitHub Desktop.
Save kampfgnu/bb7be04b624ed5ddf65d6e7c54f9ce2e to your computer and use it in GitHub Desktop.
batch extract subtitles from mkv files
#!/bin/bash -e
# a script that extracts the subtitle file of every mkv movie file and saves it with the same name
# copy to the folder where the mkv files live and run "./mkvextractTracks.sh" in terminal
# options: [trackID]
# example: ./mkvextractTracks.sh 1
#
# info:
# mkvextract is used to extract the subtitles, so mkvtoolnix app (which contains the mkvextract binary) is used:
# https://mkvtoolnix.download/downloads.html
# please adjust below path to point to mkvextract or this script won't work
extractorPath='/Applications/MKVToolNix-9.0.1.app/Contents/MacOS/mkvextract'
defaultTrackID=2
# Ensure we're running in location of script.
cd "`dirname $0`"
if [ $# -gt 0 ]
then
defaultTrackID=$1
fi
for f in *; do
if [[ $f == *.mkv ]];
then
echo $f
$extractorPath tracks "$f" $defaultTrackID:"${f//mkv/srt}"
fi
done
echo "Complete"
@MEGZ99
Copy link

MEGZ99 commented Jun 13, 2021

What if I want to extract specific tack
say I have mkv file have 3 subtitles ara eng fr
but they are not ordered same in all files
So I want to extract arabic only but it's track 3 in file and in another is 4
so what edit I should do

@kkm
Copy link

kkm commented Jun 24, 2021

$mkvmerge -i /hdd/media/Pixels/Pixels.mkv
File '/hdd/media/Pixels/Pixels.mkv': container: Matroska
Track ID 0: video (MPEG-4p10/AVC/H.264)
Track ID 1: audio (DTS)
Track ID 2: audio (DTS)
Track ID 3: subtitles (SubRip/SRT)
Track ID 4: subtitles (SubRip/SRT)
Track ID 5: subtitles (VobSub)
Track ID 6: subtitles (VobSub)
Track ID 7: subtitles (VobSub)
Track ID 8: subtitles (VobSub)
Chapters: 16 entries

your defaultTrackID is 2 and need to pass param.

@Uhter
Copy link

Uhter commented Dec 19, 2021

Thank you so much @kampfgnu. You did exactly what I need ;)

@Arcitec
Copy link

Arcitec commented Feb 20, 2022

@MEGZ99 @kkm @Uhter This gist is useless. It literally just assumes that track 2 exists, is the thing you want, and is a SRT format. It's no better than just saving a hardcoded command. Totally useless.

Use this instead, it's way better. It loops through all tracks and extracts every subtitle to its correct format, with language included in the filename:

https://github.com/Bananaman/BananaScripts/blob/main/mkvextract-allsubs

@acme64
Copy link

acme64 commented Feb 26, 2022

This gist is exactly what I needed. It was enough of a jump point to modify it for my own uses, without doing more than I needed like other solutions.

@anhthoai
Copy link

@MEGZ99 @kkm @Uhter This gist is useless. It literally just assumes that track 2 exists, is the thing you want, and is a SRT format. It's no better than just saving a hardcoded command. Totally useless.

Use this instead, it's way better. It loops through all tracks and extracts every subtitle to its correct format, with language included in the filename:

https://github.com/Bananaman/BananaScripts/blob/main/mkvextract-allsubs

How to use this?

@Arcitec
Copy link

Arcitec commented Mar 30, 2022

Use this instead, it's way better. It loops through all tracks and extracts every subtitle to its correct format, with language included in the filename:
https://github.com/Bananaman/BananaScripts/blob/main/mkvextract-allsubs

How to use this?

Install Python on your system, if you don't have it.

Install MKVToolNix and add it to your PATH environment so that the commands can be found (guide for that here).

Then save the script itself and run it with Python (or make the script file executable and run it directly). Some usage examples are in the code comments.

If there are any other questions, please make a ticket at the project page so that others can also see your question. :)

@anhthoai
Copy link

I mean I save it as mkvextract-allsubs.py. Then I run python mkvextract-allsubs.py? It is not working. Could you please share full command?

@Arcitec
Copy link

Arcitec commented Jan 17, 2023

@anhthoai The reason why I said to make tickets at the project page is because I cannot see your replies here.

Anyway, the script was written with Linux and Mac in mind, but today I added Windows support. You can find the latest script at the project page:

https://github.com/Bananaman/BananaScripts/blob/main/mkvextract-allsubs

I'm guessing you were using Windows, which is why it didn't work before.

Just head to that project page, read the source code. The comments at the top of the file explain what you need on every platform.

It's working on Linux, Windows and Mac.

If you or anybody else have any other questions, you must post them on the linked BananaScripts project page.

Important: I will never check this gist page/comments here again. I will not see any comments below this one. Use the project page if you have questions about the project! Take care. :)

@kkm
Copy link

kkm commented Jan 19, 2023

@Bananaman Oh thanks. your script is very usefull.

@anhthoai install python 3.5 and mkvtoolnix then windows command: python mkvextract-allsubs file.mkv


# Requires:
#   Python >= 3.5
#   MKVToolNix:
#   - Linux: Install "mkvtoolnix" via your native package manager.
#   - Mac: Install Homebrew use it to install the following package:
#     https://formulae.brew.sh/formula/mkvtoolnix
#   - Windows: Install Chocolatey and use it to install the following package:
#     https://community.chocolatey.org/packages/mkvtoolnix
#     (IMPORTANT: You MUST reboot Windows for the changes to take effect!)
#
# Usage:
#   mkvextract-allsubs [one or more MKV files to extract from]

@kkm
Copy link

kkm commented Jan 19, 2023

@Bananaman is it possible to directly shell script on Linux without Python, please?

@fevangelou
Copy link

fevangelou commented Mar 6, 2023

Came here for a potential one-liner but was sadly disappointed that this was just a way to extract subtitles from a single file.

Bananaman's script was borked for some reason, so no love there too.

In the end, the solution using pure Bash was not that hard.

Here's a one-liner:

for F in *.mkv; do MKV=$(echo $F | sed -e "s/\.mkv$//"); SUBS=$(mkvmerge -i "$MKV.mkv" | grep "SubRip/SRT" | cut -d ' ' -f3 | tr -d ':'); for SUB in $SUBS; do mkvextract tracks "$F" $SUB:"${MKV}_$SUB.srt"; done; done

Or if you prefer a more elegant solution in the form of a script you just execute in a folder:
https://gist.github.com/fevangelou/48da813ac1d5d0d207ff0acab1c09df2

Enjoy :)

@Uhter
Copy link

Uhter commented Mar 7, 2023

Very usefull. Thank you @fevangelou ;)

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