From 198d2a9066d7de64ba8f112d6654b7bc87c61111 Mon Sep 17 00:00:00 2001 From: Kayos Date: Sun, 24 May 2026 13:15:19 -0700 Subject: [PATCH] Path C-4 fix: stream_info uses fork's iOS-first default client order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Caught on first emulator smoke: stream_info hardcoded `player_from_clients(&[Android, Ios])` from U-3 era. Android first trips YT's "Precondition check failed" because needs_po_token doesn't flag Android — request fires unsigned and YT rejects it. The fork's audit-fixed player_client_order is [Ios, Tv] without botguard (HIGH-3 in the audit). Use rp.query().player(id) directly so we inherit that order and pick up future tweaks automatically. --- rust/strawcore/src/stream.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/rust/strawcore/src/stream.rs b/rust/strawcore/src/stream.rs index 8f550b7f3..1c28fc2b4 100644 --- a/rust/strawcore/src/stream.rs +++ b/rust/strawcore/src/stream.rs @@ -129,19 +129,15 @@ pub async fn stream_info(url: String) -> Result { log::info!("strawcore::stream_info id={}", id); let rp = RustyPipe::new(); - // rustypipe's default `player()` uses the Web client first, which - // returns signed URLs that need JS deobfuscation. Even the TV (TVHTML5) - // client signs URLs nowadays, so deobfuscation runs and currently - // fails ("could not extract sig fn name") because YT changed the - // obfuscation pattern after rustypipe 0.11.4's last cut. - // - // Android and iOS YT-app clients serve URLs UNSIGNED — no sig - // decryption needed, ExoPlayer plays them directly. This is the same - // path NewPipe uses for its mobile + iOS-embed strategies. - let player = rp - .query() - .player_from_clients(&id, &[ClientType::Android, ClientType::Ios]) - .await?; + // Use the fork's audit-fixed default client order. As of + // v0.11.5-sulkta.2 that's [Ios, Tv] without botguard — iOS first + // because it skips player.js deobfuscation AND doesn't require + // device attestation. Android is intentionally NOT in the default + // order: needs_po_token doesn't flag Android, so unsigned requests + // get YT's "Precondition check failed" / "Sign in to confirm + // you're not a bot" rejection, which is environmental-non-switchable. + // Re-add Android when a real po_token strategy lands. + let player = rp.query().player(&id).await?; let details = &player.details; // Progressive (combined audio+video) goes through video_streams; the