1. Overview

mpv is a versatile open-source media player with support for a variety of different platforms and formats. Additionally, mpv has a built-in feature for loading and playing subtitles automatically.

In this tutorial, we’ll learn how to automatically load and play subtitles with mpv. We’ll start by utilizing simple mpv command line options to accomplish this task. Then, we’ll go over more complex features that require some configuration modifications and scripting.

2. Supported Subtitle Formats in mpv

While mpv supports many subtitle formats, it doesn’t provide documentation on what exact formats are supported.

However, since mpv uses the ffmpeg suite to provide subtitles, we can look in the ffmpeg documentation to find a list of supported formats.

In particular, we can find a list of valid subtitle file extensions by looking in the options/options.c file in the mpv source code. Currently, this includes .ass, .idx, .lrc, .mks, .pgs, .rt, .sbv, .scc, .smi, .srt, .ssa, .sub, .sup, .utf, .utf-8, .utf8, and .vtt.

3. How mpv Finds and Loads Subtitles

mpv has multiple ways to find and load subtitles automatically. One of those options is –sub-auto, which configures how mpv finds external subtitle files. This option is fairly easy to use, but the least flexible of the methods we discuss.

We can pass help with certain options in mpv to output information about them, for example, mpv –sub-auto=help:

$ mpv --sub-auto=help
Valid values for option sub-auto are:
    no
    exact
    fuzzy
    all

Now, let’s go through what each of the values for –sub-auto means:

  • no: disables automatic subtitle playing, requiring us to manually provide the file with –sub-file
  • exact (default): loads subtitle files with the matching filename of the video (i.e., videoname.srt)
  • fuzzy: loads subtitle files containing the filename of the video (i.e., subtitle_videoname_english.srt)
  • all: loads all subtitles in the current directory and any additional directories specified by –sub-file-paths

Since fuzzy only needs to contain the video filename, it’s typically the best option to use for most situations. However, it might occasionally pick incorrect subtitles:

$ mpv --sub-auto=fuzzy star_wars_i.webp
...
     Subs  --sid=1 'star_wars_i.vtt' (webvtt) (external)
     Subs  --sid=2 'star_wars_ii.vtt' (webvtt) (external)
...

As we can see, both star_wars_i.vtt and star_wars_ii.vtt contain the name of the video file. In this circumstance, it would be best to utilize –sub-auto=exact or provide the subtitle explicitly.

4. Automatically Playing Subtitles in mpv

Loaded subtitle tracks don’t play automatically in mpv. However, we can change this behavior with the –sid (subtitle ID) flag.

Let’s get a list of valid values with –sid=help:

$ mpv --sid=help
Valid values for option sid are:
    no
    auto
    0-8190 (integer range)

Now, we can go over what each of these does:

  • no: disables automatically play subtitles
  • auto (default): automatically play subtitles that match the language and audio track
  • 0-8190: automatically play the subtle track with ID beginning with 0 for disabled, 1 for first subtitle track, and continuing from there

After we have an idea of what each value does, let’s run mpv –sid=1 so that loaded subtitles always play automatically:

$ mpv --sid=1 my_video.mp4

In this example, we set –sid=1, ensuring that the first loaded subtitle track plays automatically.

5. Using mpv Configuration File

Another way we can play subtitles automatically with mpv is by adjusting the configuration file.

Typically, mpv configuration files are located at:

  • ~/.config/mpv/mpv.conf for local configuration
  • /etc/mpv.conf or /user/local/etc/mpv/mpv.conf for global configuration

Let’s modify our local configuration file to make –sub-auto=fuzzy the default behavior. Then, we add the subtitles local directory to the list of directories mpv looks in. We should also set the —**sid option to ensure loaded subtitles play automatically:

# ~/.config/mpv/mpv.conf
sid=1
sub-auto=fuzzy
sub-file-paths=subtitles

Now, all subtitle files in the current /video/path/subtitles and the ~/.config/mpv/subtitles directories automatically load if they contain the video filename. Additionally, the first subtitle track now plays automatically.

6. Custom Script

Although mpv is decent at recognizing and playing subtitles automatically, it’s still reliant on a limited set of subtitle extensions. Instead of depending on mpv to detect and play subtitles on its own, we can create a custom script to detect subtitles more intelligently.

6.1. Installing Dependencies

Before we can begin creating our script, we need to install the necessary dependencies. The command we’ll use to detect subtitles is mimetype, as provided by the File-MimeInfo Perl module.

On Debian-based distributions, this module is packaged as libfile-mimeinfo-perl. Let’s go ahead and install it now using apt:

$ sudo apt install libfile-mimeinfo-perl

Now that we have the libfile-mimeinfo-perl package installed, we should be able to use the mimetype command.

6.2. Creating the Script

After installing the necessary dependencies, we can create our script:

$ cat mympv.sh
#!/bin/bash
subtitle_formats=('application/x-subrip'   'application/ttml'       'application/xml'
                  'application/ttml+xml'   'text/vtt'               'application/x-sami'
                  'text/x-mpsub'           'text/x-ssa'             'text/x-subviewer'
                  'image/subtitle'         'text/x-microdvd'        'text/x-mpl2')

get_subs() {
    while IFS= read -r -d $'\0' i; do
        file_format="$(mimetype --output-format='%m' -M "${i}" 2>/dev/null)"
        for j in "${subtitle_formats[@]}" ; do
            if [[ "${file_format}" = "${j}" ]] && [[ "${i%%.*}" =~ "${1%%.*}" ]] ; then
                echo -n "${i}:"
            fi
        done
    done < <(find "${PWD}" -maxdepth 1 -type f -print0)
}

custom_mpv() {
    mpv --sub-auto='no' --sid=1 --sub-files="$(get_subs "${1}")" "${1}"
}

custom_mpv "${1}"

At the beginning of our script, we create the subtitle_formats array, containing a list of subtitle MIME types we want to automatically load. Then, we define the function get_subs that prints files in the current directory matching two criteria:

  • MIME type defined within subtitle_formats
  • filename that contains the name of the video file

Finally, we have our function custom_mpv that takes the output files of get_subs and passes them to mpv.

6.3. Running the Script

Before we can run our script, we need to make sure it’s executable using chmod:

$ chmod +x mympv.sh

After this, we can run our script with the video file we want to play:

$ ./mympv.sh "video.webm"

To make our script globally accessible, we can either add it to our ~/.local/bin/ directory or as an alias in our ~/.bashrc.

6.4. Adding Subtitle Formats to Script

Since mpv may add support for additional subtitles, we might need to add to our list subtitle_formats. However, before we can add a subtitle format, we need to find its MIME type:

$ mimetype --output-format='%m' -M mysubtitle
text/utf-8

Next, we can simply copy and paste the outputted MIME type into our script:

# mympv.sh
subtitle_formats=('application/x-subrip'   'application/ttml'       'application/xml'
                  'application/ttml+xml'   'text/vtt'               'application/x-sami'
                  'text/x-mpsub'           'text/x-ssa'             'text/x-subviewer'
                  'image/subtitle'         'text/x-microdvd'        'text/x-mpl2'
                  'text/utf-8')  # <---ADDED

In addition to adding MIME types to our script, we can remove them just as easily.

7. Conclusion

In this article, we learned how to load and play subtitles in mpv automatically.

We first went over methods using the options and configuration file provided by mpv. Then, we created a custom script that allowed for better detection of valid subtitle formats.