How to create a m3u8 playlist

Let's create a m3u8 playlist from video named 'sample.mp4' using FFMPEG.

To create m3u8 playist with quality options we have to convert the video into different resolutions.

Create one folder/directory named 'hls' on your Desktop.

Copy a video named 'sample.mp4' having quality 1080p to the folder/directory which one you created recently on Desktop and then open terminal and run following commands:

cd hls

Now we convert the video into different resolutions.

For 144p: 256×144

ffmpeg -i sample.mp4 -c:a aac -strict experimental -c:v libx264 -s 144x256 -aspect 16:9 -f hls -hls_list_size 1000000 -hls_time 2 144_out.m3u8

For 240p: 426×240

ffmpeg -i sample.mp4 -c:a aac -strict experimental -c:v libx264 -s 240x426-aspect 16:9 -f hls -hls_list_size 1000000 -hls_time 2 240_out.m3u8

For 360p: 640×360

ffmpeg -i sample.mp4 -c:a aac -strict experimental -c:v libx264 -s 360x640 -aspect 16:9 -f hls -hls_list_size 1000000 -hls_time 2 360_out.m3u8

For 480p: 854×480

ffmpeg -i sample.mp4 -c:a aac -strict experimental -c:v libx264 -s 480x854 -aspect 16:9 -f hls -hls_list_size 1000000 -hls_time 2 480_out.m3u8

For 720p: 1280×720

ffmpeg -i sample.mp4 -c:a aac -strict experimental -c:v libx264 -s 720x1280 -aspect 16:9 -f hls -hls_list_size 1000000 -hls_time 2 720_out.m3u8

For 1080p: 1920×1080

ffmpeg -i sample.mp4 -c:a aac -strict experimental -c:v libx264 -s 1080x1920 -aspect 16:9 -f hls -hls_list_size 1000000 -hls_time 2 1080_out.m3u8
After performing 6 resolution commands 6 distinct .m3u8 files will be generated.

1. 144_out.m3u8

2. 240_out.m3u8

3. 360_out.m3u8

4. 480_out.m3u8

5. 720_out.m3u8

6. 1080_out.m3u8

Now create one .m3u8 file with named 'playlist.m3u8' in folder/directory named 'hls' manually or by programatically and add the following codes.

playlist.m3u8

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:BANDWIDTH=628000,AVERAGE-BANDWIDTH=628000,RESOLUTION=256x144
144_out.m3u8
                    
#EXT-X-STREAM-INF:BANDWIDTH=2031242,AVERAGE-BANDWIDTH=1627117,RESOLUTION=426x240
244_out.m3u8
                    
#EXT-X-STREAM-INF:BANDWIDTH=2031242,AVERAGE-BANDWIDTH=1627117,RESOLUTION=640x360
360_out.m3u8
                    
#EXT-X-STREAM-INF:BANDWIDTH=2031242,AVERAGE-BANDWIDTH=1627117,RESOLUTION=854x480
480_out.m3u8
                    
#EXT-X-STREAM-INF:BANDWIDTH=4394618,AVERAGE-BANDWIDTH=3529217,RESOLUTION=1280x720
720_out.m3u8
                    
#EXT-X-STREAM-INF:BANDWIDTH=6279722,AVERAGE-BANDWIDTH=5321023,RESOLUTION=1920x1080
1080_out.m3u8

 

Now you successfully created m3u8 playlist file.

Demo

Create 'index.html' in hls folder/directory and add follwing codes.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hls </title>
    <link rel="stylesheet" href="https://cdn.plyr.io/3.5.10/plyr.css" />
    <script src="https://cdn.jsdelivr.net/npm/hls.js"> </script>
    <script src="https://unpkg.com/plyr@3"> </script>
</head>
<body>
    <video style="height: auto !important" id="video" style="display:none" controls crossorigin playsinline>
        <source type="application/x-mpegURL" src="playlist.m3u8">
    </video>
    <script>
        $(document).addEventListener("DOMContentLoaded", () => {
            const video = document.querySelector("video");
            const source = video.getElementsByTagName("source")[0].src;
            const defaultOptions = {};
            if (Hls.isSupported()) {
                const hls = new Hls();
                hls.loadSource(source);
                hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
                    const availableQualities = hls.levels.map((l) => l.height)
                    defaultOptions.quality = {
                        default: availableQualities[0],
                        options: availableQualities,
                        forced: true,
                        onChange: (e) => updateQuality(e),
                    }

                    const player = new Plyr(video, defaultOptions);
                });
                hls.attachMedia(video);
                window.hls = hls;
            } else {
                const player = new Plyr(video, defaultOptions);
            }
            function updateQuality(newQuality) {
                window.hls.levels.forEach((level, levelIndex) => {
                    if (level.height === newQuality) {
                        console.log("Found quality match with " + newQuality);
                        window.hls.currentLevel = levelIndex;
                    }
                });
            }
        });
  </script>
</body>
</html>