2026-07-037 min readbuild m3u8 player javascript, custom hls player, create m3u8 player
Build Your Own M3U8 Player with JavaScript
Step-by-step guide to building a custom M3U8/HLS video player using hls.js. Full source code and implementation walkthrough.
Project Setup
Create a new HTML file and include hls.js:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<input id="urlInput" placeholder="Paste M3U8 URL" />
<button id="loadBtn">Load</button>
<video id="video" controls></video>
</body>
</html>
Core Player Implementation
const video = document.getElementById('video');
const urlInput = document.getElementById('urlInput');
const loadBtn = document.getElementById('loadBtn');
let hls = null;
function loadStream(url) {
if (hls) {
hls.destroy();
}
if (Hls.isSupported()) {
hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = url;
}
}
loadBtn.addEventListener('click', () => {
const url = urlInput.value.trim();
if (url) loadStream(url);
});Adding Quality Selection
function updateQualityList() {
if (!hls || !hls.levels) return;
const select = document.getElementById('qualitySelect');
select.innerHTML = '';
// Auto option
const auto = document.createElement('option');
auto.value = '-1';
auto.textContent = 'Auto';
select.appendChild(auto);
// Quality options
hls.levels.forEach((level, index) => {
const option = document.createElement('option');
option.value = index;
option.textContent = level.height + 'p (' + (level.bitrate / 1000000).toFixed(1) + ' Mbps)';
select.appendChild(option);
});
}
hls.on(Hls.Events.MANIFEST_PARSED, updateQualityList);Adding Stream Statistics
function updateStats() {
if (!hls) return;
const level = hls.levels[hls.currentLevel];
if (!level) return;
const stats = {
resolution: level.width + 'x' + level.height,
bitrate: (level.bitrate / 1000).toFixed(0) + ' kbps',
bandwidth: (hls.bandwidthEstimate / 1000).toFixed(0) + ' kbps',
buffer: (hls.media?.buffered.length > 0
? hls.media.buffered.end(0) - hls.media.currentTime
: 0).toFixed(1) + 's'
};
document.getElementById('stats').innerHTML =
Object.entries(stats).map(([k,v]) =>
'<div><strong>' + k + '</strong> ' + v + '</div>'
).join('');
}
setInterval(updateStats, 1000);Related Articles
Getting Started with hls.js: Tutorial & Examples
Learn how to use hls.js to play HLS streams in any browser. Complete tutorial with code examples for developers.
HTML5 M3U8 Player: How Modern Browsers Play HLS Streams
Technical deep-dive into how HTML5 M3U8 players work using hls.js and MSE.
M3U8 Streaming Architecture: From Server to Browser
Understand the complete M3U8 streaming architecture. How video moves from the encoder through CDN to the viewer's browser.