Giter Club home page Giter Club logo

mpv-sub-select's Introduction

mpv-sub-select

This script allows you to configure advanced subtitle track selection based on the current audio track and the names and language of the subtitle tracks. The script will automatically disable itself when mpv is started with --sid not set to auto, or when --track-auto-selection is disabled. There is also experimental mode which allows audio selection as well.

Configuration

Configuration is done in the sub-select.json file, stored in the ~~/script-opts/ config directory.

Syntax

The syntax and available options are as follows:

[
    {
        "alang": "jpn",
        "slang": "eng",
        "blacklist": [ "sign" ],                // optional
        "whitelist": [ "english", "song" ],     // optional
        "condition": "sub.codec == 'ass'",      // optional
        "id": "unique-id",                      // optional
        "inherit": "other-id"                   // optional
    }
]

alang and slang are the language codes of the audio and subtitle tracks, while blacklist and whitelist are optional filters that can be used to choose subtitle tracks based on their track names. For a track to be selected it must match any entry in the whitelist and must not match any entry in the blacklist.

alang and slang can also be arrays of valid codes to allow matching with multiple language codes. If multiple slang languages are included, then the first code to match to a track will be the one used.

Do not use uppercase characters for any options unless using patterns.

All titles are converted to lowercase automatically to allow more matches.

String Matching

All matching is done using the lua string.find function, so supports patterns. For example eng? could be used instead of eng so that the DVD language code en is also matched.

The characters ^$()%.[]*+-? have special behaviour and muct be escaped with %.

Priority

The script moves down the list of track preferences until any valid pair of audio and subtitle tracks are found. Once this happens the script immediately sets the subtitle track and terminates. If none of the tracks match then track selection is deferred to mpv.

Special Strings

There are a number of strings that can be used for the alang and slang which have special behaviour.

alang:

String Action
* matches any language
no matches when no audio track is selected - not included by *
default matches audio with the default tag
forced matches audio with the forced tag

slang:

String Action
* matches the first track that passes the filters
no disables subs if alang matches
default selects subtitles with the default tag
forced selects subtitles with the forced tag

Conditions

Conditions are a way to specify advanced, powerful, and custom filters. The condition field is a lua expression that can be used to evaluate whether or not the subtitle should be selected. This expression will be run for every subtitle that passes the other filters. The sub variable contains the subtitle track entry and audio contains the audio track entry. See the track-list property for what fields are available. The mp, mp.msg, and mp.utils modules are avaialble as mp, msg, and utils, respectively. If no audio or sub track is being compared (which only happens if you set alang or slang to no) then audio or sub will evaluate to nil.

In the following examples the condition requires:

  • "condition": "sub.external" - an external subtitle file.
  • "condition": "audio.default and sub.id == 1" - the default audio and the first subtitle in the file.
  • "condition": "mp.get_property('path', ''):find('Anime') ~= nil" - the path of the current file to contain Anime.

Inheritance

To make it easier to write complex config files you can set the preferences to inherit from each other. This will reduce the need to duplicate the same fields in multiple preferences. Inheritence uses the id and inherit fields. The id field must be a string that is unique to that preference (no two preferences can have the same ID). The inherit field can be used to specify the ID of the preference to inherit from. The special (reserved) ID ^ will inherit from the previous preference without it needing an explicit ID.

The new child preference will inherit all the fields from the parent that have not been explicitly overwritten. Inheritance can be chained, but make sure not to create circular inheritance.

In the below example the first preference inherits the alang and slang fields from the second preference. The first preference adds a condition field to prefer external subtitles.

[
    {
        "inherit": "example-id",
        "condition": "sub.external"
    },
    {
        "alang": "*",
        "slang": "eng?",
        "id": "example-id",
    }
]

In this more complex example external subtitles are the main preference, followed by a preference for ass subtitles. The special ^ ID is used to simplify the config. Note the final preference needs to add a superfluous condition statement to override the inherited condition from the third preference.

[
    {
        "alang": ["jpn", "ja"],
        "slang": ["en%-us", "eng?"],
        "whitelist": [ "sign", "song"],
        "condition": "sub.codec == 'ass' and sub.external" 
    },
    {
        "inherit": "^",
        "condition": "sub.external" 
    },
    {
        "inherit": "^",
        "condition": "sub.codec == 'ass'" 
    },
    {
         "inherit": "^",
         "condition": "sub.codec ~= 'ass'"
    }
]

Commands

The script supports two commands to control subtitle selection.

script-message select-subtitles

This command will force subtitle selection during runtime based on the current audio track.

script-message sub-select [arg]

