feat(audio): support DTS:X Profile 2 with MP4 muxing

Route titles with a dtsx/dtsy sample entry to MP4 via MP4Box, since Matroska has no CodecID for DTS-UHD. Add per-rendition HLS audio codec selection, fix merge_segments progress and its cleanup path.
This commit is contained in:
imSp4rky
2026-09-04 14:19:29 -06:00
parent b391ffc80a
commit 235839abc8
21 changed files with 1020 additions and 40 deletions
+1 -1
View File
@@ -432,7 +432,7 @@ Make a download job. It requires `service` and `title_id`. Every other field is
| `output_dir` | string | `null` | Override output directory. |
| `no_cache` / `reset_cache` | boolean | `false` | Title cache controls. |
**Validation.** Invalid values return `400 INVALID_PARAMETERS`. `vcodec` must be one of H264/H265/H.264/H.265/AVC/HEVC/VC1/VC-1/VP8/VP9/AV1. `acodec` must be one of AAC/AC3/EC3/EAC3/DD/DD+/AC4/OPUS/FLAC/ALAC/VORBIS/OGG/DTS. `range` must be one of SDR/HDR10/HDR10P/DV/HLG/HYBRID, and `HDR10+` is also valid. The bitrate, download worker, and download counts must be positive integers. You may set at most one of the `*_only` flags. You cannot combine `no_subs` with `subs_only`, or `no_audio` with `audio_only`.
**Validation.** Invalid values return `400 INVALID_PARAMETERS`. `vcodec` must be one of H264/H265/H.264/H.265/AVC/HEVC/VC1/VC-1/VP8/VP9/AV1. `acodec` must be one of AAC/AC3/EC3/EAC3/DD/DD+/AC4/OPUS/FLAC/ALAC/VORBIS/OGG/DTS/DTSX/DTS-X. `range` must be one of SDR/HDR10/HDR10P/DV/HLG/HYBRID, and `HDR10+` is also valid. The bitrate, download worker, and download counts must be positive integers. You may set at most one of the `*_only` flags. You cannot combine `no_subs` with `subs_only`, or `no_audio` with `audio_only`.
**Service options.** A service's own CLI options travel in the same body. Send them in a nested
`service_params` object, or as flat top-level keys. `service_params` wins over a flat key of the
+1 -1
View File
@@ -282,7 +282,7 @@ closed-caption descriptors. The relevant enums:
`Audio` adds `bitrate`, `channels`, `joc` (Joint Object Coding, the Atmos indicator),
and `descriptive`. `Audio.Codec` covers `AAC`, `AC3` (`DD`), `EC3` (`DD+`), `AC4`,
`OPUS`, `OGG` (Vorbis), `DTS`, `ALAC`, and `FLAC`. The `atmos` property is `True` when
`OPUS`, `OGG` (Vorbis), `DTS`, `DTSX`, `ALAC`, and `FLAC`. The `atmos` property is `True` when
`joc` is set (or when `extra` flags it).
### `Subtitle`
+5
View File
@@ -124,6 +124,7 @@ download. For example, `dovi_tool` only matters if you download Dolby Vision vid
| Tool | Binary looked up | Why it is needed |
| --- | --- | --- |
| Bento4 (`mp4decrypt`) | `mp4decrypt` | Alternative DRM decryptor to shaka-packager |
| MP4Box (GPAC) | `MP4Box` | Muxing DTS:X Profile 2 (DTS-UHD) audio |
| dovi_tool | `dovi_tool` | Dolby Vision metadata handling |
| HDR10Plus_tool | `hdr10plus_tool` | HDR10+ metadata handling |
| SubtitleEdit | `seconv`, `SubtitleEdit` | Subtitle conversion (the `SeConv` CLI from 5.x) |
@@ -135,6 +136,10 @@ download. For example, `dovi_tool` only matters if you download Dolby Vision vid
| Docker | `docker` | Gluetun VPN proxy support |
| Git | `git` | Fetching and updating remote service repositories |
!!! info "MP4Box is only used for DTS:X Profile 2"
Titles with DTS:X Profile 2 (DTS-UHD) audio mux to MP4; everything else muxes to MKV
with `mkvmerge`. Install with `apt install gpac`.
!!! tip "SubtitleEdit specifics"
unshackle looks for `seconv` first, the batch CLI shipped with
SubtitleEdit 5.x, before falling back to a `SubtitleEdit` (4.x) binary. The
+1 -1
View File
@@ -70,7 +70,7 @@ unshackle dl [OPTIONS] SERVICE [SERVICE ARGS...]
| `-p`, `--profile` | - | Profile for credentials and cookies. |
| `-q`, `--quality` | best | Resolution(s), comma-separated, e.g. `1080,720`. `-q 1080` also matches anamorphic tracks by 16:9 canvas. |
| `-v`, `--vcodec` | any | Video codec(s). Accepts names or values: `AVC`/`H.264`, `HEVC`/`H.265`, `VC1`, `VP8`, `VP9`, `AV1`. |
| `-a`, `--acodec` | any | Audio codec(s), comma-separated. Accepts `AAC`, `AC3`/`DD`, `EC3`/`DD+`/`eac3`/`ddp`, `AC4`, `OPUS`, `OGG`/`vorbis`, `DTS`, `ALAC`, `FLAC`. |
| `-a`, `--acodec` | any | Audio codec(s), comma-separated. Accepts `AAC`, `AC3`/`DD`, `EC3`/`DD+`/`eac3`/`ddp`, `AC4`, `OPUS`, `OGG`/`vorbis`, `DTS`, `DTSX`/`DTS-X`, `ALAC`, `FLAC`. |
| `-vb`, `--vbitrate` | highest | Exact video bitrate in kbps. |
| `-ab`, `--abitrate` | highest | Exact audio bitrate in kbps. |
| `-vb-range`, `--vbitrate-range` | - | Video bitrate range in kbps, e.g. `6000-7000`; picks highest within. Mutually exclusive with `--vbitrate`. |
+1
View File
@@ -215,6 +215,7 @@ bitrate for the top renditions, overriding the manifest value:
| `OPUS` | `OPUS` | Opus |
| `OGG` | `VORB` | Vorbis |
| `DTS` | `DTS` | DTS |
| `DTSX` | `DTS-X` | DTS:X Profile 2 (DTS-UHD) |
| `ALAC` | `ALAC` | Apple Lossless |
| `FLAC` | `FLAC` | FLAC |
+22 -4
View File
@@ -15,7 +15,7 @@ When a download finishes, unshackle builds the final path from three pieces:
- **Output directory**: `directories.downloads` from your config, or whatever you pass to `-o/--output` on the command line for a single run.
- **Folder template**: an optional per-title subfolder. unshackle **always** puts TV episodes and songs in a folder. Movies only get one if you define a `movies` folder template, or a single-string `folder` template that applies to all title kinds (see [Folder templates](#folder-templates)).
- **Filename template**: the `output_template` for the title kind (movie, series, or song).
- **Extension**: chosen by the muxer for a movie or an episode: `.mkv` for video, `.mka` for audio-only, `.mks` for subtitle-only. unshackle does not mux a song. It remuxes a song into the container of its codec, such as `.flac`, `.opus`, or `.m4a`. Read [Music output files](#music-output-files).
- **Extension**: chosen by the muxer for a movie or an episode: `.mkv` for video, `.mka` for audio-only, `.mks` for subtitle-only, `.mp4` for [DTS:X Profile 2 audio](#dtsx-profile-2-output). unshackle does not mux a song. It remuxes a song into the container of its codec, such as `.flac`, `.opus`, or `.m4a`. Read [Music output files](#music-output-files).
!!! example "A typical episode path"
```text
@@ -163,9 +163,9 @@ For custom templates there is also a standalone [`{part}`](../reference/configur
| Variable | Meaning | Example |
|---|---|---|
| `audio` | Audio codec | `DDP`, `DD`, `AAC` |
| `audio_channels` | Channel layout | `5.1`, `2.0` |
| `audio_full` | Codec + channels combined | `DDP5.1` |
| `audio` | Audio codec | `DDP`, `DD`, `AAC`, `DTS-X` |
| `audio_channels` | Channel layout; bed.LFE.heights when the track has height channels | `5.1`, `2.0`, `5.1.4` |
| `audio_full` | Codec + channels combined | `DDP5.1`, `DTS-X.5.1.4` |
| `atmos` | `Atmos` when any track carries JOC | `Atmos` |
| `dual` | `DUAL` for two audio languages (see [`dual_multi_mode`](../reference/configuration/download.md#dual_multi_mode)) | `DUAL` |
| `multi` | `MULTi` for more than two audio languages | `MULTi` |
@@ -277,6 +277,24 @@ warning and continues.
## Muxing options
!!! note "Height channels"
A track with height channels is named bed.LFE.heights, such as `5.1.4`.
### DTS:X Profile 2 output
A title whose audio holds a `dtsx` or `dtsy` sample entry (DTS:X Profile 2, DTS-UHD) muxes
to MP4 with [MP4Box](../getting-started/installation.md), because Matroska has no CodecID
for it. Without MP4Box installed the mux stops.
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
- attachments, such as subtitle fonts
- SubStation Alpha (`.ass`) subtitles
- container tags (`mkvpropedit`)
You configure muxing (the combination of video, audio, subtitle, chapter and attachment tracks into a single Matroska file with `mkvmerge`) under the `muxing` config key. unshackle muxes only movies and episodes. Read [Music output files](#music-output-files) for what a music download does instead.
```yaml title="unshackle.yaml"
+1 -1
View File
@@ -38,7 +38,7 @@ at a title and it will:
| Manifests | DASH, HLS, and Smooth Streaming (ISM) |
| DRM | Widevine and PlayReady, with ClearKey support |
| Video | AVC, HEVC, VC-1, VP8, VP9, AV1; SDR, HLG, HDR10, HDR10+, Dolby Vision, and Dolby Vision **hybrid** merging |
| Audio | AAC, AC-3, E-AC-3, AC-4, Opus, Vorbis, DTS, ALAC, FLAC; Dolby Atmos handling; per-channel-layout selection |
| Audio | AAC, AC-3, E-AC-3, AC-4, Opus, Vorbis, DTS, DTS-X, ALAC, FLAC; Dolby Atmos handling; per-channel-layout selection |
| Subtitles | SRT, WebVTT, ASS/SSA, TTML and more, with optional SDH stripping and format conversion |
| Key vaults | SQLite, MySQL, and HTTP/API vaults to store and share content keys |
| Proxies | Basic proxies plus NordVPN, ProtonVPN, Surfshark, Windscribe, ExpressVPN, Gluetun, and Hola providers |