C.W.K.
Stream
Lesson 02 of 08 · published

HLS Streaming

~12 min · hls, streaming, adaptive-bitrate

Level 0Viewer
0 XP0/73 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

HLS — adaptive bitrate streaming for the web

HTTP Live Streaming (HLS) is the format every modern player understands. A clip is split into ~6-second .ts segments at multiple bitrates; a master .m3u8 playlist lets clients switch between rungs based on bandwidth. Self-hosting HLS is a few FFmpeg commands plus an HTTP server.

Code

Single-bitrate HLS (simplest)·bash
# 6-second segments, M3U8 + .ts files alongside it
ffmpeg -i in.mp4 \
  -c:v libx264 -crf 20 -preset slow -g 60 -keyint_min 60 -sc_threshold 0 \
  -c:a aac -b:a 128k \
  -hls_time 6 -hls_playlist_type vod -hls_segment_filename 'seg_%03d.ts' \
  out.m3u8

# Open out.m3u8 in Safari or any HLS-capable player to play.
# -g 60 + -keyint_min 60 + -sc_threshold 0 = a keyframe every 2 seconds at 30fps,
# which keeps segment boundaries clean.
Multi-bitrate HLS ladder (production)·bash
# Three rungs (480p / 720p / 1080p), one master playlist
ffmpeg -i in.mp4 \
  -filter_complex "[0:v]split=3[v480][v720][v1080]; \
                   [v480]scale=854:480[v480o]; \
                   [v720]scale=1280:720[v720o]; \
                   [v1080]scale=1920:1080[v1080o]" \
  -map "[v480o]" -map 0:a -c:v:0 libx264 -crf 23 -preset slow -b:a:0 96k \
  -map "[v720o]" -map 0:a -c:v:1 libx264 -crf 22 -preset slow -b:a:1 128k \
  -map "[v1080o]" -map 0:a -c:v:2 libx264 -crf 21 -preset slow -b:a:2 192k \
  -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2" \
  -hls_time 6 -hls_playlist_type vod \
  -hls_segment_filename 'stream_%v/seg_%03d.ts' \
  -master_pl_name master.m3u8 \
  'stream_%v/stream.m3u8'

External links

Exercise

Take a 2-minute clip. Make a single-bitrate HLS output (master + segments). Serve it locally with python3 -m http.server from the output directory and open the m3u8 in Safari — does it play smoothly? Then make a 3-rung ladder and verify Safari picks an appropriate rung based on its window size.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.