Adaptive Bitrate Streaming (ABR) — What It Is and How Players Decide

Adaptive Bitrate Streaming (ABR)

Adaptive bitrate streaming is a technique where a single video is encoded at multiple resolutions/bitrates simultaneously and the player picks the best variant for the current network conditions. Quality switches happen at segment boundaries during playback — usually unnoticed by the viewer.

The problem ABR solves

Pre-2010s, video was served as a single fixed-bitrate file. If your connection was too slow, you got constant buffering. If you had fiber, you watched the same low quality everyone else got. Either way, mismatched.

ABR fixes this. The encoder produces a ladder of variants — typically 360p / 540p / 720p / 1080p / 4K — and the player chooses the variant that matches actual bandwidth. As bandwidth changes (e.g., entering a tunnel on mobile), the player drops to a lower variant and back up later.

How the player decides

  1. Player downloads master playlist listing all variants and their bandwidth.
  2. Player measures the time taken to download the first segment.
  3. Throughput (bandwidth) is calculated.
  4. If sustained throughput exceeds the next-higher variant’s bandwidth requirement with margin, switch up at the next segment boundary.
  5. If a segment download stalls or buffer drops below threshold, switch down immediately.

The decision algorithm is sometimes called ABR logic and varies by player (HLS.js, Shaka Player, ExoPlayer, AVPlayer all have different heuristics).

Why it’s standard now

  • Mobile bandwidth varies — driving, in elevators, in basements
  • Network sharing — household members starting downloads mid-watch
  • CDN edge variability — different edges have different uplinks
  • Protect against abandonment — every buffer event = lost viewer

ABR + encryption

Encryption (AES-128) is applied per segment, which means encryption is transparent to ABR. The player switches variants and decrypts the new variant’s segments using the same key delivery mechanism. AVCaption rotates keys per batch, which works seamlessly across variant switches.

← content.back_to_index