Manual quality profiles (source/1080p/720p/480p) in the player overflow menu plus an honest/preparatory Auto contract: adaptive when the HLS manifest exposes multiple levels, single-rendition automatic selection otherwise. - server: transcodeQualityProfiles service and qualityMode session option - player: quality menu, persisted preference, live switch with rollback - tests: npm test script and unit tests for quality profiles
70 lines
2.0 KiB
JavaScript
70 lines
2.0 KiB
JavaScript
const QUALITY_PROFILES = Object.freeze({
|
|
source: Object.freeze({
|
|
id: 'source',
|
|
videoMode: 'copy'
|
|
}),
|
|
'1080p': Object.freeze({
|
|
id: '1080p',
|
|
videoMode: 'encode',
|
|
maxResolution: '1080p',
|
|
targetVideoBitrateKbps: 6000
|
|
}),
|
|
'720p': Object.freeze({
|
|
id: '720p',
|
|
videoMode: 'encode',
|
|
maxResolution: '720p',
|
|
targetVideoBitrateKbps: 3500
|
|
}),
|
|
'480p': Object.freeze({
|
|
id: '480p',
|
|
videoMode: 'encode',
|
|
maxResolution: '480p',
|
|
targetVideoBitrateKbps: 1500
|
|
})
|
|
});
|
|
|
|
const QUALITY_MODES = Object.freeze(['auto', ...Object.keys(QUALITY_PROFILES)]);
|
|
|
|
function getAutomaticProfile(settings = {}) {
|
|
const configuredResolution = settings.maxResolution;
|
|
return QUALITY_PROFILES[configuredResolution] || QUALITY_PROFILES['1080p'];
|
|
}
|
|
|
|
function resolveQualityMode(qualityMode, settings = {}) {
|
|
if (qualityMode === undefined || qualityMode === null || qualityMode === '') {
|
|
return null;
|
|
}
|
|
|
|
if (!QUALITY_MODES.includes(qualityMode)) {
|
|
const error = new Error(`Unsupported qualityMode: ${qualityMode}`);
|
|
error.code = 'INVALID_QUALITY_MODE';
|
|
throw error;
|
|
}
|
|
|
|
const profile = qualityMode === 'auto'
|
|
? getAutomaticProfile(settings)
|
|
: QUALITY_PROFILES[qualityMode];
|
|
|
|
return {
|
|
qualityMode,
|
|
mode: 'single',
|
|
selectedProfile: profile.id,
|
|
availableProfiles: QUALITY_MODES,
|
|
sessionOptions: {
|
|
videoMode: profile.videoMode,
|
|
...(profile.maxResolution && { maxResolution: profile.maxResolution }),
|
|
...(profile.targetVideoBitrateKbps && {
|
|
targetVideoBitrateKbps: profile.targetVideoBitrateKbps
|
|
}),
|
|
// A manual downscale profile must not inherit a global upscaling setting.
|
|
...(profile.videoMode === 'encode' && { upscaleEnabled: false })
|
|
}
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
QUALITY_MODES,
|
|
QUALITY_PROFILES,
|
|
resolveQualityMode
|
|
};
|