back to blog

Adaptive Bitrate Streaming (ABR)

September 15, 2025 Β· 2 min read

Adaptive Bitrate StreamingScalable Video Platform

Adaptive Bitrate Streaming (ABR) – A Complete Guide with Next.js, Express.js, and Nginx HLS

Video streaming has become the backbone of modern platforms like YouTube, Netflix, and Twitch. But have you ever wondered how these platforms ensure smooth playback even when your internet speed fluctuates?

The answer lies in Adaptive Bitrate Streaming (ABR).

In this guide, we’ll explore how ABR works, and walk through the architecture of a video streaming platform built with Next.js, Express.js, FFmpeg, and Nginx HLS server.


What is Adaptive Bitrate Streaming?

Adaptive Bitrate Streaming (ABR) is a technique where the video player dynamically adjusts the quality of the video (resolution and bitrate) in real time, depending on the user’s network conditions.

Instead of delivering one fixed-quality video, the server provides multiple versions (1080p, 720p, 480p, etc.). The player then chooses the best possible quality without causing buffering.

πŸ‘‰ Example:

On WiFi β†’ you get 1080p smooth playback

On weak 4G β†’ player drops to 480p automatically

This makes streaming seamless and efficient.


Streaming Platform Architecture

I had implemented ABR using HLS (HTTP Live Streaming), which is widely supported across browsers and devices.

The architecture consists of three core components:

  • Next.js Frontend β†’ Video upload & player (HLS.js)

  • Express.js API Server β†’ Handles uploads & FFmpeg processing

  • Nginx HLS Server β†’ Serves .m3u8 playlists & .ts segments

System Design


How Adaptive Bitrate Works in HLS

When a video is uploaded, the backend uses FFmpeg to transcode it into multiple qualities:

const qualityConfigs = [
  { name: '1080p', resolution: '1920x1080', videoBitrate: '5000k', audioBitrate: '192k' },
  { name: '720p', resolution: '1280x720', videoBitrate: '2800k', audioBitrate: '128k' },
  { name: '480p', resolution: '854x480', videoBitrate: '1400k', audioBitrate: '96k' },
];

Each quality level gets its own .m3u8 playlist and .ts segments. Finally, a master playlist (master.m3u8) is generated to link them all:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=5192000,RESOLUTION=1920x1080,NAME="1080p"
1080p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2928000,RESOLUTION=1280x720,NAME="720p"
720p/playlist.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1496000,RESOLUTION=854x480,NAME="480p"
480p/playlist.m3u8

The HLS.js player in the frontend reads this master playlist and automatically switches quality based on bandwidth.

ABR Quality Choosing

Why HLS is Perfect for ABR

  • βœ… Broad support – Works on iOS, Android, browsers
  • βœ… Segmented delivery – Small .ts chunks ensure smooth switching
  • βœ… Scalability – Easily served via nginx or a CDN
  • βœ… Bandwidth efficiency – User always gets the best quality their internet can handle

Share it on!