2024-08-14 13:31:34 -04:00
|
|
|
import globalize from '../lib/globalize';
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
export function getVideoQualityOptions(options) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const maxStreamingBitrate = options.currentMaxBitrate;
|
2024-09-14 16:46:02 +08:00
|
|
|
const videoBitRate = options.videoBitRate ?? -1;
|
2024-09-17 17:01:42 +08:00
|
|
|
const videoCodec = options.videoCodec;
|
|
|
|
let referenceBitRate = videoBitRate;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2024-09-14 16:46:02 +08:00
|
|
|
// Quality options are indexed by bitrate. If you must duplicate them, make sure each of them are unique (by making the last digit a 1)
|
|
|
|
// Question: the maxHeight field seems not be used anywhere, is it safe to remove those?
|
|
|
|
const bitrateConfigurations = [
|
|
|
|
{ name: '120 Mbps', maxHeight: 2160, bitrate: 120000000 },
|
|
|
|
{ name: '80 Mbps', maxHeight: 2160, bitrate: 80000000 },
|
|
|
|
{ name: '60 Mbps', maxHeight: 2160, bitrate: 60000000 },
|
|
|
|
{ name: '40 Mbps', maxHeight: 2160, bitrate: 40000000 },
|
|
|
|
{ name: '20 Mbps', maxHeight: 2160, bitrate: 20000000 },
|
|
|
|
{ name: '15 Mbps', maxHeight: 1440, bitrate: 15000000 },
|
|
|
|
{ name: '10 Mbps', maxHeight: 1440, bitrate: 10000000 },
|
|
|
|
{ name: '8 Mbps', maxHeight: 1080, bitrate: 8000000 },
|
|
|
|
{ name: '6 Mbps', maxHeight: 1080, bitrate: 6000000 },
|
|
|
|
{ name: '4 Mbps', maxHeight: 720, bitrate: 4000000 },
|
|
|
|
{ name: '3 Mbps', maxHeight: 720, bitrate: 3000000 },
|
|
|
|
{ name: '1.5 Mbps', maxHeight: 720, bitrate: 1500000 },
|
|
|
|
{ name: '720 kbps', maxHeight: 480, bitrate: 720000 },
|
2024-09-14 17:06:37 +08:00
|
|
|
{ name: '420 kbps', maxHeight: 360, bitrate: 420000 }
|
|
|
|
];
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const qualityOptions = [];
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-17 20:06:20 -04:00
|
|
|
const autoQualityOption = {
|
|
|
|
name: globalize.translate('Auto'),
|
|
|
|
bitrate: 0,
|
|
|
|
selected: options.isAutomaticBitrateEnabled
|
|
|
|
};
|
|
|
|
|
|
|
|
if (options.enableAuto) {
|
|
|
|
qualityOptions.push(autoQualityOption);
|
|
|
|
}
|
|
|
|
|
2024-09-14 17:42:41 +08:00
|
|
|
if (videoBitRate > 0 && videoBitRate < bitrateConfigurations[0].bitrate) {
|
2024-09-17 17:01:42 +08:00
|
|
|
// Slightly increase reference bitrate for high efficiency codecs when it is not too high
|
|
|
|
// Ideally we only need to do this for transcoding to h264, but we need extra api request to get that info which is not ideal for this
|
|
|
|
if (videoCodec && ['hevc', 'av1', 'vp9'].includes(videoCodec) && referenceBitRate <= 20000000) {
|
|
|
|
referenceBitRate *= 1.5;
|
|
|
|
}
|
2024-09-14 16:46:02 +08:00
|
|
|
// Push one entry that has higher limit than video bitrate to allow using source bitrate when Auto is also limited
|
2024-09-17 17:01:42 +08:00
|
|
|
const sourceOptions = bitrateConfigurations.filter((c) => c.bitrate > referenceBitRate).pop();
|
2024-09-14 16:46:02 +08:00
|
|
|
qualityOptions.push(sourceOptions);
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
|
|
|
|
2024-09-14 16:46:02 +08:00
|
|
|
bitrateConfigurations.forEach((c) => {
|
2024-09-17 17:01:42 +08:00
|
|
|
if (videoBitRate <= 0 || c.bitrate <= referenceBitRate) {
|
2024-09-14 16:46:02 +08:00
|
|
|
qualityOptions.push(c);
|
|
|
|
}
|
2024-09-14 17:09:03 +08:00
|
|
|
});
|
2020-07-16 22:19:09 +02:00
|
|
|
|
|
|
|
if (maxStreamingBitrate) {
|
2020-12-04 18:14:20 +08:00
|
|
|
let selectedIndex = qualityOptions.length - 1;
|
2020-10-07 21:12:14 +09:00
|
|
|
for (let i = 0, length = qualityOptions.length; i < length; i++) {
|
|
|
|
const option = qualityOptions[i];
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-12-04 17:40:20 +08:00
|
|
|
if (option.bitrate > 0 && option.bitrate <= maxStreamingBitrate) {
|
2020-07-16 22:19:09 +02:00
|
|
|
selectedIndex = i;
|
2020-12-04 17:40:20 +08:00
|
|
|
break;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const currentQualityOption = qualityOptions[selectedIndex];
|
2020-07-16 22:19:09 +02:00
|
|
|
|
|
|
|
if (!options.isAutomaticBitrateEnabled) {
|
|
|
|
currentQualityOption.selected = true;
|
|
|
|
} else {
|
|
|
|
autoQualityOption.autoText = currentQualityOption.name;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2020-07-16 22:19:09 +02:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return qualityOptions;
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
export function getAudioQualityOptions(options) {
|
2020-10-07 21:12:14 +09:00
|
|
|
const maxStreamingBitrate = options.currentMaxBitrate;
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const qualityOptions = [];
|
2020-07-16 22:19:09 +02:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const autoQualityOption = {
|
2020-07-16 22:19:09 +02:00
|
|
|
name: globalize.translate('Auto'),
|
|
|
|
bitrate: 0,
|
|
|
|
selected: options.isAutomaticBitrateEnabled
|
|
|
|
};
|
|
|
|
|
|
|
|
if (options.enableAuto) {
|
|
|
|
qualityOptions.push(autoQualityOption);
|
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-17 20:06:20 -04:00
|
|
|
qualityOptions.push({ name: '2 Mbps', bitrate: 2000000 });
|
|
|
|
qualityOptions.push({ name: '1.5 Mbps', bitrate: 1500000 });
|
|
|
|
qualityOptions.push({ name: '1 Mbps', bitrate: 1000000 });
|
|
|
|
qualityOptions.push({ name: '320 kbps', bitrate: 320000 });
|
|
|
|
qualityOptions.push({ name: '256 kbps', bitrate: 256000 });
|
|
|
|
qualityOptions.push({ name: '192 kbps', bitrate: 192000 });
|
|
|
|
qualityOptions.push({ name: '128 kbps', bitrate: 128000 });
|
|
|
|
qualityOptions.push({ name: '96 kbps', bitrate: 96000 });
|
|
|
|
qualityOptions.push({ name: '64 kbps', bitrate: 64000 });
|
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
if (maxStreamingBitrate) {
|
2020-12-04 18:14:20 +08:00
|
|
|
let selectedIndex = qualityOptions.length - 1;
|
2020-10-07 21:12:14 +09:00
|
|
|
for (let i = 0, length = qualityOptions.length; i < length; i++) {
|
|
|
|
const option = qualityOptions[i];
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-12-04 17:40:20 +08:00
|
|
|
if (option.bitrate > 0 && option.bitrate <= maxStreamingBitrate) {
|
2020-07-16 22:19:09 +02:00
|
|
|
selectedIndex = i;
|
2020-12-04 17:40:20 +08:00
|
|
|
break;
|
2019-01-10 15:39:37 +03:00
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-10-07 21:12:14 +09:00
|
|
|
const currentQualityOption = qualityOptions[selectedIndex];
|
2020-07-16 22:19:09 +02:00
|
|
|
|
|
|
|
if (!options.isAutomaticBitrateEnabled) {
|
|
|
|
currentQualityOption.selected = true;
|
|
|
|
} else {
|
|
|
|
autoQualityOption.autoText = currentQualityOption.name;
|
|
|
|
}
|
2018-10-23 01:05:09 +03:00
|
|
|
}
|
2019-01-10 15:39:37 +03:00
|
|
|
|
2020-07-16 22:19:09 +02:00
|
|
|
return qualityOptions;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default {
|
|
|
|
getVideoQualityOptions,
|
|
|
|
getAudioQualityOptions
|
|
|
|
};
|