Skip to content

Instantly share code, notes, and snippets.

@ShashiTharoor
Created May 24, 2022 04:21
Show Gist options
  • Save ShashiTharoor/9225337463c9b1173c69c9e6234d2bbb to your computer and use it in GitHub Desktop.
Save ShashiTharoor/9225337463c9b1173c69c9e6234d2bbb to your computer and use it in GitHub Desktop.
Plyr + HLS.js & video quality
<div class="container">
<video controls crossorigin playsinline poster="https://bitdash-a.akamaihd.net/content/sintel/poster.png"></video>
</div>
<!-- Plyr resources and browser polyfills are specified in the pen settings -->
<!-- Hls.js 0.9.x and 0.10.x both have critical bugs affecting this demo. Using fixed git hash to when it was working (0.10.0 pre-release), until https://github.com/video-dev/hls.js/issues/1790 has been resolved -->
<script src="https://cdn.rawgit.com/video-dev/hls.js/18bb552/dist/hls.min.js"></script>

Plyr + HLS.js & video quality

Using Plyr html5 video player and HLS.js to play adaptive video stream with quality selector.

A Pen by Matthew Marino on CodePen.

License.

document.addEventListener('DOMContentLoaded', () => {
const source = 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8';
const video = document.querySelector('video');
const defaultOptions = {};
if (!Hls.isSupported()) {
video.src = source;
var player = new Plyr(video, defaultOptions);
} else {
// For more Hls.js options, see https://github.com/dailymotion/hls.js
const hls = new Hls();
hls.loadSource(source);
// From the m3u8 playlist, hls parses the manifest and returns
// all available video qualities. This is important, in this approach,
// we will have one source on the Plyr player.
hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
// Transform available levels into an array of integers (height values).
const availableQualities = hls.levels.map((l) => l.height)
availableQualities.unshift(0) //prepend 0 to quality array
// Add new qualities to option
defaultOptions.quality = {
default: 0, //Default - AUTO
options: availableQualities,
forced: true,
onChange: (e) => updateQuality(e),
}
// Add Auto Label
defaultOptions.i18n = {
qualityLabel: {
0: 'Auto',
},
}
hls.on(Hls.Events.LEVEL_SWITCHED, function (event, data) {
var span = document.querySelector(".plyr__menu__container [data-plyr='quality'][value='0'] span")
if (hls.autoLevelEnabled) {
span.innerHTML = `AUTO (${hls.levels[data.level].height}p)`
} else {
span.innerHTML = `AUTO`
}
})
// Initialize new Plyr player with quality options
var player = new Plyr(video, defaultOptions);
});
hls.attachMedia(video);
window.hls = hls;
}
function updateQuality(newQuality) {
if (newQuality === 0) {
window.hls.currentLevel = -1; //Enable AUTO quality if option.value = 0
} else {
window.hls.levels.forEach((level, levelIndex) => {
if (level.height === newQuality) {
console.log("Found quality match with " + newQuality);
window.hls.currentLevel = levelIndex;
}
});
}
}
});
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent,Object.entries,Object.values,URL"></script>
<script src="https://unpkg.com/plyr@3"></script>
.container {
margin: 100px auto;
width: 70%;
}
video {
width: 100%;
}
<link href="https://unpkg.com/plyr@3/dist/plyr.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment