Repository navigation
SABR client playback integration (PoC) #42
Description
Activity
@InfinityLoop1308 saw you merged the jdk25 + agp9.2 toolchain (#44), nice, gonna take advantage of it.
and about media3, you brought it up as an option back here (InfinityLoop1308/PipePipeExtractor#66 (comment)) while upgrading the project. honestly with the SABR client work it really seems like a good opportunity to go for it, the player wiring (LoadControl, buffering, the 4K mem stuff) would be way cleaner on media3. i'm down to drive that migration if you're up for it.
I have played Never Gonna Give u Up like a Thousand time im gonna crashout
Completely unrelated just wanted to share
Reacted by InfinityLoop1308small update on SABR. it's 3 PRs now (media3 #45, extractor InfinityLoop1308/PipePipeExtractor#69, client #47), all wip, nothing ready to merge yet.
the black screen when switching videos is fixed, turned out old sessions were lingering and bleeding into the new one. two things still open: seeking doesn't work yet (the current byte-stream source can't really land a seek), and 4K VP9 stalls on my Pixel which smells more like a decoder limit than SABR.
next i'm reworking the SABR side into a proper time-aware MediaSource, which should sort seeking and the switch stuff for good.
update: the sustained-playback stall from the description is fixed.
reworked the SABR source into a proper time-aware chunk MediaSource (media3 ChunkSource / ChunkSampleStream over a SabrChunkSource), so seeking actually lands now (time -> chunk index) and the asymmetric audio/video track stall is gone.
and i finally root-caused the recurring "~2min freeze" (the one i'd blamed on Opus, then the decoder, then the device). the stall detector measured "time since the pump last produced a segment", but the pump legitimately stops producing once it's buffered far enough ahead (throttle), so after ~STALL_MS of healthy throttling the first cache miss false-stalled. fixed by timing the stall per requested segment instead of off the pump's global idle clock. validated on a Pixel 8: full play-through to the end, autoplay kicks in, no stall.
other fixes that landed (all on #47): AAC audio (Opus/webm under-supplies the renderer through this chunk pipeline), respect the user-selected quality instead of forcing the max, PO token cached on disk so an app restart doesn't re-mint the ~45s BotGuard token.
honest remaining: >=1440p won't decode on my Pixel 8 (looks like a real device decoder wall, <=1080p all play fine), and i've only lightly tested network-drop recovery so far.
more updates:
- media3 1.10.1: client moved off 1.4.1 to the latest (feat(player): migrate from ExoPlayer 2.18.7 to media3 1.10.1 #45), adapted the 2 API breaks (LoadControl + ChunkSampleStream), SABR plays fine on it.
- the >=1440p wall isn't us: re-tested on a 2nd device (Galaxy S25, Snapdragon 8 Elite, android 16) and 1440p + 4K decode clean in both vp9 and av1. so the chunk path handles up to 4K; the Pixel 8 (Tensor G3) just can't do >=1440p through this path, a hardware limit. <=1080p works on both devices.
- network recovery validated: a real 60s outage (wifi+data off) -> SABR reloads and resumes. holds up to ~2min (the per-segment wait timeout), past that it gives up cleanly.
- opus/webm audio: still spam-buffers even after the freeze fix, so it's a separate bug, not that one. sticking with AAC.
validation now spans 2 devices / 2 SoCs / android 14 + 16.
quick seek update: big rewinds work now :)
if you rewound past the buffered window it used to just hang forever, the old segments got evicted and the pump only ever fetched forward so it never went back for them. now it re-asks the server for the spot you jumped to and picks back up. short rewinds were already fine thanks to a 30s back-buffer.
also fixed changing quality/codec mid-video, it was sticking on the old format and freezing, now it rebuilds the session clean. tested on my pixel 8 at 1080p, forward seek + small/big rewind + quality switch all good. extractor side is in InfinityLoop1308/PipePipeExtractor#69.
quick quality update, and it's a good one: turns out the default wasn't even playing the resolution you pick. for default 1080p the resolver asks for AV1 1080p, but the Pixel 8 has no hardware AV1 decoder, so the old fallback grabbed the highest decodable instead = VP9 4K. that's why it kept landing on 4K (and why 4K felt flaky on the Pixel). fixed it to fall back to a decodable codec at the same resolution, so it plays AVC 1080p now, your actual pick.
nice cascade: that one fix also kills the 4K cache overshoot and makes seeking smooth on the Pixel (the seek stalls were 4K-decode-bound). also added a guard so the back-buffer shrinks when the cache goes over budget, no more throttle-deadlock at high bitrate.
validated on the Pixel 8 (default plays AVC 1080p, big rewind smooth, no stall), and checked across the Galaxy S25 + emulator (android 14/16). all on #47.
Client side of the SABR work, paired with the extractor integration issue (InfinityLoop1308/PipePipeExtractor#67).
Docs (how SABR works end to end): https://priveetee.github.io/Docs-PipePipe/developer-guide/introduction
What's in it: a custom ExoPlayer source where a single pump thread drives the SABR session and fills a shared buffer, while the audio and video readers just read from it (so neither track starves the other on a network round-trip). The PO token is minted in a headless WebView (BotGuard), shared and pre-warmed, cached per videoId (~6h).
Status: plays end to end on a Pixel 8 (GrapheneOS / Vanadium WebView). The token flips SABR protection back to playable, hardware VP9/H264, no OOM, no overheating.
Known limit (the honest one): sustained playback stalls. Traced it on-device: the extractor downloads + decodes fine (token, segments, H264 1080p decoder all good), but ExoPlayer stops pulling the video track after the first segment while audio races ahead. So it's an asymmetric track stall in the client player wiring (
MergingMediaSource/LoadControl), not the SABR protocol, protection, or decoding. That's the next chunk of work, probably cleaner to do on media3.This is a PoC / reference PR, not merge-ready yet (seek + quality selection + that stall still need proper wiring).
PR: #43