feat(tracks): download and mux stereoscopic 3D (MV-HEVC) video to MP4

Mark 3D from REQ-VIDEO-LAYOUT, DV profile 20 codecs or an lhvC box; mux with MP4Box, decrypt with mp4decrypt, skip FFmpeg repack, sample cut and hybrid; add {3d} and env MP4Box.
This commit is contained in:
imSp4rky
2026-11-12 04:47:18 -07:00
parent a28c99b811
commit e29a523907
31 changed files with 513 additions and 67 deletions
+4
View File
@@ -164,6 +164,10 @@ unshackle dl -q 2160 -r HDR10,DV EXAMPLE '...'
The output file of a track with a Dolby Vision profile 8 RPU plays as Dolby Vision on a DV screen.
`--list` adds `3D` to a stereoscopic 3D (MV-HEVC) track, for example `[H.265, DV, 3D]`. When a title
has a 2D and a 3D track at the same resolution, unshackle selects the 2D track. A 3D title muxes to
MP4, see [3D output](output-and-naming.md#3d-output).
!!! warning "HYBRID requires dovi_tool"
`-r HYBRID` makes a single hybrid track by injecting the Dolby Vision RPU
metadata onto an HDR10/HDR10+ base layer with **dovi_tool**.
+20 -1
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, `.mp4` for [DTS:X Profile 2 and MPEG-H audio](#dtsx-profile-2-and-mpeg-h-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).
- **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 and MPEG-H audio](#dtsx-profile-2-and-mpeg-h-output) and [3D video](#3d-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
@@ -110,6 +110,7 @@ Every variable below is valid in both output and folder templates. unshackle tak
| `video` | Video codec | `H.264`, `H.265` |
| `hdr` | Dynamic-range label | `HDR`, `HDR10P`, `DV`, `DV.HDR`, `DV.HDR10P`, `HLG` |
| `hfr` | High frame rate marker (frame rate > 30) | `HFR` |
| `3d` | Stereoscopic 3D marker (MV-HEVC video) | `3D` |
| `edition` | Edition label from the track, if any | `Directors Cut` |
| `tag` | Release-group tag (from `config.tag` or `--tag`) | `TAG` |
| `repack` | `REPACK` when the `--repack` flag is used | `REPACK` |
@@ -429,6 +430,23 @@ An MP4 title loses:
- SubStation Alpha (`.ass`) subtitles
- container tags (`mkvpropedit`)
### 3D output
A stereoscopic 3D (MV-HEVC) video track also muxes to MP4 with MP4Box, because Matroska has no
mapping for its second view and `mkvmerge` drops it. There is no 3D Matroska output. unshackle
finds a 3D track from the manifest, or from a second video layer in the downloaded file. The MP4
title loses the same items as above. For a 3D title, unshackle also:
- decrypts the track with mp4decrypt, whatever [`decryption`](../reference/configuration/drm.md#decryption) selects
- writes QuickTime chapters
- keeps the whole downloaded segments of a `--sample` run, because the MP4Box cut removes the 3D signalling
- does not repack the track or rewrite its colour metadata with FFmpeg
- writes no `--include-sample` sample, because `mkvmerge` cuts only Matroska files
- never uses the track in a `HYBRID` merge
A Dolby Vision profile 20 track has no HDR10 base layer, so a player without Dolby Vision shows
wrong colours.
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"
@@ -475,6 +493,7 @@ The `--no-mux` flag skips muxing entirely and writes the individual track files,
[`--sample`](cli-reference.md#output-muxing-files) and `--include-sample` write a sample into a
`Sample` folder inside the output folder of the title. The sample keeps the filename of the
title, with a `SAMPLE` tag at the end. The tag uses the separator of the output template.
`--include-sample` cuts the sample with `mkvmerge`, so a title that muxes to MP4 gets no sample.
```text title="A movie with --include-sample"
Some.Movie.2026.1080p.EXAMPLE.WEB-DL.H.264-TAG/