VideoHelp Forum

Our website is made possible by displaying online advertisements to our visitors. Consider supporting us by disable your adblocker or try DVDFab and copy, convert or make Blu-rays and DVDs! :)
+ Reply to Thread
Page 1 of 2
1 2 LastLast
Results 1 to 30 of 44
Thread
  1. I have lots of MKV files which contain multiple audio and subtitle tracks. I'd like to remove the non-English tracks from the files and re-mux them all to leave just the English ones.

    This can be done manually using mmg.exe from mkvtoolnix, but is there a way to remove tracks by examining their language code which could be written into a batch file or something?

    Thanks
    Quote Quote  
  2. I'm a MEGA Super Moderator Baldrick's Avatar
    Join Date
    Aug 2000
    Location
    Sweden
    Search Comp PM
    I haven't seen anything that can examining languague codes. But if they all have same tracks you can probably use the command line mkvmerge in a batch loop, see http://forum.doom9.org/showthread.php?t=162639 .
    Quote Quote  
  3. Mkvinfo reports on the language of all the tracks. I'm guessing it would be possible to write a program which would examine the output generated by mkvinfo and determine which tracks would be kept and which discarded. But that sounds like a lot of effort. I'll give your suggestion a try. Thanks!

    EDIT: most of the files did use the same IDs for non-English tracks (check using mmg.exe) so I modified a script on the page you linked to and came up with this:

    batch_remove.bat (place inside .mkv directory with mkvmerge.exe in C:\).
    Replace 4 and 7 with whatever audio/subtitle tracks you wish to preserve.
    If you want to preserve multiple tracks, do -a 1,2,3 or -s 1,2,3 etc.

    Code:
    FOR /F "delims=*" %%A IN ('dir /b *.MKV') DO "C:\mkvmerge.exe" -o "fixed_%%A" -a 4 -s 7 --compression -1:none "%%A"
    PAUSE
    Hopefully in the future we could see some syntax like --remove-language !eng to remove all tracks which don't have a "eng" language code.
    Last edited by soulhunter123; 4th Feb 2012 at 13:19.
    Quote Quote  
  4. An old thread but others might be interested.

    The following python script will batch remove non English audio and subtitles, set the default audio track to the first English track and ensure that there are no default subtitles (only minor modification to support other languages - probably should be a command line option). The script will process any .mkv files in the input directory and all sub directories.

    You just need to install python and mkvtoolnix.

    if you need further help then search for something like "how to run a python script".

    Code:
    #!/usr/bin/python
    
    import os
    import re
    import sys
    import StringIO
    import subprocess
    
    # change this for other languages (3 character code)
    LANG = "eng"
    
    # set this to the path for mkvmerge
    MKVMERGE = "C:/Program Files/MKVtoolnix/mkvmerge.exe"
    
    AUDIO_RE    = re.compile(r"Track ID (\d+): audio \([A-Z0-9_/]+\) [number:\d+ uid:\d+ codec_id:[A-Z0-9_/]+ codec_private_length:\d+ language:([a-z]{3})")
    SUBTITLE_RE = re.compile(r"Track ID (\d+): subtitles \([A-Z0-9_/]+\) [number:\d+ uid:\d+ codec_id:[A-Z0-9_/]+ codec_private_length:\d+ language:([a-z]{3})(?: track_name:\w*)? default_track:[01]{1} forced_track:([01]{1})")
    
    if len(sys.argv) < 2:
        print "Please supply an input directory"
        sys.exit()
    
    in_dir = sys.argv[1]
    
    for root, dirs, files in os.walk(in_dir):
        for f in files:
    
            # filter out non mkv files
            if not f.endswith(".mkv"):
                continue
    
            # path to file
            path = os.path.join(root, f)
    
            # build command line
            cmd = [MKVMERGE, "--identify-verbose", path]
    
            # get mkv info
            mkvmerge = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = mkvmerge.communicate()
            if mkvmerge.returncode != 0:
                print >> sys.stderr, "mkvmerge failed to identify", path
                continue
    
            # find audio and subtitle tracks
            audio = []
            subtitle = []
            for line in StringIO.StringIO(stdout):
                m = AUDIO_RE.match(line)
                if m:
                    audio.append(m.groups())
                else:
                    m = SUBTITLE_RE.match(line)
                    if m:
                        subtitle.append(m.groups())
    
            # filter out files that don't need processing
            if len(audio) < 2 and len(subtitle) < 2:
                print >> sys.stderr, "nothing to do for", path
                continue
    
            # filter out tracks that don't match the language	
            audio_lang = filter(lambda a: a[1]==LANG, audio)
            subtitle_lang = filter(lambda a: a[1]==LANG, subtitle)
    
            # filter out files that don't need processing
            if len(audio_lang) == 0 and len(subtitle_lang) == 0:
                print >> sys.stderr, "no tracks with that language in", path
                continue
    
            # build command line
            cmd = [MKVMERGE, "-o", path + ".temp"]
            if len(audio_lang):
                cmd += ["--audio-tracks", ",".join([str(a[0]) for a in audio_lang])]
                for i in range(len(audio_lang)):
                    cmd += ["--default-track", ":".join([audio_lang[i][0], "0" if i else "1"])]
            if len(subtitle_lang):
                cmd += ["--subtitle-tracks", ",".join([str(s[0]) for s in subtitle_lang])]
                for i in range(len(subtitle_lang)):
                    cmd += ["--default-track", ":".join([subtitle_lang[i][0], "0"])]
            cmd += [path]
    
            # process file
            print >> sys.stderr, "Processing", path, "...",
            mkvmerge = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = mkvmerge.communicate()
            if mkvmerge.returncode != 0:
                print >> sys.stderr, "Failed"
                continue
            
            print >> sys.stderr, "Succeeded"
    
            # overwrite file
            os.remove(path)
            os.rename(path + ".temp", path)
    Last edited by greenbender; 29th Nov 2012 at 06:31. Reason: Clarity
    Quote Quote  
  5. Thanks for the script, I have installed python and mkvtools and set the path to mkv merge.

    I am getting

    File "J:\Movies\mkv clean audio to english.py", line 19
    print "Please supply an input directory"
    ^
    SyntaxError: invalid syntax

    The .py script is located in the folder containing the mkv files. Can anyone help?
    Last edited by gffmac; 14th Jan 2013 at 11:09.
    Quote Quote  
  6. I'm a MEGA Super Moderator Baldrick's Avatar
    Join Date
    Aug 2000
    Location
    Sweden
    Search Comp PM
    Try just remove/comment that line, add a # before print "Please supply an input directory" so it looks like
    Code:
    #print "Please supply an input directory"
    If you receive more errors it's probably something wrong with your python installation/version.
    Quote Quote  
  7. New error:
    ImportError: No module named 'StringIO'

    I tried a previous version of python pre version 3 and now get :
    File "J:\Movies\mkv clean audio to english.py", line 22, in <module>
    in_dir = sys.argv[1]
    IndexError: list index out of range.

    I give up lol, Ill look for an alternative method.

    Thanks for your reply.
    Quote Quote  
  8. I'm a MEGA Super Moderator Baldrick's Avatar
    Join Date
    Aug 2000
    Location
    Sweden
    Search Comp PM
    Or wait and see if you get any help by greenbender because my python experience is very limited.
    Quote Quote  
  9. You'll need to run this from the command prompt and provide the directory you want to have scanned (including subdirectories) to the file.

    In your case...

    ScriptName.py "J:/Movies"
    Quote Quote  
  10. Originally Posted by talonius View Post
    You'll need to run this from the command prompt and provide the directory you want to have scanned (including subdirectories) to the file.

    In your case...

    ScriptName.py "J:/Movies"
    Ill give it a shot when I get in thanks mate, think I may have tried this already though.
    Quote Quote  
  11. For the record, I used Python 2.7, not 3.0. I ran into two problems. The first is that I had the path to MKVMerge set incorrectly. In the original script, it is:

    # set this to the path for mkvmerge
    MKVMERGE = "C:/Program Files/MKVtoolnix/mkvmerge.exe"

    Since I'm running Windows 7, 64 bit, and had installed to the D: drive, I changed this to:

    # set this to the path for mkvmerge
    MKVMERGE = "D:/Program Files (x86)/MKVtoolnix/mkvmerge.exe"

    The error that accompanied this mistake was really weird; something along the lines of "cannot open input path."

    Second, I had to provide it with the path I wanted to inspect. I used a DOS prompt and navigated to my media files, then executed using

    "RemoveNonEnglish.py ."

    Where the . stands for the current directory. That scanned the current directory and all subdirectories - and it's in process now.

    Thanks.
    Quote Quote  
  12. "J:/Movies/mkv clean audio to english.py" J:/Movies

    That did the trick then was getting failed but thats due to not enough space to remux a movie :P
    I was sure I had tried that... Maybe that was when i was on version 3.... 64bit of python..

    Now processing and no errors so far

    Thanks for the responses!
    Quote Quote  
  13. I'm a MEGA Super Moderator Baldrick's Avatar
    Join Date
    Aug 2000
    Location
    Sweden
    Search Comp PM
    No problems.
    Quote Quote  
  14. i was looking forward to using this as it is exactly what i was looking for but it wont work for me. it just says "nothing to do for /mnt/user/me/TV/test/test_file.mkv"

    the file does have english and german audio and subtitles.

    so i commented out this section of code:
    Code:
            # filter out files that don't need processing
            if len(audio) < 2 and len(subtitle) < 2:
                print >> sys.stderr, "nothing to do for", path
                continue
    then i got "no tracks with that language in /mnt/user/me/TV/test/test_file.mkv"

    so i commented out:

    Code:
            # filter out files that don't need processing
           if len(audio_lang) == 0 and len(subtitle_lang) == 0:
                print >> sys.stderr, "no tracks with that language in", path
                continue
    then it processed but when it was done nothing was removed. i looked at the RE and i dont think it matches up with the expected output. maybe i have a different version of mkvmerge or something. here is the output i'm getting:

    Code:
    Track ID 1: video (V_MPEG4/ISO/AVC) [language:und display_dimensions:1920x1080 default_track:1 forced_track:0 packetizer:mpeg4_p10_video]
    Track ID 2: audio (A_AC3) [language:ger default_track:1 forced_track:0]
    Track ID 3: audio (A_AC3) [language:eng default_track:0 forced_track:0]
    Track ID 4: subtitles (S_HDMV/PGS) [language:ger default_track:0 forced_track:0]
    Track ID 5: subtitles (S_HDMV/PGS) [language:eng default_track:0 forced_track:0]


    i know some python so maybe i can get it working but anyone let me know if they have any ideas.

    UPDATE: pretty sure im using an older version of the tool that has a different format for the verbose output. a version check might be a good idea.
    Last edited by bobbintb; 24th Mar 2013 at 13:44.
    Quote Quote  
  15. i got it to work but it doesnt work all of the time. i upgraded my version to 5.8 because it was the newest version i could find packaged for my distro and i havent had the time to build it myself (nor do i want to). one file i tried it on had french audio and subs. it only removed the french audio for some reason even though the subs are labeled as fre.
    Quote Quote  
  16. I left a Feature request for Media Centre Master to build this feature into his program as that would be PERFECT.

    I cannot believe there is no program you can run to automatically examine a MKV and strip languages or subs from a file with some command line prompts or even a GUI to feed a folder in and it examines all within.

    Its not that hard!!
    Quote Quote  
  17. Member
    Join Date
    Apr 2004
    Location
    Canada
    Search Comp PM
    Originally Posted by greenbender View Post
    An old thread but others might be interested.
    An old post but I just logged in to give my thanks as this script came in very handy.

    For people having issues in Windows, Python versions greater than 3 are probably why. Python version 2.7.4 worked fine for me and this script successfully stripped some unwanted subs and audio from plenty of folders.
    Quote Quote  
  18. How could I do this so this would loop in a batch file?

    Code:
    ""F:\Program Files (x86)\MKVToolNix\mkvmerge.exe" -o "F:\\downloads\\folder\\folder\\file (1).mkv"  "--default-track" "0:yes" "--forced-track" "0:no" "--display-dimensions" "0:720x384" "--language" "2:eng" "--track-name" "2:Funimation" "--default-track" "2:no" "--forced-track" "2:no" "-a" "2" "-d" "0" "-S" "-T" "--no-global-tags" "--no-chapters" "(" "F:\\downloads\\folder\\folder\\file.mkv" ")" "--track-order" "0:0,0:2"
    Quote Quote  
  19. Member
    Join Date
    May 2013
    Location
    Netherlands
    Search PM
    Nice script!

    I'm on linux, so with a little tweaking, i got this to work. I am hoping to use this in SABnzbd, but i really need help with this. I would like the script to do the following:

    - Rename the original MKV file, and name the new file as the original

    - If dutch subtitles are available in the MKV file, they must be extracted and named the same as the MKV file as "FileName.nl.srt"

    - In the MKV file, only keep:
    *Video track
    *English audio track. DTS if available, otherwise AC3, otherwise something else (2 eng audio tracks means 1 has to go)
    NOTHING else to keep. No other audio, no subtitles

    - The original MKV has to be deleted.

    Nice to haves:
    - Do this for all MKV files found in all subfolders
    - Options to set languages for video and subtitles to remove and also for the ones to keep and extract (you would need to rename the extracted subtitle based on the language chosen)

    I think the one who makes this script will be a hero. At least to me, but i guess for a lot more people. Would save a LOT of work.

    Thanks in advance!
    Last edited by rilorolo; 23rd May 2013 at 11:00.
    Quote Quote  
  20. Member
    Join Date
    Jun 2013
    Location
    Left Coast, United States
    Search Comp PM
    Originally Posted by rilorolo View Post
    Nice script!

    I'm on linux, so with a little tweaking, i got this to work. I am hoping to use this in SABnzbd, but i really need help with this. I would like the script to do the following:

    - Rename the original MKV file, and name the new file as the original

    - If dutch subtitles are available in the MKV file, they must be extracted and named the same as the MKV file as "FileName.nl.srt"

    - In the MKV file, only keep:
    *Video track
    *English audio track. DTS if available, otherwise AC3, otherwise something else (2 eng audio tracks means 1 has to go)
    NOTHING else to keep. No other audio, no subtitles

    - The original MKV has to be deleted.

    Nice to haves:
    - Do this for all MKV files found in all subfolders
    - Options to set languages for video and subtitles to remove and also for the ones to keep and extract (you would need to rename the extracted subtitle based on the language chosen)

    I think the one who makes this script will be a hero. At least to me, but i guess for a lot more people. Would save a LOT of work.

    Thanks in advance!

    This would be amazing! Please someone, anyone, that knows how to do this, please do this!
    Quote Quote  
  21. Member
    Join Date
    Nov 2013
    Location
    United States
    Search Comp PM
    Thanks for the script! This is exactly what I need and it is nice to know that this is possible. However, I can confirm that the different versions output different formats. It would appear that this script uses 6.x so it will not run on anything pre-6.x. You will need to upgrade to 6.x to get this to work.

    If you are using Ubuntu, here is the info on how to get the repos into apt.


    http://www.hecticgeek.com/2013/05/install-mkvtoolnix-6-2-0-ubuntu-13-04-12-10/
    Last edited by Geek23; 8th Nov 2013 at 15:18.
    Quote Quote  
  22. Member fryk's Avatar
    Join Date
    Oct 2012
    Location
    Europe
    Search PM
    I adopted it for the Windows cmd shell ('batch') and added subtitle support.
    Tested with Windows 8.

    Code:
     
    @ECHO OFF &SETLOCAL
    TITLE Recursive remove audio and subtitle tracks by language from MKV video files
    rem search for MKVs in all "StartFolder\Subfolders", not in "Startfolder" itself
    SET "StartFolder=."
    rem example to keep English and German audio tracks, please note the colon in front of the language code
    SET "AudioTracksToKeep=:eng:ger"
    rem example to keep Spanish and French subtitle tracks, please note the colon in front of the language code
    SET "SubsTracksToKeep=:spa:fre"
    rem the file name variable must be global for some reasons
    SET "MKVFile="
    
    FOR /f "DELIMS=" %%a IN ('DIR /b /s /a-d "%StartFolder%\*.mkv"') DO SET "MKVFile=%%~a"&CALL:scanmkv
    GOTO:EOF
    
    :scanmkv
    SETLOCAL
    ECHO(
    ECHO(Scanning "%MKVFile%" for unwanted tracks.
    (FOR /l %%b IN (1 1 45) DO <nul SET /p "=-")&ECHO(
    
    SET /a AudioTrackCount=0
    SET /a NumberKeepAudio=0
    SET /a NumberDiscardAudio=0
    
    rem get the number of audio tracks
    FOR /f %%a IN ('mkvmerge --ui-language en -i "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: audio"') DO SET /a AudioTrackCount+=1
    ECHO(Number of audio tracks: %AudioTrackCount%
    rem always keep at least one audio track
    IF %AudioTrackCount% LSS 2 GOTO:subscan
    
    rem get the audio tracks to keep
    SET "KeepAudioSearchString=%AudioTracksToKeep::= language:%"
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: audio"^|FINDSTR /ri "%KeepAudioSearchString%"') DO (
        SET /a NumberKeepAudio+=1
        CALL SET "AudioIdentKeepLine=%%AudioIdentKeepLine%%,%%a"
    )
    IF NOT DEFINED AudioIdentKeepLine SET "AudioIdentKeepLine= ^<none^>"
    ECHO(ID of %NumberKeepAudio% track(s) to keep: %AudioIdentKeepLine:~1%
    IF %NumberKeepAudio%==0 GOTO:subscan
    
    rem get the audio tracks to reject
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: audio"^|FINDSTR /riv "%KeepAudioSearchString%"') DO (
        SET /a NumberDiscardAudio+=1
        CALL SET "AudioIdentDiscardLine=%%AudioIdentDiscardLine%%,%%a"
    )
    IF NOT DEFINED AudioIdentDiscardLine SET "AudioIdentDiscardLine= ^<none^>"
    ECHO(ID of %NumberDiscardAudio% track(s) to reject: %AudioIdentDiscardLine:~1%
    IF %NumberDiscardAudio%==0 GOTO:subscan
    
    :subscan
    SET /a SubsTrackCount=0
    SET /a NumberKeepSubs=0
    SET /a NumberDiscardSubs=0
    
    rem get the number of subtitle tracks
    FOR /f %%a IN ('mkvmerge --ui-language en -i "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: subtitles"') DO SET /a SubsTrackCount+=1
    ECHO(Number of subtitle tracks: %SubsTrackCount%
    IF %SubsTrackCount% EQU 0 GOTO:muxing
    
    rem get the subtitle tracks to keep
    SET "KeepSubsSearchString=%SubsTracksToKeep::= language:%"
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: subtitles"^|FINDSTR /ri "%KeepSubsSearchString%"') DO (
        SET /a NumberKeepSubs+=1
        CALL SET "SubsIdentKeepLine=%%SubsIdentKeepLine%%,%%a"
    )
    IF NOT DEFINED SubsIdentKeepLine SET "SubsIdentKeepLine= ^<none^>"
    ECHO(ID of %NumberKeepSubs% track(s) to keep: %SubsIdentKeepLine:~1%
    IF %NumberKeepSubs%==0 GOTO:muxing
    
    rem get the subtitle tracks to reject
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: subtitles"^|FINDSTR /riv "%KeepSubsSearchString%"') DO (
        SET /a NumberDiscardSubs+=1
        CALL SET "SubsIdentDiscardLine=%%SubsIdentDiscardLine%%,%%a"
    )
    IF NOT DEFINED SubsIdentDiscardLine SET "SubsIdentDiscardLine= ^<none^>"
    ECHO(ID of %NumberDiscardSubs% track(s) to reject: %SubsIdentDiscardLine:~1%
    IF %NumberDiscardSubs%==0 GOTO:muxing
    
    :muxing
    IF %NumberDiscardAudio%==0 IF %NumberDiscardSubs%==0 ECHO(Nothing to do.&EXIT /b
    IF %NumberDiscardAudio% NEQ 0 SET "CommandLine=-a %AudioIdentKeepLine:~1%"
    IF %NumberDiscardSubs% NEQ 0 SET "CommandLine=%Commandline% -s %SubsIdentKeepLine:~1%"
    
    rem make a backup copy of the MKV
    FOR %%a IN ("%MKVFile%") DO SET "MKVBackupFile=%%~na.bak%%~xa"
    ECHO(Building "%MKVBackupFile%"
    REN "%MKVFile%" "%MKVBackupFile%" || (ECHO(Error renaming to "%MKVBackupFile%"&EXIT /b)
    
    rem build the new MKV
    FOR %%a IN ("%MKVFile%") DO SET "MKVBackupFile=%%~dpa%MKVBackupFile%"
    ECHO(REMuxing "%MKVFile%"
    mkvmerge -o "%MKVFile%" %Commandline% "%MKVBackupFile%"
    EXIT /b
    The code might crash, if you use characters like !%^ or similar in file or path names.
    Last edited by fryk; 19th Dec 2013 at 10:33. Reason: update.
    Quote Quote  
  23. Thanks for that fryc! I have two questions:- There seems to be an issue with passing the .bak file to the mkvmerge when the mkv's are in subfolders
    - Is there a way to make it set the default flash for video/audio?

    Thanks!
    Quote Quote  
  24. Member fryk's Avatar
    Join Date
    Oct 2012
    Location
    Europe
    Search PM
    Originally Posted by f00kie View Post
    There seems to be an issue with passing the .bak file to the mkvmerge when the mkv's are in subfolders
    -
    Yes, you are right, thanks. I made an edit. What defaults do you want to set?
    Quote Quote  
  25. Originally Posted by greenbender View Post
    An old thread but others might be interested.

    The following python script will batch remove non English audio and subtitles, set the default audio track to the first English track and ensure that there are no default subtitles (only minor modification to support other languages - probably should be a command line option). The script will process any .mkv files in the input directory and all sub directories.

    You just need to install python and mkvtoolnix.

    if you need further help then search for something like "how to run a python script".

    Code:
    #!/usr/bin/python
    
    import os
    import re
    import sys
    import StringIO
    import subprocess
    
    # change this for other languages (3 character code)
    LANG = "eng"
    
    # set this to the path for mkvmerge
    MKVMERGE = "C:/Program Files/MKVtoolnix/mkvmerge.exe"
    
    AUDIO_RE    = re.compile(r"Track ID (\d+): audio \([A-Z0-9_/]+\) [number:\d+ uid:\d+ codec_id:[A-Z0-9_/]+ codec_private_length:\d+ language:([a-z]{3})")
    SUBTITLE_RE = re.compile(r"Track ID (\d+): subtitles \([A-Z0-9_/]+\) [number:\d+ uid:\d+ codec_id:[A-Z0-9_/]+ codec_private_length:\d+ language:([a-z]{3})(?: track_name:\w*)? default_track:[01]{1} forced_track:([01]{1})")
    
    if len(sys.argv) < 2:
        print "Please supply an input directory"
        sys.exit()
    
    in_dir = sys.argv[1]
    
    for root, dirs, files in os.walk(in_dir):
        for f in files:
    
            # filter out non mkv files
            if not f.endswith(".mkv"):
                continue
    
            # path to file
            path = os.path.join(root, f)
    
            # build command line
            cmd = [MKVMERGE, "--identify-verbose", path]
    
            # get mkv info
            mkvmerge = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = mkvmerge.communicate()
            if mkvmerge.returncode != 0:
                print >> sys.stderr, "mkvmerge failed to identify", path
                continue
    
            # find audio and subtitle tracks
            audio = []
            subtitle = []
            for line in StringIO.StringIO(stdout):
                m = AUDIO_RE.match(line)
                if m:
                    audio.append(m.groups())
                else:
                    m = SUBTITLE_RE.match(line)
                    if m:
                        subtitle.append(m.groups())
    
            # filter out files that don't need processing
            if len(audio) < 2 and len(subtitle) < 2:
                print >> sys.stderr, "nothing to do for", path
                continue
    
            # filter out tracks that don't match the language    
            audio_lang = filter(lambda a: a[1]==LANG, audio)
            subtitle_lang = filter(lambda a: a[1]==LANG, subtitle)
    
            # filter out files that don't need processing
            if len(audio_lang) == 0 and len(subtitle_lang) == 0:
                print >> sys.stderr, "no tracks with that language in", path
                continue
    
            # build command line
            cmd = [MKVMERGE, "-o", path + ".temp"]
            if len(audio_lang):
                cmd += ["--audio-tracks", ",".join([str(a[0]) for a in audio_lang])]
                for i in range(len(audio_lang)):
                    cmd += ["--default-track", ":".join([audio_lang[i][0], "0" if i else "1"])]
            if len(subtitle_lang):
                cmd += ["--subtitle-tracks", ",".join([str(s[0]) for s in subtitle_lang])]
                for i in range(len(subtitle_lang)):
                    cmd += ["--default-track", ":".join([subtitle_lang[i][0], "0"])]
            cmd += [path]
    
            # process file
            print >> sys.stderr, "Processing", path, "...",
            mkvmerge = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout, stderr = mkvmerge.communicate()
            if mkvmerge.returncode != 0:
                print >> sys.stderr, "Failed"
                continue
            
            print >> sys.stderr, "Succeeded"
    
            # overwrite file
            os.remove(path)
            os.rename(path + ".temp", path)
    I've found this to work really well for stripping non-english audio tracks, however it seems to miss subtitles. Is there something else that can be modified to strip non-english subtitles as well?
    Quote Quote  
  26. [QUOTE=the block;2291787]
    Originally Posted by greenbender View Post
    I've found this to work really well for stripping non-english audio tracks, however it seems to miss subtitles. Is there something else that can be modified to strip non-english subtitles as well?
    I'm also looking for a script to remove non-english subtitles and chapters from my files. Any help would be much appreciated.
    Quote Quote  
  27. batch expert Endoro's Avatar
    Join Date
    Dec 2013
    Location
    Bozen
    Search PM
    I scripted it with awk, an Unix scripting language, available also for Windows.

    ----------

    usage:

    Code:
    awk -f script.awk [video.mkv] [audio-langs-to-keep] [subtitle-langs-to-keep] [keep-chapters]


    examples:


    - keep English and Spain audio, keep French and German subtitles, no chapters
    Code:
    awk -f script.awk video.mkv :eng:spa :fre:ger
    - keep English audio, no subs, keep the chapters
    Code:
    awk -f script.awk video.mkv :eng "" chapters
    - keep no audio, no subs but the chapters
    Code:
    awk -f script.awk video.mkv "" "" chapters
    ----------
    Put a colon `:` in front of every language code. Some valid codes are:
    Code:
    English language name                         | ISO639-2 code
    ----------------------------------------------+---------------
    Afrikaans                                     | afr
    Arabic                                        | ara
    Australian languages                          | aus
    Baltic languages                              | bat
    Catalan; Valencian                            | cat
    Caucasian languages                           | cau
    Chinese                                       | chi
    Corsican                                      | cos
    Croatian                                      | hrv
    Czech                                         | cze
    Dutch; Flemish                                | dut
    English                                       | eng
    French                                        | fre
    Georgian                                      | geo
    German                                        | ger
    Greek, Modern (1453-)                         | gre
    Hebrew                                        | heb
    Hindi                                         | hin
    Hungarian                                     | hun
    Irish                                         | gle
    Italian                                       | ita
    Japanese                                      | jpn
    Javanese                                      | jav
    Korean                                        | kor
    Kurdish                                       | kur
    Norwegian                                     | nor
    Persian                                       | per
    Polish                                        | pol
    Portuguese                                    | por
    Romanian; Moldavian; Moldovan                 | rum
    Russian                                       | rus
    Serbian                                       | srp
    Spanish; Castillan                            | spa
    Swedish                                       | swe
    Thai                                          | tha
    Turkish                                       | tur
    Ukrainian                                     | ukr
    Vietnamese                                    | vie
    Walloon                                       | wln
    Yiddish                                       | yid
    ----------
    **Please set the full `PATH` to your MKVToolnix distribution in the variable `MKVMerge`.**
    ----------
    ###`script.awk`
    Code:
    BEGIN {
        MKVMerge="C:\\Program Files\\mkvtoolnix\\MKVMerge.exe" # for Win32
        MKVMerge="C:\\Program Files (x86)\\mkvtoolnix\\MKVMerge.exe" # for Win64
        FS="[\t\n: ]"
        IGNORECASE=1
        MKVVideo=ARGV[1]
        AudioKeep=ARGV[2]
        SubsKeep=ARGV[3]
        ChaptersKeep=ARGV[4]
        NewVideo=substr(MKVVideo, 1, length(MKVVideo)-4)".new.mkv"
        do {
            Result=("\""MKVMerge"\" --ui-language en --identify-verbose \""MKVVideo"\"" | getline Line);
            if (Result>0) {
                FieldCount=split(Line, Fields)
                if (Fields[1]=="Track") {
                    NoTr++
                    Track[NoTr, "id"]=Fields[3]
                    Track[NoTr, "typ"]=Fields[5]
                    for (i=6; i<=FieldCount; i++) {
                        if (Fields[i]=="language") Track[NoTr, "lang"]=Fields[++i]
                    }
                }
            }
        }    while (Result>0)
        if (NoTr==0) {
            print "Error! No tracks found in \""MKVVideo"\"."
            exit
        } else {print "\""MKVVideo"\":", NoTr, "tracks found."}
        for (i=1; i<=NoTr; i++) {
            if (Track[i, "typ"]=="audio") {
                if (AudioKeep~Track[i, "lang"]) {
                    print "Keep", Track[i, "typ"], "Track", Track[i, "id"],  Track[i, "lang"]
                    if (AudioCommand=="") {AudioCommand=Track[i, "id"]
                } else AudioCommand=AudioCommand","Track[i, "id"]
                } else {
                    print "\tRemove", Track[i, "typ"], "Track", Track[i, "id"],  Track[i, "lang"]
                }
            } else {
                if (Track[i, "typ"]=="subtitles") {
                    if (SubsKeep~Track[i, "lang"]) {
                        print "Keep", Track[i, "typ"], "Track", Track[i, "id"],  Track[i, "lang"]
                        if (SubsCommand=="") {SubsCommand=Track[i, "id"]
                        } else SubsCommand=SubsCommand","Track[i, "id"]
                    } else {
                        print "\tRemove", Track[i, "typ"], "Track", Track[i, "id"],  Track[i, "lang"]
                    }
                }
            }
        }
        if (AudioCommand=="") {CommandLine="-A"
        } else {CommandLine="-a "AudioCommand}
        if (SubsCommand=="") {CommandLine=CommandLine" -S"
        } else {CommandLine=CommandLine" -s "SubsCommand}
        if (!ChaptersKeep) CommandLine=CommandLine" --no-chapters"
        print "\"" MKVMerge "\" -o \"" NewVideo "\" " CommandLine " \"" MKVVideo "\""
        Result=system("\"" MKVMerge "\" -o \"" NewVideo "\" " CommandLine " \"" MKVVideo "\"")
        if (Result>1) print "Error "Result" muxing \""MKVVideo"\"!"
    }
    Quote Quote  
  28. Member
    Join Date
    Jan 2014
    Location
    iikingli
    Search Comp PM
    Originally Posted by fryk View Post
    I adopted it for the Windows cmd shell ('batch') and added subtitle support.
    Tested with Windows 8.

    Code:
     
    @ECHO OFF &SETLOCAL
    TITLE Recursive remove audio and subtitle tracks by language from MKV video files
    rem search for MKVs in all "StartFolder\Subfolders", not in "Startfolder" itself
    SET "StartFolder=."
    rem example to keep English and German audio tracks, please note the colon in front of the language code
    SET "AudioTracksToKeep=:eng:ger"
    rem example to keep Spanish and French subtitle tracks, please note the colon in front of the language code
    SET "SubsTracksToKeep=:spa:fre"
    rem the file name variable must be global for some reasons
    SET "MKVFile="
    
    FOR /f "DELIMS=" %%a IN ('DIR /b /s /a-d "%StartFolder%\*.mkv"') DO SET "MKVFile=%%~a"&CALL:scanmkv
    GOTO:EOF
    
    :scanmkv
    SETLOCAL
    ECHO(
    ECHO(Scanning "%MKVFile%" for unwanted tracks.
    (FOR /l %%b IN (1 1 45) DO <nul SET /p "=-")&ECHO(
    
    SET /a AudioTrackCount=0
    SET /a NumberKeepAudio=0
    SET /a NumberDiscardAudio=0
    
    rem get the number of audio tracks
    FOR /f %%a IN ('mkvmerge --ui-language en -i "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: audio"') DO SET /a AudioTrackCount+=1
    ECHO(Number of audio tracks: %AudioTrackCount%
    rem always keep at least one audio track
    IF %AudioTrackCount% LSS 2 GOTO:subscan
    
    rem get the audio tracks to keep
    SET "KeepAudioSearchString=%AudioTracksToKeep::= language:%"
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: audio"^|FINDSTR /ri "%KeepAudioSearchString%"') DO (
        SET /a NumberKeepAudio+=1
        CALL SET "AudioIdentKeepLine=%%AudioIdentKeepLine%%,%%a"
    )
    IF NOT DEFINED AudioIdentKeepLine SET "AudioIdentKeepLine= ^<none^>"
    ECHO(ID of %NumberKeepAudio% track(s) to keep: %AudioIdentKeepLine:~1%
    IF %NumberKeepAudio%==0 GOTO:subscan
    
    rem get the audio tracks to reject
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: audio"^|FINDSTR /riv "%KeepAudioSearchString%"') DO (
        SET /a NumberDiscardAudio+=1
        CALL SET "AudioIdentDiscardLine=%%AudioIdentDiscardLine%%,%%a"
    )
    IF NOT DEFINED AudioIdentDiscardLine SET "AudioIdentDiscardLine= ^<none^>"
    ECHO(ID of %NumberDiscardAudio% track(s) to reject: %AudioIdentDiscardLine:~1%
    IF %NumberDiscardAudio%==0 GOTO:subscan
    
    :subscan
    SET /a SubsTrackCount=0
    SET /a NumberKeepSubs=0
    SET /a NumberDiscardSubs=0
    
    rem get the number of subtitle tracks
    FOR /f %%a IN ('mkvmerge --ui-language en -i "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: subtitles"') DO SET /a SubsTrackCount+=1
    ECHO(Number of subtitle tracks: %SubsTrackCount%
    IF %SubsTrackCount% EQU 0 GOTO:muxing
    
    rem get the subtitle tracks to keep
    SET "KeepSubsSearchString=%SubsTracksToKeep::= language:%"
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: subtitles"^|FINDSTR /ri "%KeepSubsSearchString%"') DO (
        SET /a NumberKeepSubs+=1
        CALL SET "SubsIdentKeepLine=%%SubsIdentKeepLine%%,%%a"
    )
    IF NOT DEFINED SubsIdentKeepLine SET "SubsIdentKeepLine= ^<none^>"
    ECHO(ID of %NumberKeepSubs% track(s) to keep: %SubsIdentKeepLine:~1%
    IF %NumberKeepSubs%==0 GOTO:muxing
    
    rem get the subtitle tracks to reject
    FOR /f "TOKENS=3DELIMS=: " %%a IN ('mkvmerge --ui-language en --identify-verbose "%MKVFile%"^|FINDSTR /rbic:"Track ID [0-9][0-9]*: subtitles"^|FINDSTR /riv "%KeepSubsSearchString%"') DO (
        SET /a NumberDiscardSubs+=1
        CALL SET "SubsIdentDiscardLine=%%SubsIdentDiscardLine%%,%%a"
    )
    IF NOT DEFINED SubsIdentDiscardLine SET "SubsIdentDiscardLine= ^<none^>"
    ECHO(ID of %NumberDiscardSubs% track(s) to reject: %SubsIdentDiscardLine:~1%
    IF %NumberDiscardSubs%==0 GOTO:muxing
    
    :muxing
    IF %NumberDiscardAudio%==0 IF %NumberDiscardSubs%==0 ECHO(Nothing to do.&EXIT /b
    IF %NumberDiscardAudio% NEQ 0 SET "CommandLine=-a %AudioIdentKeepLine:~1%"
    IF %NumberDiscardSubs% NEQ 0 SET "CommandLine=%Commandline% -s %SubsIdentKeepLine:~1%"
    
    rem make a backup copy of the MKV
    FOR %%a IN ("%MKVFile%") DO SET "MKVBackupFile=%%~na.bak%%~xa"
    ECHO(Building "%MKVBackupFile%"
    REN "%MKVFile%" "%MKVBackupFile%" || (ECHO(Error renaming to "%MKVBackupFile%"&EXIT /b)
    
    rem build the new MKV
    FOR %%a IN ("%MKVFile%") DO SET "MKVBackupFile=%%~dpa%MKVBackupFile%"
    ECHO(REMuxing "%MKVFile%"
    mkvmerge -o "%MKVFile%" %Commandline% "%MKVBackupFile%"
    EXIT /b
    The code might crash, if you use characters like !%^ or similar in file or path names.

    Fryk I have been trying your scrip to no end over the last several hours... i keep getting Error: The file 'W:\MKVToolNix"' could not be opened for reading: open file error.

    I have checked every persmisson known to man and still no luck. Now if i try and run a different batch file pasted below i can get it to work. However I would prefer your script as not every file is id 2... any help you can provide would be awesome

    Sorry for the Bold Large Text i figured its the fastest way to break my text in between the 2 bat files

    @echo off

    title MKVstrip

    cls
    set /p MM=This batch script will strip unwanted audio/subtitle tracks from ALL .mkv files in the directory it is run from. The changes will be made to copies of the files and the originals will remain untouched. For this reason, please make sure you have enough disk space for the output files. Continue? (Y/N):
    IF '%MM%' == 'Y' GOTO AS
    IF '%MM%' == 'y' GOTO AS
    IF '%MM%' == 'N' GOTO EN
    IF '%MM%' == 'n' GOTO EN

    :AS
    cls
    set /p AT=Type the track ID(s) of the audio track(s) you would like to KEEP, seperated by commas (to keep ALL type 0, to view track IDs type i):
    IF '%AT%' == 'i' GOTO ID
    IF '%AT%' == '0' GOTO SSNA

    :SS
    cls
    set /p ST=Type the track ID(s) of the subtitle track(s) you would like to KEEP, seperated by commas (if none are present or to remove ALL then type 0):
    IF '%ST%' == '0' GOTO NS

    :WS
    cls
    md output
    for %%i in (*.mkv) do mkvmerge -o output/"%%i" --atracks "%AT%" --stracks "%ST%" "%%i"
    cls
    Echo The process is complete. The stripped files are located in the "output" folder.
    pause
    exit

    :SSNA
    cls
    set /p ST=Type the track ID(s) of the subtitle track(s) you would like to KEEP, seperated by commas (if none are present or to remove ALL then type 0):
    IF '%ST%' == '0' GOTO NANS

    :NA
    cls
    md output
    for %%i in (*.mkv) do mkvmerge -o output/"%%i" --stracks "%ST%" "%%i"
    cls
    Echo The process is complete. The stripped files are located in the "output" folder.
    pause
    exit

    :NANS
    cls
    md output
    for %%i in (*.mkv) do mkvmerge -o output/"%%i" --no-subtitles "%%i"
    cls
    Echo The process is complete. The stripped files are located in the "output" folder.
    pause
    exit

    :NS
    cls
    md output
    for %%i in (*.mkv) do mkvmerge -o output/"%%i" --atracks "%AT%" --no-subtitles "%%i"
    cls
    Echo The process is complete. The stripped files are located in the "output" folder.
    pause
    exit

    :ID
    for %%i in (*.mkv) do mkvmerge -i "%%i"
    Echo Press ENTER to continue:
    pause
    GOTO AS

    :EN
    exit
    Quote Quote  
  29. Member fryk's Avatar
    Join Date
    Oct 2012
    Location
    Europe
    Search PM
    Originally Posted by iikingli View Post
    Fryk I have been trying your scrip to no end over the last several hours... i keep getting Error: The file 'W:\MKVToolNix"' could not be opened for reading: open file error.

    I have checked every persmisson known to man and still no luck. Now if i try and run a different batch file pasted below i can get it to work. However I would prefer your script as not every file is id 2... any help you can provide would be awesome
    SOrry, but I do not know anything about your folder tree, the PATH and environment variables setting. What is The file 'W:\MKVToolNix"'? File, folder or ...
    Quote Quote  



Similar Threads