Site icon Fix I.T. Phill – Your Go-To Tech Guru

Nginx HLS Playback Guide: Serve m3u8 Video Streams Safely

Nginx HLS playback tutorial showing m3u8 playlists video segments CDN cache and player verification

Nginx HLS playback tutorial showing m3u8 playlists video segments CDN cache and player verification

Nginx is very good at serving HLS playback files when the playlist and segments already exist. For many business, training, church, event, course, and membership sites, that is the cleanest setup: generate the HLS files with your encoder or media workflow, then let Nginx serve the .m3u8 playlist and segment files quickly.

There are two different jobs people mix together. One is serving static HLS files. The other is generating HLS from source media or a live stream. Standard open source Nginx can serve the files. NGINX Plus includes an official HLS module for MP4/MOV server-side support. Community live-stream workflows often use a third-party module such as nginx-rtmp-module.

Static HLS file layout

A common HLS folder contains one playlist and many small media segments:

/var/www/video/hls/course-intro/
  index.m3u8
  segment-00001.ts
  segment-00002.ts
  segment-00003.ts

For fragmented MP4 HLS, you may see .m4s segments instead of .ts. The player loads the playlist first, then fetches segments as playback progresses.

Nginx config for HLS playback

server {
    listen 443 ssl;
    http2 on;
    server_name video.example.com;

    ssl_certificate /etc/letsencrypt/live/video.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/video.example.com/privkey.pem;

    location /hls/ {
        alias /var/www/video/hls/;

        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
            video/mp4 mp4 m4s;
        }

        add_header Access-Control-Allow-Origin "*" always;
        add_header Cache-Control "public, max-age=60" always;

        try_files $uri =404;
    }
}

Use root or alias deliberately. With alias, the trailing slash matters. Test the exact playlist URL after every change.

Cache planning

For video on demand, longer cache times usually make sense after the files are final. For live or frequently replaced playlists, keep the playlist cache short and let segments cache longer. If a CDN sits in front of Nginx, purge or version playlists when replacing a video.

Playback verification

curl -I https://video.example.com/hls/course-intro/index.m3u8
curl -I https://video.example.com/hls/course-intro/segment-00001.ts

The playlist should return a normal 200 response and a playlist MIME type. The segment should return 200 and a video segment type. Test playback in Safari, VLC, or an HTML5 player that uses hls.js for browsers that do not play HLS natively.

When you need more than static files

If you want Nginx to create HLS playlists from MP4/MOV files on demand, read the official Nginx HLS module documentation and note that it is part of the commercial subscription. If you want live ingest, transcoding, DVR windows, or adaptive bitrate ladders, plan the encoder and streaming layer separately. Nginx can be the delivery piece, but it is not the whole media pipeline by itself.

Security and hosting notes

Related Fix I.T. Phill guides

Sources checked

Exit mobile version