Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separate bitrate control from resolution #6071

Merged
merged 9 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/playback/playersettingsmenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ function showQualityMenu(player, btn) {
})[0];
const videoWidth = videoStream ? videoStream.Width : null;
const videoHeight = videoStream ? videoStream.Height : null;
const videoBitRate = videoStream ? videoStream.BitRate : null;

const options = qualityoptions.getVideoQualityOptions({
currentMaxBitrate: playbackManager.getMaxStreamingBitrate(player),
isAutomaticBitrateEnabled: playbackManager.enableAutomaticBitrateDetection(player),
videoWidth: videoWidth,
videoHeight: videoHeight,
videoBitRate,
enableAuto: true
});

Expand Down
66 changes: 29 additions & 37 deletions src/components/qualityOptions.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { appHost } from '../components/apphost';
import minBy from 'lodash-es/minBy';
import globalize from '../lib/globalize';
import appSettings from '../scripts/settings/appSettings';

export function getVideoQualityOptions(options) {
const maxStreamingBitrate = options.currentMaxBitrate;
let videoWidth = options.videoWidth;
const videoHeight = options.videoHeight;
const videoBitRate = options.videoBitRate ?? -1;

// If the aspect ratio is less than 16/9 (1.77), set the width as if it were pillarboxed.
// 4:3 1440x1080 -> 1920x1080
if (videoWidth / videoHeight < 16 / 9) {
videoWidth = videoHeight * (16 / 9);
}

const maxVideoWidth = options.maxVideoWidth == null ? appSettings.maxVideoWidth() : options.maxVideoWidth;

const hostScreenWidth = (maxVideoWidth < 0 ? appHost.screen()?.maxAllowedWidth : maxVideoWidth) || 4096;
const maxAllowedWidth = videoWidth || 4096;
// 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 },
{ name: '420 kbps', maxHeight: 360, bitrate: 420000 }
];

const qualityOptions = [];

Expand All @@ -30,31 +36,17 @@ export function getVideoQualityOptions(options) {
qualityOptions.push(autoQualityOption);
}

// 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)
if (maxAllowedWidth >= 3800 && hostScreenWidth >= 1930) {
qualityOptions.push({ name: '4K - 120 Mbps', maxHeight: 2160, bitrate: 120000000 });
qualityOptions.push({ name: '4K - 80 Mbps', maxHeight: 2160, bitrate: 80000000 });
}
// Some 1080- videos are reported as 1912?
if (maxAllowedWidth >= 1900 && hostScreenWidth >= 1290) {
qualityOptions.push({ name: '1080p - 60 Mbps', maxHeight: 1080, bitrate: 60000000 });
qualityOptions.push({ name: '1080p - 40 Mbps', maxHeight: 1080, bitrate: 40000000 });
qualityOptions.push({ name: '1080p - 20 Mbps', maxHeight: 1080, bitrate: 20000000 });
qualityOptions.push({ name: '1080p - 15 Mbps', maxHeight: 1080, bitrate: 15000000 });
qualityOptions.push({ name: '1080p - 10 Mbps', maxHeight: 1080, bitrate: 10000000 });
}
if (maxAllowedWidth >= 1260 && hostScreenWidth >= 650) {
qualityOptions.push({ name: '720p - 8 Mbps', maxHeight: 720, bitrate: 8000000 });
qualityOptions.push({ name: '720p - 6 Mbps', maxHeight: 720, bitrate: 6000000 });
qualityOptions.push({ name: '720p - 4 Mbps', maxHeight: 720, bitrate: 4000000 });
}
if (maxAllowedWidth >= 620) {
qualityOptions.push({ name: '480p - 3 Mbps', maxHeight: 480, bitrate: 3000000 });
qualityOptions.push({ name: '480p - 1.5 Mbps', maxHeight: 480, bitrate: 1500000 });
qualityOptions.push({ name: '480p - 720 kbps', maxHeight: 480, bitrate: 720000 });
if (videoBitRate > 0 && videoBitRate < bitrateConfigurations[0].bitrate) {
// Push one entry that has higher limit than video bitrate to allow using source bitrate when Auto is also limited
const sourceOptions = minBy(bitrateConfigurations.filter((c) => c.bitrate > videoBitRate), (x) => x.bitrate);
qualityOptions.push(sourceOptions);
gnattu marked this conversation as resolved.
Show resolved Hide resolved
}

qualityOptions.push({ name: '360p - 420 kbps', maxHeight: 360, bitrate: 420000 });
bitrateConfigurations.forEach((c) => {
if (videoBitRate <= 0 || c.bitrate <= videoBitRate) {
qualityOptions.push(c);
}
});

if (maxStreamingBitrate) {
let selectedIndex = qualityOptions.length - 1;
Expand Down
Loading