Skip to content

Add support for SABR (v2) - #5814

Open
unixfox wants to merge 10 commits into
iv-org:masterfrom
unixfox:sabr-shakajs-2
Open

Add support for SABR (v2)#5814
unixfox wants to merge 10 commits into
iv-org:masterfrom
unixfox:sabr-shakajs-2

Conversation

@unixfox

@unixfox unixfox commented Jul 20, 2026

Copy link
Copy Markdown
Member

Checklist

  • I have read the AI Policy and understand the disclosure requirements

AI Disclosure

  • AI was not used to create this pull request
  • AI was used to fully create this pull request
  • AI was used to partially create this pull request

Model(s) used (and thinking/reasoning level if relevant):
Claude Opus 4.8

Tool(s) used:
Claude Code

How was AI used?

Was used to replicate the code from https://github.com/LuanRT/kira and freetube's SABR code.


Pull request description

This pull request is for adding SABR support to invidious.

Close #5263

unixfox and others added 10 commits June 28, 2026 13:28
… 5.1.10), companion-optional watch page, no esm.sh
Segment index parsers (mp4/webm) declared the per-segment URI array with
`var` inside the loop, so every SegmentReference's getUris() closure
captured the same function-scoped binding and returned the LAST segment's
URL. YouTube received the final segment's startTimeMs/sq for every
segment, replied with policy-only UMP (no media), and the player looped
forever on a black screen ("SABR throttled by YouTube"). Use `let`
(block-scoped, fresh per iteration) to match FreeTube's `const`.

Also scope the big centered play button styling to
`.shaka-play-button-container`; the bare `.shaka-play-button` selector
also matched the control-bar play button (48px siblings), oversizing it
to ~54px and pushing it out of alignment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the plain /youtubei/v1/player request (made through the proxy,
and therefore bound to the proxy's egress IP) with an encrypted Onesie
request using the WEB client. Onesie is proxied by YouTube's "trusted
bandaid", so the returned player response - and the server_abr_streaming_url
inside it - is not tied to our egress IP. Media is still pulled over SABR
(sabr_scheme_plugin.js); only how the player response is obtained changes.

- sabr_onesie.js: new module, window.fetchOnesiePlayerResponse(). Builds the
  WEB player request, encrypts it (OnesieInnertubeRequest + OnesieRequest),
  POSTs to the onesie endpoint through /proxy, parses ONESIE_HEADER/ONESIE_DATA
  UMP parts, gunzips/decrypts, returns the raw player response JSON. Adapted
  from googlevideo/examples/onesie-request and invidious-secret-companion's
  WEB-client variant.
- sabr_helpers.js: add decryptResponse() (AES-CTR + HMAC verify), companion to
  the existing encryptRequest().
- sabr_loader.js: expose window.YT so a VideoInfo can be built from the raw
  onesie player response.
- sabr_player.js: in loadVideo(), fetch the player response via Onesie and wrap
  it in new YT.VideoInfo(...); fall back to innertube.getInfo() on failure.
- player.ecr: load sabr_onesie.js before sabr_player.js.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@unixfox unixfox mentioned this pull request Jul 20, 2026
6 tasks
mdbraber added a commit to mdbraber/owntube that referenced this pull request Jul 30, 2026
docs/OWNTUBE-UPSTREAM-PLAN.md proposes replacing Invidious with a service we own,
built on youtubei.js. Two pressures point the same way: the fork is now 8 patches
rebased forever, and upstream is moving to SABR client-side only
(iv-org/invidious#5814), which is a viable answer for a web player but not
obviously one for a client set that includes expo-video on Android TV.

The plan records what was measured rather than assumed — youtubei.js' coverage
(FreeTube's 2,270-line local.js, shipped to 21.5k users), how much of Invidious we
actually use (8 endpoint families; ~40% of it is UI and accounts), and that
server-side SABR is feasible because googlevideo exports SabrStream for headless
use. It also records four corrections to my own earlier reasoning, including that
Android TV does *not* structurally force a server-side connector — Materialious
ships SABR on Android TV through a Capacitor WebView, so that constraint is our
choice of expo-video, not the platform.

The detector is the part worth having today. `sabrExposure` measures the share of
*non-live* videos that no longer carry init/index byte ranges — the thing that
would silently break /dash and /hls. Currently 0/12. Live streams are excluded
because they are legitimately segment-addressed; that exclusion leans on liveNow
being correct, which Phase 3.2 fixed and listLiveFlag guards.

It samples `popular` rather than trending, which was the first attempt and
SKIPped: trending is the livestreams feed now, so it yields no non-live sample at
all.

Canary is 8 PASS + 1 SKIP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

[Enhancement] SABR support

1 participant