Change default audio for series
#1
Howdo.

I've just started watching a series that has two audio tracks, 1 in German, the other English.
XBMC always plays the German track, when I'd prefer the English. I can manually change this each time from the in-video menu, but was wondering if there is a more elegant, automated way to change this? sort of a "force english" audio option.

btw, i changed the audio to track 2 (english) and saved it as default from the in-video menu, but that didnt make any difference to the next episode i played.


thanks.
Image
Reply
#2
I suspect you'll have to use mkvtools or something similar to change the default track setting in the mkv.

JR
Reply
#3
I have stumbled over the very same situation, it is not Windows or any platform specific and I am actually surprised that XBMC does not provide a preference setting where the user can specify what default audio track he/she wants to listen to. I'm sure this function has been asked for many many times in this forum and it should be difficult to add it.

In the absence of that functionality built into XBMC, you can do the following on a Unix-like (FreeBSD, Linux, ...) system:

Install mkvtoolnix on your system, write a bash / awk script (or any other scripting language of your choice), walk through all your movies, run mkvinfo on each file, parse the relevant properties into variables in your script, construct an appropriate "mkvpropedit" commandline and execute that command on each file. With mkvpropedit you can set the "default-flag" of exactly that audio track you want XBMC to use as the default.

I have verified that this process works.

PS: If there is any other thread around here where that functionality is being discussed, pls point me to it, I haven't found any yet.
Reply
#4
Thanks for the info tinyxbmc. If you have written a script to do the job is there any chance you could share it on the forum please?
Reply
#5
And for those of you that can't write bash scripts or don't have the slightest idea what any of that means, you can simply use mkvmerge GUI to remove audio tracks and/or change the default audio flag.

XBMC cannot pick out anything but the default audio track, unless you play it and switch it manually, then it remembers the audio track you selected.
Reply
#6
If it is just a 'one-off' or infrequent occurrence, you could load the file in mkvmerge and use the 'header' options to change the default flagging of the audio to whatever track you want without remuxing.

The same process can be used to change default/forced subtitle tracks to your preferred language.
Reply
#7
superdubious Wrote:Thanks for the info tinyxbmc. If you have written a script to do the job is there any chance you could share it on the forum please?
I can certainly make it available "as is". Where should I put it?
Reply
#8
Given that XBMC can list the audio tracks by name already (some of which say the language), it'd be cool to see a configurable regex that can auto-select the track that way. Even cooler if its toggle-able for TV and/or Movies. I know that movie DVDs can sometimes have multiple English tracks.

Maybe I'll see if this could be accomplished by a plugin...
Reply
#9
(2012-01-09, 23:02)tinyxbmc Wrote:
superdubious Wrote:Thanks for the info tinyxbmc. If you have written a script to do the job is there any chance you could share it on the forum please?
I can certainly make it available "as is". Where should I put it?
If it's just a bash script throw it up in a bbcode tag (literally just ['code'] without the ''s):
Code:
Like so

Hope you subscribed to this thread as I really would like your script Tongue
Reply
#10
I am trying the "code" tags, however, no guarantees that the copy/paste really renders a working script. At least the tab characters are gone and the formatting of the source file seems broken. I would prefer to upload a real file.

Code:
#!/bin/bash
#
# File:         mkvflags
# Author:       tinyxbmc
# Version:      $Id: mkvflags,v 1.9 2012/04/06 20:26:26 tinyxbmc Exp tinyxbmc $
#
# Description
#
#       This script reads and changes flag properties in .mkv containers
#
#       If no argument is passed we walk down all .mkv files in the current
#       working directory. If an argument or list of arguments is
#       given we treat each of them as file and try to process it
#
# Motivation / Background
#
#       .mkv Movies contain multiple "tracks". Video tracks, audio tracks,
#       subtitle tracks. At creation time the author can specify which
#       tracks should be played by default. He can also set a "force" flag.
#       The "XBMC" media player interprets those flags and plays the
#       appropriate track. Frequently the files have been authored with
#       "German" audio track marked as "default", an option which I personally
#       did not want. Consequently I have written this script to walk
#       through all my files and modify the flags such that an "English"
#       track is marked as the default track. Subsequently I enhanced the
#       script to recognize if more than one English audio track is available
#       and then make the DTS track the default, if available.
#
# Filename Requirements
#
#       None
#
# Dependencies:
#
#       bash
#       awk (actually "gawk", not "mawk")
#       mkvinfo
#       mkvpropedit
#

