Smooth Streaming TTML times cues from each fragment's start; a whole track stacked into the first fragment. Also stop rebase_ttml failing on a track with no cues.
DASH reads the AudioChannelConfiguration scheme (Dolby mask, CICP index incl. immersive layouts, channel count); HLS and ISM counts map 6/7/8 to 5.1/6.1/7.1.
DASH no longer drops service-set DRM when the manifest has none, and the WebVTT rebase allows a cue that starts one segment early. --remote also sends single-track manifests matched by track id.
get_tracks_for_variants skips a later manifest's track when a held track has the same signature, so a track whose ID changes per manifest is listed once.
Fix DASH SegmentTimeline negative @r and Pattern, TTML sidecar sets with no contentType, HLS CHANNELS identifiers and Dolby channel masks; test against 408 public DASH/HLS/ISM manifests.
Set muxing.track_names to native to name an unnamed track in its own language (中文(繁體), Português (Portugal)) in place of English. The same script and region rules apply. --list, the muxed names and the REST API track_name follow the option. A test fixture resets the muxing options, so a local unshackle.yaml cannot change test results.
Unnamed tracks get the English language name (default region left out); subtitle tags gain the script their region implies (zh-TW -> zh-Hant-TW). Refs #169
Builds per-scene L1 in unshackle (PQ mean, letterbox-aware) with a generate_dv_mode config (v29/v40/legacy); a failed hybrid no longer exits 0 with no video.
A tag with a region (en-US, es-419) matches only that variant and reports a miss instead of taking another region. A bare tag takes the variant it means (pt -> pt-BR, es -> es-ES) and falls back to any variant only when that one is missing. `orig` prefers the title's own tag, `-sl orig` resolves, forced and SDH subtitles are picked from their own pools, and the track name no longer strips the region from the cached language.
BREAKING CHANGE: -l es-419 no longer selects es-ES, and language_priority, language_tags and muxing.default_language treat a regional tag as exact.
Manifest, licence and auth stay on --proxy; track, subtitle and attachment downloads use the second proxy. Also exposed as proxy_download on the REST download job with the same server_proxy gate. The download session now ignores HTTP(S)_PROXY and copies rnet cookies set by name.
parse_channels rejected a three-figure layout, so a remote download crashed rebuilding the track from JSON. Add channel_total so --channels can compare either form.
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.
An exact height match in one range denied the 16:9 canvas fallback to the others, so a cropped HDR10 or SDR track was dropped whenever an uncropped DV track matched the requested height. Also sweep the hybrid L5 temp files so a killed run cannot leave a stale RPU behind.
Strip cue classes, <v>/<lang>/ruby and karaoke timestamps before conversion, decode entities for SRT/SSA/ASS, load pysubs2 as utf-8-sig, and route sdh_method: filter-subs through convert_before_strip instead of raising.
Renames 314 defs and 41 module/class-level constants. Keeps 11 names underscored where the stripped form collides in scope, plus 5.5.0 shims for the three symbols external service repos call.
Catch the branch up with dev (45 commits) so testers can run the perf work
against current dev.
Conflict resolutions:
- downloaders/requests.py: keep the branch's racing-gated read1, adaptive
controller speed reporting and byte-range slice guards; take dev's
content-encoding checks (raw reads are skipped on an encoded body) and its
rolling SpeedWindow for the no-controller speed fallback. The single-URL
ranged-parallel gate now requires no speed limit and no caller Range.
- service.py / session.py: keep the branch's TimeoutHTTPAdapter and retry
config, raise POOL_MAX_SIZE to 64 so dev's pool-starvation fix survives
(pool_block=True stalls threads on a pool smaller than the in-flight count).
- docs: dev split configuration.md into per-area pages, so the branch's rnet
network option rows moved to reference/configuration/network.md.
sort_subtitles resolved only the all token, while the video and audio sorts
resolved all and best. by_language now asks matching_languages rather than
repeating the RFC 4647 preference, with no behaviour change.
subtitle.language_priority and audio.language_priority prepend to the CLI
languages, so the named languages sort first and nothing is filtered.
--exact-lang now applies to the sorts too, through matching_languages, which
follows the same RFC 4647 rule as Tracks.by_language and ignores invalid tags.
sort_subtitles applied the language sort before the type sort. Python sorts
are stable, so the last pass wins and type became the major key: every forced
track, then every normal, then every SDH, each block ordered by language. In a
title with many languages this put a track far from its own SDH version, for
example Finnish at track 5 and Finnish SDH at track 42.
Add a group_by parameter that selects the major key. "type" is the default and
keeps the current order byte for byte. "language" swaps the two passes so each
language stays next to its own variants. Read it from the new subtitle.group_by
config key.
Also correct the docs: type_priority was described as sorting the variants
within each language, which was never true. It ranks the types across all
languages.
UNITY_MATRIX emitted 11 int32s instead of 9, oversizing mvhd/tkhd so pymp4 desynced and fTTML subtitles yielded no cues. Also rewrites PIFF senc to CENC so shaka can decrypt Smooth, labels HEV1 as hev1, and raises when a fragment survives decryption still carrying a sample-encryption box.
Detect an encv/enca sample entry surviving decryption (moov-scoped 4CC scan) and force a repack so mkvmerge isn't first-FourCC-locked to a generic encrypted codec; warn if one persists after repacking.
Closes#142
Merge cues at the string level instead of round-tripping through
pycaption, which dropped inline tags and cue settings. STYLE and
REGION blocks are kept, duplicate boundary cues splice correctly,
and a bad timing line now skips the cue instead of crashing.
Also rank pysubs2 above SubtitleEdit for ASS to TTML/VTT since
SubtitleEdit flattens inline styling there. Documented the measured
backend fidelity table and added regression tests for the merge.
Share one best-audio selector across the episode and music paths so best/all works for songs, descriptive audio is capped to one track, and codec_priority is honored. Guard --channels and 16:9 canvas math against tracks missing channel/width metadata. Extend --best-available to video languages and full resolution misses in both normal and hybrid mode, and count only deliverable ranges when reporting missing resolutions. Rank video by resolution before bitrate, and trim group audio selections to one track per song with a warning.
BREAKING CHANGE: a missing resolution with -r HYBRID now errors without --best-available, matching non-hybrid behavior.