This command will enable/disable the script. Valid arguments are enable, disable, and toggle. If the script gets enabled then the current subtitle track will be reselected.

Auto-Switch Mode

The detect_audio_switches script-opt allows one to enable Auto-Switch Mode. In this mode the script will automatically reselect the subtitles when the script detects that the audio language has changed. This setting ignores --sid=auto, but when using synchronous mode the script will not change the original sid until the first audio switch. This feature still respects --track-auto-selection. This mode can be disabled during runtime wi the sub-select script message shown above.

Audio Selection

This is an experimental option to allow advanced selection of pairs of audio and subtitle tracks. Controlled by the select_audio option.

When this option is enabled the script will go through the list of preferences as usual, but instead of comparing the sub tracks against the current audio track it will compare it against all audio tracks. If any audio tracks match the alang and there are subs that match the slang and filters, then that audio track will be selected.

If multiple audio tracks match a preference then the track that occurs first in the track list will be chosen. This option does not break observe_audio_switches but will disable the force_prediction and detect_incorrect_predictions options.

The whitelist and blacklist will still only work with subs, but the condition filter can be used to implement audio-specific filtering behaviour.

Synchronous vs Asynchronous Track Selection

The script has two different ways it can select subtitles, controlled with the preload script-opt. The default is to load synchronously during the preload phase, which is before track selection; this allows the script to seamlessly change the subtitles to the desired track without any indication that the tracks were switched manually. This likely has better compatability with other options and scripts.

The downside of this method is that when --aid is set to auto the script needs to scan the track-list and predict what track mpv will select. Therefore, in some rare situations, this could result in the wrong audio track prediction, and hence the wrong subtitle being selected. There are several solutions to this problem:

Use Asynchronous Mode (default no)

Disable the hook by setting preload=no. This is the simplest and most efficient solution, however it means that track switching messages will be printed to the console and it may break other scripts that use subtitle information.

Force Prediction (default no)

Force the predicted track to be correct by setting aid to the predicted value. This can be enabled with force_prediction=yes. This method works well, but is not ideal if one wants to utilise a more refined audio track selector, or if mpv's default is more desirable.

Detect Incorrect Predictions (default yes)

Check the audio track when playback starts and compare with the latest prediction, if the prediction was wrong then the subtitle selection is run again. This can be disabled with detect_incorrect_predictions=no. This is the best of both worlds, since 99% of the time the subtitles will load seamlessly, and on the rare occasion that the file has weird track tagging the correct subtitles will be reloaded. However, this method does have the highest computational overhead, if anyone cares about that.

Auto-Select Mode enables this intrinsically.

Use audio selection mode (default no)

See Audio Selection.

Examples

The sub_select.conf file contains all of the options for the script and their defaults. The sub-select.json file contains a decent default configuration for English users. The wiki page provides some more custom examples.

mpv-sub-select's People

Contributors

cabbagefork avatar cogentredtester avatar duxovni avatar dyphire avatar grub4k avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mpv-sub-select's Issues

Allow optional preferred terms

In some files, there are more than one subtitle of the same language, and the subtitle with all the dialogues has a suffix (full). Is it possible to add it as an optional preferred term? Adding it as a whitelist term will select nothing when only one subtitle of that language is present.

Need Help With Configuration

For some reason I am unable to properly install the script. I put the sub-select.lua file in the scripts folder and the sub-select.json file in the script-opts folder. I have not used the sub-select.conf file as I don't know where to put it.
My .json file is as follows

[
	{
		"alang": "jpn"
		"slang": ["jpn", "enm", "eng"]
		"blacklist": ["sign", "signs", "translation only"]
		"whitelist": ["commie", "honorifics"]
	},
	{
		"alang": "eng"
		"slang": ["forced", "no"]
	},
        {
                "alang": "el"
                "slang": "no"
        },
	{
		"alang": "*"
		"slang": "eng"
	}
]

So, if an audio track has the language English it should try a forced track and if there isn't one, subtitles should be turned off. Yet, when I tested this with a video with English audio and an English non-forced subtitle track, the english subtitles were selected, as if mpv did the selection and not the script. Maybe I have to copy sub-select.conf somewhere for it to work? Please help.

Add option to use "sid=" value from mpv.conf inside media folder

MPV has useful option for overriding certain options per-folder by creating mpv.conf in it with option you need (for example sid=2 to always select subtitle number two), but, sub-select overrides mpv's subtitle selecting logic and "sid" value from this file is not used, so, it would be nice to have an option to use "sid" value if mpv.conf has it.

Feature request: Ability to blacklist / whitelist audio tracks

