Skip to content

Quality Levels

Adaptive bitrate is on by default, hls.js (or Safari’s native HLS) keeps switching renditions to match bandwidth without you doing anything. This page is for when you want a manual quality menu on top of that.

Listing levels

qualityLevels() returns the manifest’s bitrate renditions once the 'levels' event has fired, each with bitrate, and height/width when the manifest provides them. qualityLevels({ includeUnsupported: true }) also returns renditions the current device can’t decode, useful for showing them disabled in a menu rather than hiding them entirely:

TypeScript
import nmplayer from '@nomercy-entertainment/nomercy-video-player';

const player = nmplayer('player');

const levels = player.qualityLevels(); // QualityLevel[]
const withUnsupported = player.qualityLevels({ includeUnsupported: true });

Reading and setting the selection

quality() returns { index, track } for a manually-picked level, or the string 'auto' while ABR is driving. quality(idx) locks a specific level; quality('auto') hands control back to the backend:

TypeScript
player.quality(0); // lock the first (usually lowest) rendition
player.quality('auto'); // back to adaptive

Setting a level emits 'quality:requested' immediately (video-specific, fired before the backend confirms the switch) and 'level-switched' once the backend actually applies it, subscribe to the latter for a “now playing at 1080p” toast, the former if you need to reflect the request instantly in a UI without waiting on the network.

Default quality

defaultQuality on VideoPlayerConfig applies once after the first manifest parse, either 'auto' (the kit’s own default, so setting it explicitly is only useful for readability) or a fixed level index:

TypeScript
player.setup({
baseUrl,
playlist: [item],
defaultQuality: 'auto',
});

Bandwidth and capability checks

bandwidth() reads the backend’s current bandwidth estimate in bits per second, the number ABR is deciding against; bandwidthEstimator(fn) overrides the estimator with your own (a shared measurement across multiple players on the same page, for example). canPlay(profile) asks the platform’s MediaCapabilities whether a given content profile (contentType, resolution, bitrate, framerate) is decodable before you offer it in a menu at all.

Next steps

  • Chapters: chapters(), seekToChapter(), and playSegment() for arbitrary time windows.