Skip to content

Instantly share code, notes, and snippets.

@mdschweda
Created April 2, 2024 00:01
Show Gist options
  • Save mdschweda/26d45da561347b7ca12bdf47315fc715 to your computer and use it in GitHub Desktop.
Save mdschweda/26d45da561347b7ca12bdf47315fc715 to your computer and use it in GitHub Desktop.
Plyr + dash.js quality toggle w/ Auto
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/x-icon" href="https://cdn.plyr.io/static/icons/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Quality Toggle</title>
</head>
<body>
<video playsinline controls></video>
<script type="module" src="/main.js"></script>
</body>
</html>
import "./style.css";
import dashjs from "dashjs";
import Plyr from"plyr";
import "plyr/dist/plyr.css";
// Use "0p" as a marker for automatic bitrate switching
const AUTO_QUALITY = 0;
const el = document.querySelector("video");
const url = "https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd";
/**
* @type Plyr?
*/
let player;
/**
* @type Plyr.Options
*/
const options = {
i18n: {
qualityLabel: {
// Display "Auto" instead of "0p" in the settings menu
[AUTO_QUALITY]: "Auto",
}
}
};
// Set up MPEG-DASH streaming media source extension
const dash = dashjs.MediaPlayer().create();
dash.initialize(el, url, true);
dash.on("streamInitialized", e => {
/**
* @type Map<number, dashjs.BitrateInfo>
*/
const qualities = new Map();
// Video quality choices
// Eliminate duplicates, prefer higher bitrates
for (let info of dash.getBitrateInfoListFor("video"))
if (!qualities.has(info.height) || qualities.get(info.height).bitrate < info.bitrate)
qualities.set(info.height, info);
const resolutionsSorted = Array.from(qualities.keys()).sort((a, b) => a > b);
/**
* @type Plyr.QualityOptions
*/
const qualityOptions = {
options: [AUTO_QUALITY, ...resolutionsSorted],
default: AUTO_QUALITY,
forced: true,
onChange: (e) => {
if (e === AUTO_QUALITY) {
// dash.js auto bitrate
dash.getSettings().streaming.abr.autoSwitchBitrate.video = true;
} else {
// dash.js explicit bitrate
dash.getSettings().streaming.abr.autoSwitchBitrate.video = false;
const index = qualities.get(e).qualityIndex;
dash.setQualityFor("video", index, true);
}
},
}
player = new Plyr(el, { ...options, quality: qualityOptions });
});
:root {
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
margin: 0;
height: 100dvh;
display: flex;
place-items: center;
justify-content: center;
}
.plyr {
aspect-ratio: 16/9;
height: 640px;
border-radius: 6px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment