HTTP Live Streaming (HLS) delivers video by breaking it into small segments served over standard HTTP, playable natively in most browsers and devices — the most broadly compatible way to deliver both live and on-demand video.
Why HLS Over Raw RTMP for Viewers
RTMP requires specific player support (largely fallen out of favor in browsers); HLS plays natively in Safari and via standard JavaScript players in other browsers, using ordinary HTTP/HTTPS — making it the practical choice for actually delivering video to viewers.
How HLS Works
The video stream is split into short segments (a few seconds each), with a playlist file (.m3u8) listing the available segments — players download the playlist, then fetch and play segments sequentially, requesting updated playlists for ongoing live content.
Prerequisites
- Nginx with the RTMP module (see How to Set Up Nginx RTMP for Live Video Streaming) as the source, or FFmpeg for converting existing video files
Step 1 — Configure HLS Output in the RTMP Block
rtmp {
server {
listen 1935;
application live {
live on;
hls on;
hls_path /var/www/hls;
hls_fragment 4;
hls_playlist_length 30;
}
}
}
hls_fragment sets segment length in seconds; shorter segments reduce latency but increase overhead, longer segments do the opposite.
Step 2 — Serve the HLS Files
server {
listen 80;
server_name stream.yourdomain.com;
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /var/www;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
}
Step 3 — Play the Stream in a Browser
<video controls>
<source src="https://stream.yourdomain.com/hls/live.m3u8" type="application/vnd.apple.mpegurl">
</video>
Native support exists in Safari; for broader browser compatibility, use a JavaScript HLS player library (such as hls.js) as a wrapper.
Converting an Existing Video File to HLS (On-Demand, Not Live)
ffmpeg -i input.mp4 -codec: copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls output.m3u8
Generating Multiple Quality Levels (Adaptive Bitrate)
application live {
live on;
hls on;
hls_path /var/www/hls;
hls_variant _low BANDWIDTH=500000;
hls_variant _mid BANDWIDTH=1500000;
hls_variant _high BANDWIDTH=3000000;
}
Allows players to automatically switch quality based on the viewer's actual available bandwidth — requires configuring FFmpeg to produce these multiple bitrate variants; see How to Set Up a Video Transcoding Pipeline with FFmpeg.
Adding a CDN in Front of HLS Delivery
See How to Optimize Video Delivery with a CDN for Streaming Content — especially valuable for HLS given how many small segment requests a typical viewing session generates.
Common Errors
Playlist loads but video won't play — verify the MIME types for .m3u8 and .ts files are correctly configured, as shown in Step 2; incorrect MIME types cause many players to reject the content.
Playback has excessive delay for live content — reduce hls_fragment size and hls_playlist_length for lower latency, accepting the trade-off of more frequent segment requests.
Continue Reading
- How to Set Up Nginx RTMP for Live Video Streaming
- How to Set Up a Video Transcoding Pipeline with FFmpeg
- How to Optimize Video Delivery with a CDN for Streaming Content
Browse more articles in Media & Streaming Servers.