From 63d010e3aa29c20e02b1b7c7006e79e74140c59b Mon Sep 17 00:00:00 2001 From: houssemko Date: Fri, 18 Sep 2026 10:16:19 +0100 Subject: [PATCH 1/2] Prefer taller in-cap HLS variant over shorter muxed adoption --- src/video.rs | 51 ++++++++++++++++++++++++++--- src/video_tests.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 4 deletions(-) diff --git a/src/video.rs b/src/video.rs index 443b773da..87f72e3ec 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1464,6 +1464,15 @@ fn select_muxed_format(formats: &[Format], want: Option) -> Option Option { + formats + .iter() + .find(|f| f.format_id == id) + .and_then(|f| f.video_resolution.height.filter(|&h| h > 0)) +} + /// Stored quality value to a height cap: `None` (Best) takes the /// tallest variant available. fn quality_height(value: &str) -> Option { @@ -2017,7 +2026,9 @@ struct StreamPlan { /// resolved, for satisfied audio-only requests, and when a video /// request already holds both splits. /// 4. The HLS preset stays a last resort for rows with no direct audio -/// (a muxed adoption above takes precedence when it found a file). +/// (a muxed adoption above takes precedence when it found a file), +/// except when the preset is taller yet within the cap: Best match +/// means best across transports, not best direct file. fn plan_streams( video: &Video, quality: &str, @@ -2073,6 +2084,10 @@ fn plan_streams( // so storyboards and manifests can never adopt here. let mut audio_only = audio_only_request; let mut single_adopted = false; + // Pre-adoption audio: restored if the HLS override below fires, so + // a shadowed adoption never leaks its single-part mode into the + // HLS path. + let pre_audio_sel = audio_sel.clone(); if pinned_hls.is_none() && (audio_sel.is_none() || video_sel.is_none()) && (!audio_only_request || audio_sel.is_none()) @@ -2115,11 +2130,39 @@ fn plan_streams( // directly fetchable, but manifest variants exist. A resolved pin // wins outright; otherwise the preset only runs when no direct // audio survived (a muxed adoption above takes precedence). + // Best-overall override: when the adoption took a muxed file + // shorter than an in-cap HLS variant (x.com direct files top out + // below the tallest variant), the variant wins — Best match must + // mean best across transports, not best direct file. Ties and + // over-cap variants keep the direct file. + let hls_preset = if audio_only_request { + None + } else { + select_hls_format(&video.formats, quality_height(quality)) + }; + let mut hls_wins = false; + if !audio_only_request + && pinned_hls.is_none() + && single_adopted + && let (Some(preset), Some(muxed_h)) = ( + hls_preset.as_ref(), + audio_sel + .as_ref() + .and_then(|s| format_height(&video.formats, &s.format_id)), + ) + && let Some(preset_h) = preset.height + && preset_h > muxed_h + && quality_height(quality).is_none_or(|cap| preset_h <= cap) + { + hls_wins = true; + audio_sel = pre_audio_sel; + audio_only = audio_only_request; + } let hls_sel: Option = pinned_hls.or_else(|| { - if audio_sel.is_some() { - None + if hls_wins || audio_sel.is_none() { + hls_preset.clone() } else { - select_hls_format(&video.formats, quality_height(quality)) + None } }); StreamPlan { diff --git a/src/video_tests.rs b/src/video_tests.rs index 992515cd2..a5fd0c664 100644 --- a/src/video_tests.rs +++ b/src/video_tests.rs @@ -2556,3 +2556,83 @@ fn resolve_hls_input_prefers_binary_dump() { assert_eq!(input.referer.as_deref(), Some("https://www.tiktok.com/")); let _ = std::fs::remove_dir_all(&dir); } + +// ── best-overall muxed vs HLS ──────────────────────────────────────── + +/// Direct muxed files top out below the tallest HLS variant (the +/// x.com shape that Best match undershot before the override). +fn muxed_below_hls_video() -> yt_dlp::model::Video { + test_video(serde_json::json!([ + test_format_full( + "m320", + "avc1.64001f", + "mp4a.40.2", + Some(320), + None, + "https", + false + ), + test_format_full( + "m720", + "avc1.64001f", + "mp4a.40.2", + Some(720), + None, + "https", + false + ), + test_format_full( + "h480", + "avc1", + "mp4a.40.2", + Some(480), + None, + "m3u8_native", + false + ), + test_format_full( + "h1080", + "avc1", + "mp4a.40.2", + Some(1080), + None, + "m3u8_native", + false + ), + ])) +} + +#[test] +fn plan_best_prefers_taller_hls_over_muxed() { + let video = muxed_below_hls_video(); + let plan = plan_streams(&video, "best", false, None, true, 1); + assert!(plan.video_sel.is_none()); + assert!(plan.audio_sel.is_none(), "adoption yields to the variant"); + assert!(!plan.audio_only); + assert_eq!(plan.hls_sel.expect("hls wins").height, Some(1080)); +} + +#[test] +fn plan_cap_blocks_taller_hls() { + // Capped 720p: the 1080p variant exceeds the cap, so the direct + // 720p file stands. + let video = muxed_below_hls_video(); + let plan = plan_streams(&video, "720p", false, None, true, 1); + assert_eq!(plan.audio_sel.expect("adopted").format_id, "m720"); + assert!(plan.audio_only); + assert!(plan.hls_sel.is_none()); + // Capped 1080p: the variant is within cap and taller, so it wins. + let plan = plan_streams(&video, "1080p", false, None, true, 1); + assert!(plan.audio_sel.is_none()); + assert_eq!(plan.hls_sel.expect("hls wins").height, Some(1080)); +} + +#[test] +fn plan_tie_keeps_direct_muxed() { + // Equal heights: direct-file precedence is unchanged. + let video = x_like_video(); + let plan = plan_streams(&video, "best", false, None, true, 1); + assert_eq!(plan.audio_sel.expect("adopted").format_id, "http-720"); + assert!(plan.audio_only); + assert!(plan.hls_sel.is_none()); +} From bf9cc96f3b735683fac8e536751d2e07607be2fa Mon Sep 17 00:00:00 2001 From: houssemko Date: Fri, 18 Sep 2026 10:39:25 +0100 Subject: [PATCH 2/2] Repair web-merge damage on best-overall --- src/video.rs | 1 + src/video_tests.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/video.rs b/src/video.rs index 7e5554ba0..b0b031165 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1471,6 +1471,7 @@ fn format_height(formats: &[Format], id: &str) -> Option { .iter() .find(|f| f.format_id == id) .and_then(|f| f.video_resolution.height.filter(|&h| h > 0)) +} /// Default combo selection for a fresh resolve: "Best match" (index /// 0) when the preference is Best, else the listed height closest to /// the preferred one (ties go taller). The combo lists Best first, diff --git a/src/video_tests.rs b/src/video_tests.rs index 3f1c0a01d..791861ba8 100644 --- a/src/video_tests.rs +++ b/src/video_tests.rs @@ -2635,6 +2635,8 @@ fn plan_tie_keeps_direct_muxed() { assert_eq!(plan.audio_sel.expect("adopted").format_id, "http-720"); assert!(plan.audio_only); assert!(plan.hls_sel.is_none()); +} + // ── default combo selection ────────────────────────────────────────── fn test_options() -> Vec {