help ()
{
        cat <<EOF 1>&2

mkvflags \$Revision: 1.9 $ is a tool to read and modify .mkv property flags

Usage: mkvflags [options] [file 1] ...  [file n]

   Options
      -d prints debug messages
      -e perform (hard coded) flag edit functions
      -q quiet
      -v verbose

   file 1 ... file n
      Specifying a filename is optional. If no filename is specified,
      .mkv files in the current directory will be processed implicitly
      A word on the use of the "-d" switch: If that switch is set
      mkvflags will echo the full mkvpropedit command to stdout but
      it doesn't execute it. The command can be executed manually via
      copying / pasting it into a command line and even manually
      editing the flags.

   Author: tinyxbmc

EOF
        exit 1
}

# process ()
#
#       gets invoked on a per file basis. It takes the full filename from
#       "$f" implicitly
#

process () {
        mkvinfo  "$f" 2>&1 | awk -v quiet=$quiet -v verbose=$verbose -v edit=$edit -v debug=$debug -v file="$f" '
                BEGIN {
                        t = 0;             # track index
                }
                /Track number/ {
                        t++;               # track index
                        num[t]       = $5; # keep track of the tracknumber as stored in the mkv
                        uid[t]       = 0;  # track UID
                        type[t]      = ""; # track type, e.g. video, audio, subtitle
                        default_f[t] = 0;  # default flag as read from the mkv
                        forced_f[t]  = 0;  # forced flag as read from the mkv
                        codec[t]     = ""; # codec as read from the mkv
                        language[t]  = ""; # language as read from the mkv
                        lang_done    = 0;  # there might be Chapter Language fields following
                }
                /Track UID/ {
                        uid[t] = $5;
                }
                /Track type/ {
                        type[t] = $5;
                }
                /Default flag/ {
                        default_f[t] = $5;
                }
                /Forced flag/ {
                        forced_f[t] = $5;
                }
                /Codec ID/ {
                        codec[t] = $5;
                }
                /Language/ {
                        if (!lang_done) {
                                language[t] = $4;
                                lang_done = 1;
                        }
                }
                END {
                        # 1st pass through all tracks
                        # walk through all audio tracks and find out if there is an
                        # English DTS track which then would be our preference for the default
                        # sometimes we find an audio track marked "und" which probably stands for
                        # "undefined". In all practical examples those tracks were English so
                        # I treat them that way
        
                        eng_dts_found = 0;
                        for (i = 1; i <= t; i++) {
                                if (codec[i] == "A_DTS" && (language[i] == "eng" || language[i] == "und" || language[i] == ""))
                                        eng_dts_found = i;
                        }

                        # 2nd pass through all tracks
                        # The ultimate goal, besides listing the fields in verbose mode, is to find
                        # the right audio track which we want to set as the default. All but one
                        # audio track gets the default = 0 flag, the forced flag is set to zero
                        # all tracks unconditionally

                        out = sprintf("Tracks: %s\n", t);
                        cmd = sprintf("mkvpropedit \"%s\" ", file);
                        audio_done = 0;

                        for (i = 1; i <= t; i++) {
                                df = 0;
                                out = out sprintf("Track %u(%u,%u), ", i, num[i], uid[i]);
                                out = out sprintf("Type %s, ",         type[i]);
                                out = out sprintf("Language %s, ",     language[i]);
                                out = out sprintf("Default %s, ",      default_f[i]);
                                out = out sprintf("Forced %s, ",       forced_f[i]);
                                out = out sprintf("Codec %s\n",        codec[i]);
                                if (type[i] == "video") df = 1;
                                if (type[i] == "audio") {
                                        if (!audio_done && (language[i] == "eng" || language[i] == "und" || language[i] == "")) {
                                                if (eng_dts_found) {
                                                        if (codec[i] == "A_DTS") {
                                                                df = 1;
                                                                audio_done = 1;
                                                        }
                                                } else {
                                                        df = 1;
                                                        audio_done = 1;
                                                }
                                        }
                                }
                                cmd = cmd sprintf("--edit track:%u --set flag-default=%u ", num[i], df);
                                cmd = cmd sprintf("--set flag-forced=%u ", 0);
                        }

                        out = out sprintf("\n");
                        if (quiet == "0") {
                                printf("File %s\n", file);
                                if (verbose == "1") printf(out);
                        }

                        if (t) {
                                if (debug == "1") printf("%s\n", cmd);
                                if (edit  == "1") system(cmd);
                        }
                }
        '
}