Consider this example of a file with mislabeled tracks:

 (+) Video --vid=1 'H.264/AVC Video' (h264 720x480 29.970fps)
 (+) Audio --aid=1 --alang=eng (*) 'English: Stereo' (aac 2ch 44100Hz)
     Audio --aid=2 --alang=eng 'Japanese: Stereo' (aac 2ch 48000Hz)
 (+) Subs  --sid=1 --slang=eng (*) 'Titles & Signs' (ass)
     Subs  --sid=2 --slang=eng 'English Subtitles (Anime-Keep)' (ass)

It'd be great if I could say, select the audio track which has "japanese" in its title, before going for eng audio.

Issue blacklisting a subtitle

I've got a video with two subtitles. One has the name "English" and the other has the name "English (Translation Only)". The default sub is the latter which is akin to signs/songs in terms of actually being useful when watching something with an audio track in another language.

I have this in my sub-select.json

    {
        "alang": [ "j[ap]n?" ],
        "slang": [ "eng?", "und", "jpn?" ],
        "blacklist": [ "Sings/Songs", "signs", "songs", "sign", "song", "English (Translation Only)" ]
    },

Despite that I can't seem to blacklist this sub for some reason. I tried escaping the parentheses with one and two backslashes but to no avail.

Any idea what might be going on?

Here is the output from mkvinfo in case I missed something.

+ EBML head
|+ EBML version: 1
|+ EBML read version: 1
|+ Maximum EBML ID length: 4
|+ Maximum EBML size length: 8
|+ Document type: matroska
|+ Document type version: 2
|+ Document type read version: 2
+ Segment: size 3114128818
|+ Seek head (subentries will be skipped)
|+ EBML void: size 4029
|+ Segment information
| + Timestamp scale: 1000000
| + Multiplexing application: libebml v1.2.1 + libmatroska v1.1.1
| + Writing application: mkvmerge v4.9.1 ('Ich will') built on Jul 11 2011 23:53:15
| + Duration: 00:24:10.474000000
| + Date: 2021-01-23 07:57:15 UTC
| + Segment UID: 0xbb 0x81 0xbd 0x1c 0x01 0x0d 0x3a 0xad 0x91 0x8b 0x20 0xe6 0x02 0x54 0x1c 0x24
|+ Tracks
| + Track
|  + Track number: 1 (track ID for mkvmerge & mkvextract: 0)
|  + Track UID: 1209811604
|  + Track type: video
|  + "Lacing" flag: 0
|  + Minimum cache: 1
|  + Codec ID: V_MPEG4/ISO/AVC
|  + Codec's private data: size 41 (H.264 profile: High @L4.1)
|  + Default duration: 00:00:00.041708333 (23.976 frames/fields per second for a video track)
|  + Language: und
|  + Name: ENCODED BY DARKDREAM
|  + Video track
|   + Pixel width: 1920
|   + Pixel height: 1080
|   + Display width: 1920
|   + Display height: 1080
| + Track
|  + Track number: 2 (track ID for mkvmerge & mkvextract: 1)
|  + Track UID: 1103072181
|  + Track type: audio
|  + Codec ID: A_AAC
|  + Codec's private data: size 5
|  + Default duration: 00:00:00.021333333 (46.875 frames/fields per second for a video track)
|  + Name: English
|  + Audio track
|   + Sampling frequency: 48000
|   + Channels: 6
| + Track
|  + Track number: 3 (track ID for mkvmerge & mkvextract: 2)
|  + Track UID: 1610248080
|  + Track type: audio
|  + "Default track" flag: 0
|  + Codec ID: A_AAC
|  + Codec's private data: size 5
|  + Default duration: 00:00:00.021333333 (46.875 frames/fields per second for a video track)
|  + Language: jpn
|  + Name: Japanese
|  + Audio track
|   + Sampling frequency: 48000
|   + Channels: 6
| + Track
|  + Track number: 4 (track ID for mkvmerge & mkvextract: 3)
|  + Track UID: 1675229328
|  + Track type: subtitles
|  + "Lacing" flag: 0
|  + Codec ID: S_TEXT/ASS
|  + Codec's private data: size 823
|  + Name: English (Translation Only)
| + Track
|  + Track number: 5 (track ID for mkvmerge & mkvextract: 4)
|  + Track UID: 1537904289
|  + Track type: subtitles
|  + "Default track" flag: 0
|  + "Lacing" flag: 0
|  + Codec ID: S_TEXT/ASS
|  + Codec's private data: size 823
|  + Name: English
|+ EBML void: size 1189
|+ Attachments
| + Attached
|  + File name: OpenSans-Semibold_0.ttf
|  + MIME type: application/x-truetype-font
|  + File data: size 221328
|  + File UID: 123114646
|+ Cluster

