From 6cefc0c0e5b97b63497a25fd5fd68f56c8634526 Mon Sep 17 00:00:00 2001 From: Luna Date: Mon, 1 Jun 2026 05:25:06 -0700 Subject: [PATCH] Per-channel "skip auth check" toggle for the youtubetab warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit yt-dlp prints a scary-looking ERROR when it can't confirm a channel tab loaded authenticated: ERROR: [youtube:tab] @Channel: Playlists that require authentication may not extract correctly without a successful webpage download… pass "--extractor-args youtubetab:skip=authcheck" to skip this check For PUBLIC channels that's just noise — there's no auth-gated content to miss, and the flag silences it without changing which videos are found. But for members-only/private channels archived with cookies, the warning is a real "your cookies may not be working, you might be getting an incomplete list" signal worth keeping. So make it a per-channel toggle rather than a blanket setting: - DownloadOptions gains `skip_auth_check: bool`; apply() emits `--extractor-args youtubetab:skip=authcheck` when set. (Its own flag; the youtubetab: namespace is distinct from the POT provider's youtubepot-bgutilhttp: one, so they coexist.) - Desktop + web channel-options dialogs gain a checkbox with a tooltip spelling out the public-vs-private trade-off. 1 new test; 81 pass. Co-Authored-By: Claude Opus 4.7 --- src/app.rs | 8 ++++++++ src/download_options.rs | 27 +++++++++++++++++++++++++++ src/web_ui/index.html | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/src/app.rs b/src/app.rs index d96bd4a..f6961a6 100644 --- a/src/app.rs +++ b/src/app.rs @@ -219,6 +219,7 @@ struct ChannelOptionsForm { quality_idx: usize, // 0=default, 1=Best, 2=1080p, 3=720p, 4=480p, 5=360p audio_only: bool, fetch_comments: bool, + skip_auth_check: bool, limit_rate_kb: String, min_filesize_mb: String, max_filesize_mb: String, @@ -440,6 +441,7 @@ impl App { quality_idx, audio_only: opts.audio_only, fetch_comments: opts.fetch_comments, + skip_auth_check: opts.skip_auth_check, limit_rate_kb: num(opts.limit_rate_kb), min_filesize_mb: num(opts.min_filesize_mb), max_filesize_mb: num(opts.max_filesize_mb), @@ -470,6 +472,7 @@ impl App { quality, audio_only: f.audio_only, fetch_comments: f.fetch_comments, + skip_auth_check: f.skip_auth_check, limit_rate_kb: parse_num(&f.limit_rate_kb), min_filesize_mb: parse_num(&f.min_filesize_mb), max_filesize_mb: parse_num(&f.max_filesize_mb), @@ -1904,6 +1907,11 @@ impl App { .on_hover_text("Slow on popular videos. Once captured, comments are browsable from the player modal in the web UI."); ui.end_row(); + ui.label("Skip auth check"); + ui.checkbox(&mut form.skip_auth_check, "Suppress the channel-tab authentication warning") + .on_hover_text("Passes --extractor-args youtubetab:skip=authcheck. Safe for PUBLIC channels — it silences yt-dlp's \"playlists that require authentication may not extract correctly\" warning without changing which videos are found. Leave OFF for members-only/private channels, where that warning signals your cookies may not be working."); + ui.end_row(); + ui.label("Bandwidth cap (KB/s)"); ui.add(egui::TextEdit::singleline(&mut form.limit_rate_kb).desired_width(100.0).hint_text("off")); ui.end_row(); diff --git a/src/download_options.rs b/src/download_options.rs index b20a79d..45efcd7 100644 --- a/src/download_options.rs +++ b/src/download_options.rs @@ -79,6 +79,19 @@ pub struct DownloadOptions { /// When on, the web UI's player modal exposes a Comments tab. #[serde(default)] pub fetch_comments: bool, + + /// Skip yt-dlp's channel-tab authentication sanity check by passing + /// `--extractor-args youtubetab:skip=authcheck`. + /// + /// yt-dlp warns ("Playlists that require authentication may not + /// extract correctly…") when it can't confirm a channel page loaded + /// authenticated. For PUBLIC channels that warning is noise — there's + /// no auth-gated content to miss — so this silences it. Leave OFF for + /// channels where you archive members-only / private content with + /// cookies: there the warning is a real "your cookies aren't working, + /// you may be getting an incomplete list" signal worth keeping. + #[serde(default)] + pub skip_auth_check: bool, } impl DownloadOptions { @@ -129,6 +142,12 @@ impl DownloadOptions { if self.fetch_comments { cmd.arg("--write-comments"); } + if self.skip_auth_check { + // Its own --extractor-args flag; the youtubetab: namespace is + // distinct from the POT provider's youtubepot-bgutilhttp: one, + // so they coexist as separate flags without clobbering. + cmd.arg("--extractor-args").arg("youtubetab:skip=authcheck"); + } } /// Deserialize from the JSON blob stored in `channel_options.options_json`. @@ -182,6 +201,14 @@ mod tests { assert_eq!(args, vec!["--sub-langs", "en,ja,es"]); } + #[test] + fn skip_auth_check_emits_extractor_arg() { + let mut cmd = Command::new("yt-dlp"); + DownloadOptions { skip_auth_check: true, ..Default::default() }.apply(&mut cmd); + let args: Vec = cmd.get_args().map(|a| a.to_string_lossy().into_owned()).collect(); + assert_eq!(args, vec!["--extractor-args", "youtubetab:skip=authcheck"]); + } + #[test] fn audio_only_adds_extract_audio_chain() { let mut cmd = Command::new("yt-dlp"); diff --git a/src/web_ui/index.html b/src/web_ui/index.html index 0a0fd40..e50282b 100644 --- a/src/web_ui/index.html +++ b/src/web_ui/index.html @@ -913,6 +913,9 @@ async function openChannelOptions(idx){
Adds --write-comments. Embeds the comment tree into info.json — slow for popular videos but enables the Comments tab in the player.
+
+
+
Adds --extractor-args youtubetab:skip=authcheck. Safe for public channels — silences the "playlists that require authentication may not extract correctly" warning without changing which videos are found. Leave off for members-only/private channels, where that warning means your cookies may not be working.
@@ -949,6 +952,7 @@ function readChannelOptionsForm(){ quality:q?q:null, audio_only:document.getElementById('opt-audio')?.checked||false, fetch_comments:document.getElementById('opt-comments')?.checked||false, + skip_auth_check:document.getElementById('opt-skipauth')?.checked||false, limit_rate_kb:intOrNull('opt-rate'), min_filesize_mb:intOrNull('opt-minsz'), max_filesize_mb:intOrNull('opt-maxsz'),