feat(dl): add --worst flag and SHIELD OkHttp fingerprint preset

Add --worst CLI flag to select the lowest bitrate video track within a specified resolution (e.g. --worst -q 720). Requires -q/--quality.
Add shield_okhttp TLS fingerprint preset for NVIDIA SHIELD Android TV with OkHttp 4.11 JA3 signature.
This commit is contained in:
Andy
2026-03-11 13:59:07 -06:00
parent c82bb5fe34
commit e02aa66843
2 changed files with 46 additions and 28 deletions

View File

@@ -506,6 +506,12 @@ class dl:
@click.option(
"--reset-cache", "reset_cache", is_flag=True, default=False, help="Clear title cache before fetching."
)
@click.option(
"--worst",
is_flag=True,
default=False,
help="Select the lowest bitrate track within the specified quality. Requires -q/--quality.",
)
@click.option(
"--best-available",
"best_available",
@@ -991,6 +997,7 @@ class dl:
no_mux: bool,
workers: Optional[int],
downloads: int,
worst: bool,
best_available: bool,
split_audio: Optional[bool] = None,
*_: Any,
@@ -1016,6 +1023,10 @@ class dl:
self.log.error("--require-subs and --s-lang cannot be used together")
sys.exit(1)
if worst and not quality:
self.log.error("--worst requires -q/--quality to be specified")
sys.exit(1)
if select_titles and wanted:
self.log.error("--select-titles and -w/--wanted cannot be used together")
sys.exit(1)
@@ -1609,20 +1620,18 @@ class dl:
for resolution, color_range, codec in product(
quality or [None], non_hybrid_ranges, vcodec or [None]
):
match = next(
(
t
for t in non_hybrid_tracks
if (
not resolution
or t.height == resolution
or int(t.width * (9 / 16)) == resolution
)
and (not color_range or t.range == color_range)
and (not codec or t.codec == codec)
),
None,
)
candidates = [
t
for t in non_hybrid_tracks
if (
not resolution
or t.height == resolution
or int(t.width * (9 / 16)) == resolution
)
and (not color_range or t.range == color_range)
and (not codec or t.codec == codec)
]
match = candidates[-1] if worst and candidates else next(iter(candidates), None)
if match and match not in non_hybrid_selected:
non_hybrid_selected.append(match)
@@ -1632,20 +1641,18 @@ class dl:
for resolution, color_range, codec in product(
quality or [None], range_ or [None], vcodec or [None]
):
match = next(
(
t
for t in title.tracks.videos
if (
not resolution
or t.height == resolution
or int(t.width * (9 / 16)) == resolution
)
and (not color_range or t.range == color_range)
and (not codec or t.codec == codec)
),
None,
)
candidates = [
t
for t in title.tracks.videos
if (
not resolution
or t.height == resolution
or int(t.width * (9 / 16)) == resolution
)
and (not color_range or t.range == color_range)
and (not codec or t.codec == codec)
]
match = candidates[-1] if worst and candidates else next(iter(candidates), None)
if match and match not in selected_videos:
selected_videos.append(match)
title.tracks.videos = selected_videos

View File

@@ -44,6 +44,17 @@ FINGERPRINT_PRESETS = {
"akamai": "4:16777216|16711681|0|m,p,a,s",
"description": "OkHttp 5.x (BoringSSL TLS stack)",
},
"shield_okhttp": {
"ja3": (
"771," # TLS 1.2
"4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53," # Ciphers (OkHttp 4.11)
"0-23-65281-10-11-35-16-5-13-51-45-43-21," # Extensions (incl padding ext 21)
"29-23-24," # Named groups (x25519, secp256r1, secp384r1)
"0" # EC point formats
),
"akamai": "4:16777216|16711681|0|m,p,a,s",
"description": "NVIDIA SHIELD Android TV OkHttp 4.11 (captured JA3)",
},
}