Skip to content

fix(youtube): support SABR random access from player time#83

Open
Priveetee wants to merge 8 commits into
InfinityLoop1308:mainfrom
Priveetee:fix/youtube-sabr-player-time
Open

fix(youtube): support SABR random access from player time#83
Priveetee wants to merge 8 commits into
InfinityLoop1308:mainfrom
Priveetee:fix/youtube-sabr-player-time

Conversation

@Priveetee

@Priveetee Priveetee commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds an additional random-access option for YouTube SABR sessions.

The existing SABR flow is kept as-is. This adds another way to drive a SABR session when a caller already knows the current playback position: seed the YouTube player response with startTimeSecs, then request media around a specific playerTimeMs.

The session still keeps the normal stateful SABR data: selected formats, active tracks, buffered ranges, playback cookie, SABR contexts and PO token state.

It also fixes SABR init retrieval for fresh sessions opened at a non-zero playback position by fetching init data before applying seek-state changes.

Why

PipePipe's SABR support already has the pieces needed for stateful playback, but consumers currently have no clean extractor-level primitive for "give me media around this playback time".

This gives PipePipe and downstream consumers another option for playback flows where starting from the beginning is not ideal or not enough.

It can be useful for:

  • resuming from a saved position
  • seeking
  • quality switching
  • queue transitions
  • restoring playback after app/background interruptions
  • avoiding unnecessary full session resets

Without a player-time entry point, downstream consumers may need to restart from the beginning, keep local workaround state, or accidentally depend on fallback playback surfaces instead of driving the SABR session directly.

This PR keeps that behavior inside PipePipeExtractor, where the YouTube SABR session state is already managed.

For TypeType, this is essential because TypeType uses a SABR-only YouTube playback contract and needs a reliable way to open or reuse a stateful SABR session around the current player position. The same primitive could be useful to PipePipe in the future for resume, seek, quality-switch and performance-sensitive playback paths.

Changes

  • Add YoutubeSabrProbe.fetchSabrInfo(..., startTimeSecs).
  • Include startTimeSecs in the YouTube player request when provided.
  • Add YoutubeSabrSession.fetchMediaAt(playerTimeMs, videoActive, audioActive, localization).
  • Add YoutubeSabrSession.fetchMediaSegmentAt(...) for targeted player-time media requests.
  • Preserve active/preferred audio and video track state separately in SABR requests.
  • Include current format selections and buffered ranges on player-time requests.
  • Track observed segment timings from media headers.
  • Treat a player-time request as satisfied only when the returned media is the exact requested segment or covers the requested player time.
  • Fetch SABR init data before applying non-zero seek state, so fresh sessions opened near a later playback position can still return valid init data.

Validation

Extractor:

JAVA_HOME=/usr/lib/jvm/java-25-openjdk ./gradlew :extractor:compileJava --no-daemon --no-parallel --max-workers=1
git diff --check

Player-time media probes:

MO7hCeL-zRU @ 321601ms, video 137, audio 140: passed
AVC batch 137,136,135,134,133,160 with audio 140: passed

Observed media around 321601ms:

video 137 seq=64 startMs=318618 durationMs=4672
audio 140 seq=33 startMs=319506 durationMs=9985

Both returned media ranges cover 321601ms.

Downstream runtime validation also passed in TypeType, which uses SABR-only playback without HLS/DASH/progressive fallback:

videoId=ZNHSuMl7GnE videoItag=136 audioItag=140

playerTimeMs=128000
descriptor status=200
audioInit -> 200 audio/mp4 959 bytes
videoInit -> 200 video/mp4 1216 bytes

playerTimeMs=149717
descriptor status=200
audioInit -> 200 audio/mp4 959 bytes
videoInit -> 200 video/mp4 1216 bytes

Notes

This does not replace the existing SABR session flow.

It adds an optional player-time random-access path. Callers that do not need this behavior can continue using the current flow unchanged.

@Priveetee Priveetee marked this pull request as draft July 4, 2026 10:40
@Priveetee Priveetee marked this pull request as ready for review July 4, 2026 19:54
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.

1 participant