#
# main body of the script
#
#       This is just to allow the passing of a single file as an argument
#       or go for the full directory addressing all .mkv files. In most
#       cases the script is invoked without any parameters.
#
#       At first we check whether the dependencies to external programs
#       are met, then we parse the commandline options, finally we
#       execute the "process" on each input file
#

hash mkvinfo &> /dev/null
if [ $? -eq 1 ]; then
        echo >&2 "mkvinfo is required but not found"
        exit
fi

hash mkvpropedit &> /dev/null
if [ $? -eq 1 ]; then
        echo >&2 "mkvpropedit is required but not found"
        exit
fi

OPTERR=0
debug=0
edit=0
quiet=0
verbose=0
n=0

while getopts den:qv opt ; do
        case "$opt" in
                d) debug=1;;
                e) edit=1;;
                n) n="$OPTARG";;
                q) quiet=1;;
                v) verbose=1;;
                [?]) help;;
        esac
done

shift $((OPTIND-1))

if [ "$debug" -ne "0" ] ; then
        echo "Running in debug mode" 1>&2
        quiet=0
fi

if [ -z "$1" ]; then
        for f in *.mkv ; do
                if [ -f "$f" ]; then
                        #echo $f
                        process
                fi
        done
else
        until [ -z "$1" ] ; do
                f=$1
                process
                shift
        done
fi
Reply
#11
Thanks for this tinyxbmc.

Does this work recursively through folders until it finds the mkv files? All my media is in separate folders named after the movie/tv show.

Would it be easy enough to alter the script to choose DD AC3 as the preferred first track, DTS if it can't find DD, and then go for the UND track?
Reply
#12
(2012-04-10, 17:10)DeMoB Wrote: Thanks for this tinyxbmc.

Does this work recursively through folders until it finds the mkv files? All my media is in separate folders named after the movie/tv show.

Would it be easy enough to alter the script to choose DD AC3 as the preferred first track, DTS if it can't find DD, and then go for the UND track?
At this time it stays in the current directory only. It shouldn't be too hard to add the code to walk directory trees. Which track it chooses for the default is currently hard wired into the code. Let me see if I can find a way to code the rules into variables that can be customized easily without requiring a code change all the time.

Reply
#13
This whole thread is exactly what I was looking to accomplish with my own files, but I'm a bit of a dummy when it comes to scripting.

Has this idea been implemented into XBMC in the meantime since the last post? I'm having issues with a TV Show series that is insisting on choosing Russian AC3 (Track 1) instead of English DTS (Track 2) despite my setting english as the preferred audio in XBMC Eden stable.

Any direction? Sorry if I'm resurrecting a dead thread or a solved issue.
Reply
#14
I don't think it's in Eden, but perhaps in the releases for Frodo whish I guess you can call Alpha status.

So your option is:

- Have a look at this: http://forum.xbmc.org/showthread.php?tid=89014

- learn to script a little bit and use mkvpropedit (if you're on Linux, use the script posted earlier in this thread)

- use an external player like MPC-HC where you can set which Audio track it should play.
Reply
#15
Is there any progress on something like this yet? I watch a lot of Japanese stuff and it's murder having to change language each video.
Reply

Logout Mark Read Team Forum Stats Members Help
Change default audio for series0