"sub.external" for plex not working ?

Hi,

Firstly, I thank you for your great work, sir.
Your script seems to also work for plex, but for plex, the script won't select sub.external even though it works for mpv? 
I would appreciate it if you could please help me?

Naming convention for .conf-file

Naming the configuration file sub_select.conf breaks with the other two filenames and is confusing at first.
I would suggest changing it to opt.read_options(o, "sub-select") in the main script to keep the naming consistent or change the two other files to sub_select too.

Can't blacklist a certain term that uses "S&S" as a label

Having trouble doing a specific blacklisting "s&s" from a force subtitle condition. Not sure how to properly escape this, I would assume that within the double quotations it would read everything as is.

Currently this is how I setup the blacklist in the json:

{
"alang": ["jpn", "ja"],
"slang": "eng?",
"blacklist": [ "sign", "s&s" ],
"condition": "sub.forced"
}

[Question] Select by file name?

Example:
-- Folder name: Movie
--- Movie.mkv
--- Movie_eng.ass
--- Movie_chi.ass
--- Movie_spa.ass

Is it possible to auto-select subs with "eng" as their file name?
In some cases those are the only indications to which language the subs are.

"forced" option is not working

First of all, thank you for the great script.
It seems like, since your latest commits this setting is not working for me:

[ 
   {
        "alang": "hun?",
        "slang": [
            "forced",
            "no"
        ]
    }
]

The script cannot find the subtitle track with "forced" flag. I also tried it with "default" option and without the "no" option, but it doen't work either.
It works fine with other settings.

Can you help me?

SubsSelect Stopped Working

It just stopped working seemingly at random. I was using an older version that was running without issue, I thought a recent mpv version might've broken it, yet the issue persisted after I downloaded the .lua file. FOr some reason, it produces no error code on the console, it just says it's selecting a subtitle when it isn't (at least not correctly). I'm pretty sure it's just falling back to native mpv selection. I checked my .json as well and there's nothing wrong with the syntax (it follows the example).

Blacklisted Track Is Selected

A track that should be blacklisted is selected for some reason. Here is the .json:

[
	{
		"alang": "jpn",
		"slang": ["jpn", "enm", "eng"],
		"blacklist": ["signs", "songs", "translation only"],
		"whitelist": ["commie", "honorifics"]
	},
        {
                "alang": "gre",
                "slang": "no"
        },
        {
                "alang": "eng",
                "slang": ["forced", "no"]
        },
	{
		"alang": "*",
		"slang": "eng"
	}
]

A track with the title "Signs and Songs" is selected on my test file, even though both "signs" and "songs" are in the blacklist.

please help me configure it

did I put the setup file correctly? I didn't know exactly where
"C:\Program Files\MPV\mpv\script-opts\sub-select.json"

I watch anime, so here's how to make it so that the Japanese audio track selects the titles of the subtitles that I entered?
and can I make it so that an audio track with a specific name is selected, regardless of the title of the subtitles?
for example, I have an audio track from wakanim and crunchyroll in the video, how do I get the script to select crunchyroll? if it is 2 in the list?
I copied the settings file to different folders but the script doesn't work,

[

{
    "alang": "*",
    "slang": ["*"],
    "blacklist": [ "Надписи" ]
},
{
    "alang": "*",
    "slang": "*",
    "whitelist": ["Полные"]
}

]

Feature: further simplify config files, optimize priority logic

At present, the following config are required to achieve accurate priority:

[
    {
        "alang": "j[ap]n?",
        "slang": ["chi", "und"],
        "whitelist": ["chs&j[ap]n?"]
    },
    {
        "inherit": "^",
        "whitelist": ["sc&j[ap]n?"]
    },
    {
        "inherit": "^",
        "whitelist": ["cht&j[ap]n?"]
    },
    {
        "inherit": "^",
        "whitelist": ["ch&j[ap]n?"]
    },
    {
        "inherit": "^",
        "whitelist": ["tc&j[ap]n?"]
    },
    {
        "inherit": "^",
        "whitelist": ["zh&j[ap]n?"]
    }
]

I hope it can be optimized to the following concise content:

[
    {
        "alang": "j[ap]n?",
        "slang": ["chi", "und"],
        "whitelist": ["chs&j[ap]n?", "sc&j[ap]n?", "cht&j[ap]n?", "ch&j[ap]n?", "tc&j[ap]n?", "zh&j[ap]n?"]
    }
]

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.