How to create M3U8 playlists for your own videos

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.

First things first: An M3U8 file isn't just an MP4 with a different extension. It's a map. Your video must be chopped into small segments (usually .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:

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:

  1. Copy the URL to your .m3u8 file.
  2. Go to our M3U8 Online Player.
  3. 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.

Related guides