If you're hosting video on your own site or setting up an IPTV service, you'll eventually need an M3U8 playlist. It's the standard for HLS (HTTP Live Streaming), and it's how platforms like Netflix and YouTube handle high-quality video without constant buffering.
But an M3U8 file isn't just an MP4 with a different name. It's a special manifest file. Here is how to create one using professional tools or just a simple text editor.
This guide focuses on practical output: files that actually play on real browsers, phones, and TV apps, not just commands that work in a demo folder.
.ts or .m4s files) for this to work.
Method 1: FFmpeg (the professional way)
FFmpeg handles the heavy lifting. It can convert almost any video format into HLS segments and generate the M3U8 playlist for you automatically.
Before you start, make sure your source has stable frame rate and keyframes at regular intervals. Irregular sources often produce glitchy seeking and poor adaptive switching.
Basic HLS conversion
To convert a standard MP4 file into HLS segments and an M3U8 playlist, use the following command:
ffmpeg -i input.mp4 -codec copy -start_number 0 -hls_time 10 -hls_list_size 0 -f hls playlist.m3u8 Breakdown of the flags:
-i input.mp4: Your source video file.-
-codec: copy: Tells FFmpeg to copy the video/audio streams without re-encoding (extremely fast). -
-hls_time 10: Sets the target segment length to 10 seconds. -
-hls_list_size 0: Ensures all segments are kept in the playlist (standard for VOD). -f hls: Sets the output format to HLS.
Using -codec copy is fast, but only safe when your
input codec is already compatible with target devices. If playback
fails on older phones, re-encode to H.264/AAC instead of copying.
Adaptive bitrate (multiple quality levels)
To provide a seamless experience, you can create a "Master Playlist" that points to different versions of the same video (like 1080p, 720p, and 480p):
ffmpeg -i input.mp4 \
-map 0:v -map 0:a -s:v:0 1920x1080 -b:v:0 5000k \
-map 0:v -map 0:a -s:v:1 1280x720 -b:v:1 2800k \
-var_stream_map "v:0,a:0 v:1,a:1" \
-master_pl_name master.m3u8 \
-f hls -hls_time 10 -hls_list_size 0 \
-hls_segment_filename "v%v/seg%d.ts" v%v/index.m3u8 Keep each rendition in a separate folder (`v0`, `v1`, etc.). Relative paths in playlists are easier to migrate across staging, production, and CDN origins than hard-coded absolute URLs.
Method 2: Manual creation (for IPTV)
If you already have the links to your video segments or channel streams, you can just build the playlist yourself in a text editor like VS Code or Notepad.
VOD playlist structure
Create a new file named playlist.m3u8 and paste the following
structure:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:10.0,
https://example.com/segments/part1.ts
#EXTINF:10.0,
https://example.com/segments/part2.ts
#EXTINF:10.0,
https://example.com/segments/part3.ts
#EXT-X-ENDLIST IPTV M3U structure
If you are creating a list of different channels or movies (standard M3U/M3U8 for IPTV), the format looks like this:
#EXTM3U
#EXTINF:-1 tvg-id="CNN" tvg-logo="https://logo.com/cnn.png",CNN News
https://stream.provider.com/cnn/index.m3u8
#EXTINF:-1 tvg-id="HBO" tvg-name="HBO HD",HBO
https://stream.provider.com/hbo/index.m3u8 If you're distributing an IPTV list, be consistent with channel naming and metadata (`tvg-id`, `tvg-name`, logos). Small metadata mistakes are one of the biggest reasons EPG mappings break later.
The checklist for a smooth stream
If you want your playlist to work everywhere, keep these two things in mind:
1. CORS headers
If your M3U8 file is on server-a.com but your player
is on my-site.com, the browser will block the video
unless you add this header to your server configuration:
Access-Control-Allow-Origin: * 2. Segment length
10-second segments are standard, but if you're doing live streaming, try 2 or 4 seconds. This reduces "latency"—the lag between the camera and the viewer's screen.
For VOD, longer segments can improve CDN efficiency. For live, shorter segments improve responsiveness but increase request count. Choose based on your audience and server capacity, not on a single "best" value.
3. Content-Type and cache behavior
Serve playlists with application/vnd.apple.mpegurl and
segments with proper media MIME types. For live streams, keep playlist
cache TTL short to avoid stale manifests at the CDN edge.
4. Use absolute time and consistent clocks
In distributed setups, origin and packager clock drift can cause confusing live-edge issues. Synchronize servers with NTP and keep monitoring on segment generation delay.
Testing it out
Once you've uploaded your files, testing is easy:
- Copy the URL to your
.m3u8file. - Go to our M3U8 Online Player.
- Paste the link and hit Play.
If the video starts and you can skip around, you're good to go.
Do one more pass before launch: test on Safari (iOS), Chrome (desktop), and at least one Android device. If adaptive switching, seeking, and restart-from-pause all behave correctly, your playlist is production-ready.