Streams and delivery
extractStreams produces the formats the player consumes. The result is not one list but three, and each entry describes both what the media is and how you get it.

Three lists, not one
StreamInfo carries the playable media in three separate lists, plus subtitles:
List<VideoStream> videoStreams; // muxed: video + audio together
List<AudioStream> audioStreams; // audio only
List<VideoStream> videoOnlyStreams; // video with no audio track
List<SubtitlesStream> subtitles;The split is the whole point. Progressive formats ship a single muxed track, that is videoStreams. Adaptive playback instead pairs a videoOnlyStream with a separate audioStream and lets the player pick each one independently by bandwidth. The extractor surfaces all three so the player can choose its own combination, rather than the extractor deciding for it.
What a Stream is
All three extend Stream (which is Serializable). A Stream answers two questions.
What the media is:
getFormat()returns aMediaFormat(container and codec, with a MIME type and file suffix);getFormatId()for the raw id.AudioStreamaddsaverageBitrate, the audio track id / name / locale, and the underlying itag (ItagItem).VideoStreamaddsresolution,fps, width and height, andisVideoOnly.
How to get it:
getDeliveryMethod()returns aDeliveryMethod.getContent()plusisUrl(): the content is either a direct URL (isUrl == true) or an inline manifest blob (isUrl == false), depending on the delivery method;getManifestUrl()covers the manifest-by-URL case.
Streams are compared by delivery method and id, not by URL (equalStats / equals). Media URLs are short-lived and signed, so they make a useless identity.
DeliveryMethod
enum DeliveryMethod { PROGRESSIVE_HTTP, DASH, HLS, SS, TORRENT, SABR }PROGRESSIVE_HTTP: a plain media URL served with byte-range GETs. The simple case.DASH/HLS/SS: an adaptive manifest (a URL or inline blob); the player drives segment selection from it.SABR: YouTube's session protocol. There is no plain URL and no static manifest: the client opens a session and keeps talking to the server for the whole playback.TORRENTexists for completeness and is not used on the YouTube path.
Where this meets SABR
For every delivery method except SABR, the player ends up with either a URL or a manifest, and ExoPlayer takes it from there. SABR is the exception. A SABR stream is not something you download once; it is a conversation you maintain, request, UMP response, segments, follow-up request, with attestation gating the protected media.
The extractor's job stops at marking the stream SABR and handing over the pieces a session needs. Driving that session is a topic of its own: the whole SABR Guide.
