feat(mux): add muxing.default_subtitle_type for the default subtitle

Name which subtitle type (forced, normal, sdh) gets the default flag. The forced default now follows the default audio track, not the first.
This commit is contained in:
imSp4rky
2026-11-10 17:53:14 -07:00
parent d12bf31b6b
commit 2873cf4c53
6 changed files with 166 additions and 19 deletions
+8 -2
View File
@@ -424,7 +424,7 @@ DTS:X Profile 1 is DTS-HD Master Audio and muxes to MKV as usual.
An MP4 title loses:
- the forced, hearing-impaired and original track flags
- the default, forced, hearing-impaired and original track flags
- attachments, such as subtitle fonts
- SubStation Alpha (`.ass`) subtitles
- container tags (`mkvpropedit`)
@@ -447,8 +447,14 @@ muxing:
| `merge_video` | bool | `false` | Group video tracks that share the same resolution, range, and codec into one file so only language varies inside it. |
| `merge_audio` | bool | `true` | Merge audio tracks of the same kind so multiple languages sit in one file. |
| `default_language` | map | *(unset)* | Preferred language per track type (`video` / `audio` / `subtitle`). A track in the preferred language is flagged as the default track. |
| `default_subtitle_type` | str or list | *(unset)* | The subtitle types that can take the default flag, in order: `forced`, `normal`, `sdh` (CC counts as SDH). The first subtitle track of the first type that the title has gets the flag. |
When no track has the preferred language, unshackle applies sensible defaults. The video default falls back to the title language, then the original-language track, then the first track. The audio default is the original-language track. The subtitle default is a forced track in the first audio's language.
When no track has the preferred language, unshackle applies sensible defaults. The video default falls back to the title language, then the original-language track, then the first track. The audio default is the original-language track. The subtitle default is a forced track in the language of the default audio track.
Set `default_subtitle_type` to give the subtitle default to a different type. `default_subtitle_type: normal` with `default_language.subtitle: pl` puts the flag on the full Polish track when the title also has a forced Polish track. Without `default_language.subtitle`, the first track of the type in file order gets the flag, and a forced track counts only in the language of the default audio track. When the title has no track of a listed type, the rules above apply.
!!! tip "Use `normal` for players that read the forced flag"
A forced track always carries the Matroska forced flag. A player that reads it, such as mpv or Jellyfin in its Smart mode, shows the forced track when the audio is in your subtitle language and the default track when it is not. `default_subtitle_type: forced` puts the default flag on the forced track, and such a player then shows it in place of the full track.
!!! note "`default_language` only sets the default-track flag"
`default_language` controls **which track carries the MKV `--default-track` flag**. Nothing else. It does not change track *selection* (that stays with `-l`/`--a-lang` and friends). It also does not touch which track carries the original flag: `--original-flag` still tags the *true* original-audio track. That is the point: you can make your player default to, say, Polish audio on an English-original title without altering the original marker. When the configured language is not present in the manifest, each track type falls back to its normal default rule described above.
+3 -1
View File
@@ -156,7 +156,9 @@ Every subtitle track carries flags describing what kind of captions it holds. Th
flags drive selection, sort order, output filenames, and the Matroska track flags.
- **Forced**: only signs and foreign dialogue, meant to play when the audio language
matches. Off by default. Enable it with `--forced-subs`.
matches. Off by default. Enable it with `--forced-subs`. To choose which type gets the
default flag in the file, set
[`muxing.default_subtitle_type`](../reference/configuration/download.md#muxing).
- **SDH** (Subtitles for the Deaf and Hard-of-Hearing, also called HOH): a full
transcript that includes both dialogue and non-speech sound cues.
- **CC** (Closed Captions): captions originating from an EIA-608/708 broadcast stream,
+13 -7
View File
@@ -236,21 +236,25 @@ subtitle:
`en-GB` falls to the alphabetical tail with the rest. Name each tag you want when you use
that flag.
!!! note "`type_priority` picks the default subtitle only with `muxing.default_language`"
!!! note "`type_priority` alone does not pick the default subtitle"
At mux time the `default` flag goes to every forced subtitle whose language matches the
first audio track, so a full dialogue track never becomes default on its own.
`type_priority` alone does not change that. Name a subtitle language in
[`muxing.default_language`](#muxing) and the first track in that language gets the flag
instead, which is where `type_priority` decides which track that is:
default audio track, so a full dialogue track never becomes default on its own.
`type_priority` changes the order of the tracks in the file. It decides the flag only
between the tracks of one language, when you set `muxing.default_language.subtitle`. Set
[`muxing.default_subtitle_type`](#muxing) to name the type that gets the flag:
```yaml
muxing:
default_subtitle_type: [normal, sdh, forced]
default_language:
subtitle: en
subtitle:
type_priority: [normal, sdh, forced]
```
Here the flag goes to the full English track, then to the English SDH track when the
title has no full one, then to the forced one. Without `default_language.subtitle`, the
first track of the type in file order gets the flag, in any language. A forced track is
the exception: it gets the flag only in the language of the default audio track.
## `audio`
- **Type:** `dict`  ·  **Default:** `{}`
@@ -287,6 +291,7 @@ Matroska (MKV) muxing options.
|---------|------|---------|-------------|
| `set_title` | bool | `true` | Write a human-readable title into the MKV container. |
| `default_language` | dict | `{}` | Force which language is flagged *default* per track type, e.g. `{audio: en, subtitle: en}`. A tag with a region, such as `en-US`, matches only that variant. |
| `default_subtitle_type` | str or list | unset | The subtitle types that can take the *default* flag, in order: `forced`, `normal`, `sdh` (CC counts as SDH, and `cc` is the same as `sdh`). The first subtitle track of the first type that the title has gets the flag. With `default_language.subtitle`, only the tracks in that language count. unshackle ignores a different word with a warning. `normal` is the value for players that read the forced flag. Read [Muxing](../../guide/output-and-naming.md#muxing-options). |
| `merge_audio` | bool | `true` | Merge all audio into one file. `--split-audio` on the CLI flips this off. |
| `merge_video` | bool | `false` | Merge video tracks that share height, range, and codec into one file, so only language varies inside a file. `--merge-video` on the CLI flips this on. |
| `track_names` | str | `english` | The language of the name unshackle gives a track that the service left unnamed: `english` (`Chinese (Traditional)`), `native`, the name in the language itself (`中文(繁體)`), or `none`, which leaves the track unnamed. Read [Track names and language tags](../../guide/output-and-naming.md#track-names-and-language-tags). |
@@ -300,6 +305,7 @@ muxing:
default_language:
audio: en
subtitle: en
default_subtitle_type: normal
```
## `language_tags`