Smoke-tested against current YT player c2f7551f (May 2026):
test ios_player_returns_streams ........... ok
test default_client_order_returns_streams . ok (audio Range-GET 206 Partial Content, 1024 bytes)
test tv_player_returns_streams ............ ok (or env-skipped on IP-banned egress)
Fork changes since upstream v0.11.4:
- client::ClientType::needs_deobf: skip player.js deobf for Android too
- client::player::player_client_order: prefer iOS first (no botguard),
iOS/Android/Tv/Desktop (with botguard)
- deobfuscate::DeobfData::extract_fns: soft-fail sig_fn/nsig_fn extraction
so Tv/Desktop callers keep working when YT rotates player.js to a shape
our regex doesn't recognise — only the load-bearing sig_timestamp is
required for the request payload
- tests/sulkta_smoke.rs: end-to-end sanity covering iOS, Tv, default-order
and a Range-GET probe to confirm YT actually serves the audio bytes
YouTube googlevideo CDN 403s HEAD requests + 403s requests with a
non-client User-Agent. Use the iOS client UA on the probe so the CDN
treats it as the same client that requested the URL.
Exercises the patched default client_order + soft-fail DeobfData
end-to-end against current YouTube. Verifies:
1. iOS player_from_client returns streams (no deobf path).
2. TV player_from_client returns streams (deobf path with soft-fail).
3. default-clients player() picks iOS primary and a returned audio
URL HEADs to a 2xx/3xx (i.e. YouTube CDN accepts it).
Lives alongside the upstream tests/youtube.rs so we don't fork their
big snapshot-based test suite, but stays standalone so a single
`cargo test --test sulkta_smoke` exercises just the load-bearing
playback path for our consumers (straw, future torttube).