feat(tracks): support HDR Vivid and Audio Vivid

Add Video.Range.VIVID and Audio.Codec.AV3A, found by the first-segment probe (CUVA SEI, MPEG-TS cuvv/AVSA/0xD5); sort videos by standard resolution, then bitrate; drop service names left in core and tests. Closes #179
This commit is contained in:
imSp4rky
2026-11-14 22:03:13 -07:00
parent 7a5ad5024a
commit 856a193061
26 changed files with 365 additions and 96 deletions
+8 -1
View File
@@ -38,7 +38,7 @@ Common config keys. This is a useful subset, and every `dl` flag works:
| `quality` | list | `[]` (best) | Resolution(s), e.g. `[1080]`. |
| `vcodec` | list | `[]` (any) | Video codec(s), e.g. `[H265]`. |
| `acodec` | list | `[]` (any) | Audio codec(s), e.g. `[EC3]`. |
| `range` | list | `["SDR"]` | Colour range(s): `SDR`, `HLG`, `HDR10`, `HDR10P`, `DV`, `HYBRID`. |
| `range` | list | `["SDR"]` | Colour range(s): `SDR`, `HLG`, `HDR10`, `HDR10P`, `VIVID`, `DV`, `HYBRID`. |
| `channels` | float | *(unset)* | Audio channels, e.g. `6` for 5.1. |
| `sub_format` | str | *(unset)* | Convert subtitles to this format (`srt`, `vtt`, `original`, ...). |
| `sub_font` | str | *(unset)* | Font for subtitles converted to ASS; implies `sub_format: ass`. Ignored when `sub_format` is another format. |
@@ -433,6 +433,13 @@ probes the two highest and the two lowest bitrates first:
| Some carry HDR10+ | The title has HDR10 and HDR10+ encodes side by side, so unshackle probes every track. |
| None carry HDR10+ | Every track stays `HDR10`. |
The probe also finds HDR Vivid in HEVC HDR10 and HLG tracks. A track becomes `VIVID`, so
`-r VIVID` selects it, when its first frame carries CUVA HDR Vivid metadata, or when its MPEG-TS
program map table (PMT) has the `cuvv` registration. An HLG track never becomes `HDR10P`. An audio
track with no codec gets its codec from the PMT of an MPEG-TS first segment: the `AVSA`
registration or `stream_type` `0xD5` gives `Audio Vivid`. The probe has no HDR10+ result for an
MPEG-TS track.
A probe that fails, or a fragment whose metadata is encrypted, keeps the label from the service.
unshackle does not probe ISM tracks. Each probe makes one to three small requests: the 64 KiB
fragment, plus the playlist of an HLS track or the header of a one-file track. The probes run in
+2 -2
View File
@@ -144,8 +144,8 @@ Put the more specific rules first, because unshackle stops at the first match.
an HDR10 base layer gives `DV.HDR`, and with an HDR10+ base layer `DV.HDR10P`. Plain `DV`
does **not** match those. Name every variant you want, as the example above does. Note
also that HDR10 gives `HDR`, not `HDR10`, and so does a PQ video track with no HDR10
metadata. The full set of values is `HDR`, `HDR10P`, `DV`, `DV.HDR`, `DV.HDR10P`, and
`HLG`, as listed in the
metadata. The full set of values is `HDR`, `HDR10P`, `DV`, `DV.HDR`, `DV.HDR10P`,
`HDRVivid`, and `HLG`, as listed in the
[variable table](../../guide/output-and-naming.md#template-variables).
### Operators