Starting a session
Part of SABR in the extractor. The current PipePipeExtractor keeps player-response parsing and the media-session driver separate. There is no stand-alone YoutubeSabrProbe or client-profile enum in the current source.
From the player response to YoutubeSabrInfo
YoutubeStreamExtractor.buildSabrInfoFromPlayerResponse(...) is the entry point used after the selected MWEB player response has been fetched. It builds the immutable YoutubeSabrInfo object consumed by YoutubeSabrSession:
- Read
streamingData. A response without it is rejected as a SABR protocol error. - Read
serverAbrStreamingUrl, thevideoPlaybackUstreamerConfig, visitor data, andadaptiveFormats. - Collect signatures and
nparameters from the adaptive format URLs and the SABR endpoint. If any are present,YoutubeJavaScriptPlayerManagerperforms one batch deobfuscation and the resolved values are put back into the URLs. - Convert the adaptive formats into
YoutubeSabrInfo.Formatvalues and keep the optional player PO token, when the caller supplied one.
YoutubeSabrInfo contains the video id, CPN, client version, visitor data, resolved SABR endpoint, ustreamer configuration, optional PO token, and the format list. A format keeps its parsed ItagItem, MIME type, codec-related metadata, audio-track identity, DRC flag, initialization URL/range, and the approximate duration. The class deliberately exposes no HTTP or decoder state.
Creating requests
The session is created with:
YoutubeSabrSession session = new YoutubeSabrSession(info);An optional spool directory enables disk-backed assembly for large, uncompressed media segments. The caller creates immutable requests with YoutubeSabrRequest:
YoutubeSabrRequest preparation = YoutubeSabrRequest.preparation(
playerTimeMs, preferredFormats);
YoutubeSabrRequest playback = YoutubeSabrRequest.playback(
playerTimeMs, playbackRate, tracks);preparation asks for format timelines without declaring selected tracks. playback declares one audio track, one video track, or either one alone, and may carry a YoutubeSabrFormatTimeline plus the last buffered sequence for each track. A request cannot contain two audio tracks, two video tracks, or the same itag as both audio and video.
Sending a request
YoutubeSabrSession.requestOnce(request, consumer) performs at most one HTTP transaction. It returns the number of completed media segments, the server backoff, and whether the call was deferred because an earlier backoff is still active. The session increments its request number only after a response has been read. YoutubeSabrRequestHelper then:
- adds
alr=yes,cpn, and the zero-based request number to the SABR endpoint; - encodes the request as
VideoPlaybackAbrRequest; - sends the MWEB user agent and localization;
- requires an
application/vnd.yt-umpresponse; - streams UMP parts through
SabrStreamingResponseReaderso large media payloads do not require buffering the complete HTTP body; - returns a
YoutubeSabrResponsewith control summaries, media statistics, and completedSabrMediaSegmentobjects.
The consumer receives segments as soon as a MEDIA_END part completes one. When an optional spool directory is used, large segments can be read from a file (or progressively while the file is still being written) through SabrMediaSegment.openStream().
What state is carried forward
YoutubeSabrSession keeps only protocol state between calls: request number, the current redirected SABR URL, playback cookie, active SABR contexts, PO token, bandwidth estimate, live metadata, and bounded diagnostic counters. A NEXT_REQUEST_POLICY can update the cookie and backoff. Context updates and context-sending policy decide which opaque context values are echoed in later requests.
The session validates redirects before accepting them: they must use HTTPS and remain on googlevideo.com or one of its subdomains. A media-bearing response resets the redirect counter, while malformed or incomplete media is classified for bounded recovery.
Next: The request.
