fix(tracks): honor --worst in hybrid range selection

select_hybrid always picked max-bitrate HDR10 base layer, ignoring the --worst flag. Thread worst through to use min bitrate when requested.
This commit is contained in:
imSp4rky
2026-05-08 15:37:09 -06:00
parent 5984eefcbe
commit 4c981e2ffd
2 changed files with 9 additions and 6 deletions

View File

@@ -1663,7 +1663,7 @@ class dl:
] ]
# Apply hybrid selection to HDR10+DV tracks # Apply hybrid selection to HDR10+DV tracks
hybrid_filter = title.tracks.select_hybrid(hybrid_candidate_tracks, quality) hybrid_filter = title.tracks.select_hybrid(hybrid_candidate_tracks, quality, worst=worst)
hybrid_selected = list(filter(hybrid_filter, hybrid_candidate_tracks)) hybrid_selected = list(filter(hybrid_filter, hybrid_candidate_tracks))
if non_hybrid_ranges and non_hybrid_tracks: if non_hybrid_ranges and non_hybrid_tracks:
@@ -1718,12 +1718,14 @@ class dl:
if not quality: if not quality:
best_resolution = max((v.height for v in hybrid_candidate_tracks), default=None) best_resolution = max((v.height for v in hybrid_candidate_tracks), default=None)
if best_resolution: if best_resolution:
hybrid_filter = title.tracks.select_hybrid(hybrid_candidate_tracks, [best_resolution]) hybrid_filter = title.tracks.select_hybrid(
hybrid_candidate_tracks, [best_resolution], worst=worst
)
hybrid_selected = list(filter(hybrid_filter, hybrid_candidate_tracks)) hybrid_selected = list(filter(hybrid_filter, hybrid_candidate_tracks))
else: else:
hybrid_selected = [] hybrid_selected = []
else: else:
hybrid_filter = title.tracks.select_hybrid(hybrid_candidate_tracks, quality) hybrid_filter = title.tracks.select_hybrid(hybrid_candidate_tracks, quality, worst=worst)
hybrid_selected = list(filter(hybrid_filter, hybrid_candidate_tracks)) hybrid_selected = list(filter(hybrid_filter, hybrid_candidate_tracks))
# For non-hybrid ranges, apply Cartesian product selection # For non-hybrid ranges, apply Cartesian product selection

View File

@@ -316,7 +316,7 @@ class Tracks:
new_tracks.attachments = list(self.attachments) new_tracks.attachments = list(self.attachments)
return new_tracks return new_tracks
def select_hybrid(self, tracks, quality): def select_hybrid(self, tracks, quality, worst: bool = False):
# Prefer HDR10+ over HDR10 as the base layer (preserves dynamic metadata) # Prefer HDR10+ over HDR10 as the base layer (preserves dynamic metadata)
base_ranges = (Video.Range.HDR10P, Video.Range.HDR10) base_ranges = (Video.Range.HDR10P, Video.Range.HDR10)
base_tracks = [] base_tracks = []
@@ -327,12 +327,13 @@ class Tracks:
if base_tracks: if base_tracks:
break break
pick = min if worst else max
base_selected = [] base_selected = []
for res in quality: for res in quality:
candidates = [v for v in base_tracks if v.height == res or int(v.width * 9 / 16) == res] candidates = [v for v in base_tracks if v.height == res or int(v.width * 9 / 16) == res]
if candidates: if candidates:
best = max(candidates, key=lambda v: v.bitrate) chosen = pick(candidates, key=lambda v: v.bitrate)
base_selected.append(best) base_selected.append(chosen)
dv_tracks = [v for v in tracks if v.range == Video.Range.DV] dv_tracks = [v for v in tracks if v.range == Video.Range.DV]
lowest_dv = min(dv_tracks, key=lambda v: v.height) if dv_tracks else None lowest_dv = min(dv_tracks, key=lambda v: v.height) if dv_tracks else None