Skip to content

fix(youtube): support logged-in age-restricted streams through TV fallback#81

Closed
Priveetee wants to merge 4 commits into
InfinityLoop1308:mainfrom
Priveetee:fix/youtube-age-restricted-tv-fallback
Closed

fix(youtube): support logged-in age-restricted streams through TV fallback#81
Priveetee wants to merge 4 commits into
InfinityLoop1308:mainfrom
Priveetee:fix/youtube-age-restricted-tv-fallback

Conversation

@Priveetee

@Priveetee Priveetee commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Refs InfinityLoop1308/PipePipeClient#70 (comment)

Summary

This fixes the logged-in age-restricted YouTube path I tested after the Android 17 / SABR work.

WEB/MWEB can still return LOGIN_REQUIRED without usable streamingData even when cookies are present. With a real logged-in / age-verified cookie set, the TV downgraded player can return normal direct streams, but it needs the logged-in watch ytcfg state and the correct auth headers.

This adds that fallback and keeps the normal SABR path untouched.

Problem

The failing path looked like this:

WEB/MWEB player response:
LOGIN_REQUIRED
no streamingData

The app then surfaced the normal age-restricted error even though YouTube cookies were configured.

During testing I also found that cookie quality matters a lot here. A partial cookie set still made the app look "logged in" locally, but YouTube returned a signed-out watch page:

no VISITOR_DATA
no SESSION_INDEX
TV player => LOGIN_REQUIRED

With a real logged-in cookie set, the watch page exposes:

LOGGED_IN=true
VISITOR_DATA present
SESSION_INDEX=1

and the TV downgraded player returns usable direct streams.

Changes

  • Fetch the logged-in YouTube watch ytcfg when WEB/MWEB do not provide streams.
  • Read VISITOR_DATA and SESSION_INDEX from the watch page for the TV fallback request.
  • Build the TVHTML5 downgraded player request for logged-in fallback.
  • Send the full logged-in cookie header and YouTube auth headers.
  • Generate all available auth schemes:
    • SAPISIDHASH
    • SAPISID1PHASH
    • SAPISID3PHASH
  • Merge the TV fallback streamingData into the existing player response instead of replacing all metadata.
  • Restore direct stream building for non-SABR formats / adaptiveFormats returned by the TV fallback.
  • Ignore the WEB age-gate error only after the TV fallback actually returned usable streams.

Validation

Build:

  • ./gradlew :extractor:compileJava --no-build-cache --no-configuration-cache --no-daemon
  • ./gradlew :app:assembleDebug --no-build-cache --no-configuration-cache --no-daemon from PipePipeClient with this extractor through includeBuild
  • git diff --check

Local reverse check with the same cookie set:

ytcfg:
LOGGED_IN=true
VISITOR_DATA present
SESSION_INDEX=1

TV downgraded player:
status=OK
formats=1
adaptiveFormats=6
serverAbrStreamingUrl=false

Emulator validation:

Age-restricted playback:

https://www.youtube.com/watch?v=Jrt8nic1UAg

Result:

MediaSession PLAYING(3)
title: مشهد مؤثر لاشتباكات المنطقة الثانية سرت
video decoder: h264
audio decoder: aac

Age-restricted download:

selected: AVC1 720p
postprocessing completed

Final file checked with ffprobe:

video: h264 1280x720
audio: aac
duration: 37.685986
size: 10530427

Normal playback smoke:

https://www.youtube.com/watch?v=lLaRC7GkVR8

Result:

SABR playback reached PLAYING(3)

Notes

This PR is extractor-only.

The client already benefits from this once the extractor returns normal direct streams from the logged-in TV fallback. In my emulator test, playback and download worked with the current client build after substituting this extractor.

This depends on a real logged-in / age-verified YouTube cookie set. A partial cookie set can still contain some YouTube account cookies but fail the age-gate path, and in that case YouTube returns no logged-in watch state and the TV fallback still cannot unlock the video.

I tested that case too while debugging: yt-dlp failed with the partial set and passed with the real logged-in set, matching the app behavior.

@InfinityLoop1308 do you want me to look at the client-side login/cookie UX too, or do you prefer to handle that part? (of course if it is needed)

@InfinityLoop1308

Copy link
Copy Markdown
Owner

🤔 I don't think adding the TV downgraded fallback is the right direction here — non-SABR paths will likely be removed by YouTube soon, and I'd prefer not to add code with a short shelf life.

I noticed the same behavior in my tests. The root cause is stale cookies. Some newer cookie fields aren't being synced from the WebView to stored preferences. The login itself is still valid — logging out and back in (without the WebView session actually being cleared) gives fresh cookies that work fine for age-restricted content.

What's actually needed is cookie validity checking — detecting when stored cookies are stale and prompting the user to re-login. I'm not planning to include that in 5.2.1, but will consider it for a future release.

The SABR main path should already handle logged-in cookies correctly, so this isn't blocking normal usage.

@InfinityLoop1308

Copy link
Copy Markdown
Owner

btw since the sabr topic is going to be finished, if you work on new issues, do you prefer me adding dev side topics in client/extractor or focus on issues reported in main repo?

@Priveetee

Copy link
Copy Markdown
Contributor Author

btw since the sabr topic is going to be finished, if you work on new issues, do you prefer me adding dev side topics in client/extractor or focus on issues reported in main repo?

Honestly, yeah, I think it would be better if you assigned me dev-side topics directly :)

I like talking with users and checking issues too, but sometimes I spend more time figuring out what to work on than actually coding, and then I still need to ask you if the direction makes sense (and it is normal tho)

And to be honest, it can be a bit overwhelming sometimes. I wonder how you handle all of this, lmao 😅

So if you have something in extractor/client, just assign it to me directly, as you can see, I read my emails pretty often :p

I like client too, but I prefer extractor work :p

@Priveetee

Copy link
Copy Markdown
Contributor Author

🤔 I don't think adding the TV downgraded fallback is the right direction here — non-SABR paths will likely be removed by YouTube soon, and I'd prefer not to add code with a short shelf life.

I noticed the same behavior in my tests. The root cause is stale cookies. Some newer cookie fields aren't being synced from the WebView to stored preferences. The login itself is still valid — logging out and back in (without the WebView session actually being cleared) gives fresh cookies that work fine for age-restricted content.

What's actually needed is cookie validity checking — detecting when stored cookies are stale and prompting the user to re-login. I'm not planning to include that in 5.2.1, but will consider it for a future release.

The SABR main path should already handle logged-in cookies correctly, so this isn't blocking normal usage.

Np, I understand your point :)

When I have read the client comment, I extrapolated a bit too much and went straight into the TV fallback path 😂

But yeah, I agree it’s probably not a good idea to add a non-SABR path if we already expect YouTube to remove it soon (and I agree too)

So if I understand correctly, the real thing to handle here would be cookie validity checking: detect when the stored cookies are stale or incomplete, then ask the user to log in again?

@InfinityLoop1308

Copy link
Copy Markdown
Owner

I like talking with users and checking issues too, but sometimes I spend more time figuring out what to work on than actually coding, and then I still need to ask you if the direction makes sense (and it is normal tho)

And to be honest, it can be a bit overwhelming sometimes. I wonder how you handle all of this, lmao 😅

maybe... experience? 😄

So if I understand correctly, the real thing to handle here would be cookie validity checking: detect when the stored > cookies are stale or incomplete, then ask the user to log in again?

yeah but I think it may need more discussion since it's a little bit hard to determine where to place and trigger this logic.

So if you have something in extractor/client, just assign it to me directly, as you can see, I read my emails pretty often :p

I like client too, but I prefer extractor work :p

ok I'll open issues in client/extractor repo later. For now I think the best topic is SABR for post_live / live. it's not urgent but if YT doesn't provide hls for them in the future we can still support them with sabr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants