Add maximum allowed video resolution selector

This commit is contained in:
Dmitry Lyzo 2022-06-17 00:17:10 +03:00
parent 0bd774dd45
commit f06cd961d5
6 changed files with 80 additions and 6 deletions

View File

@ -39,7 +39,8 @@ function getDeviceProfile(item) {
profile = profileBuilder(builderOpts);
}
const maxTranscodingVideoWidth = appHost.screen()?.maxAllowedWidth;
const maxVideoWidth = appSettings.maxVideoWidth();
const maxTranscodingVideoWidth = maxVideoWidth < 0 ? appHost.screen()?.maxAllowedWidth : maxVideoWidth;
if (maxTranscodingVideoWidth) {
profile.TranscodingProfiles.forEach((transcodingProfile) => {

View File

@ -41,7 +41,7 @@ import template from './playbackSettings.template.html';
select.innerHTML = html;
}
function setMaxBitrateIntoField(select, isInNetwork, mediatype) {
function fillQuality(select, isInNetwork, mediatype, maxVideoWidth) {
const options = mediatype === 'Audio' ? qualityoptions.getAudioQualityOptions({
currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype),
@ -52,7 +52,8 @@ import template from './playbackSettings.template.html';
currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype),
isAutomaticBitrateEnabled: appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype),
enableAuto: true
enableAuto: true,
maxVideoWidth
});
@ -60,6 +61,10 @@ import template from './playbackSettings.template.html';
// render empty string instead of 0 for the auto option
return `<option value="${i.bitrate || ''}">${i.name}</option>`;
}).join('');
}
function setMaxBitrateIntoField(select, isInNetwork, mediatype) {
fillQuality(select, isInNetwork, mediatype);
if (appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype)) {
select.value = '';
@ -68,12 +73,13 @@ import template from './playbackSettings.template.html';
}
}
function fillChromecastQuality(select) {
function fillChromecastQuality(select, maxVideoWidth) {
const options = qualityoptions.getVideoQualityOptions({
currentMaxBitrate: appSettings.maxChromecastBitrate(),
isAutomaticBitrateEnabled: !appSettings.maxChromecastBitrate(),
enableAuto: true
enableAuto: true,
maxVideoWidth
});
select.innerHTML = options.map(i => {
@ -192,6 +198,9 @@ import template from './playbackSettings.template.html';
const selectChromecastVersion = context.querySelector('.selectChromecastVersion');
selectChromecastVersion.value = userSettings.chromecastVersion();
const selectLabelMaxVideoWidth = context.querySelector('.selectLabelMaxVideoWidth');
selectLabelMaxVideoWidth.value = appSettings.maxVideoWidth();
const selectSkipForwardLength = context.querySelector('.selectSkipForwardLength');
fillSkipLengths(selectSkipForwardLength);
selectSkipForwardLength.value = userSettings.skipForwardLength();
@ -209,6 +218,7 @@ import template from './playbackSettings.template.html';
appSettings.enableSystemExternalPlayers(context.querySelector('.chkExternalVideoPlayer').checked);
appSettings.maxChromecastBitrate(context.querySelector('.selectChromecastVideoQuality').value);
appSettings.maxVideoWidth(context.querySelector('.selectLabelMaxVideoWidth').value);
setMaxBitrateFromField(context.querySelector('.selectVideoInNetworkQuality'), true, 'Video');
setMaxBitrateFromField(context.querySelector('.selectVideoInternetQuality'), false, 'Video');
@ -247,6 +257,36 @@ import template from './playbackSettings.template.html';
});
}
function setSelectValue(select, value, defaultValue) {
select.value = value;
if (select.selectedIndex < 0) {
select.value = defaultValue;
}
}
function onMaxVideoWidthChange(e) {
const context = this.options.element;
const selectVideoInNetworkQuality = context.querySelector('.selectVideoInNetworkQuality');
const selectVideoInternetQuality = context.querySelector('.selectVideoInternetQuality');
const selectChromecastVideoQuality = context.querySelector('.selectChromecastVideoQuality');
const selectVideoInNetworkQualityValue = selectVideoInNetworkQuality.value;
const selectVideoInternetQualityValue = selectVideoInternetQuality.value;
const selectChromecastVideoQualityValue = selectChromecastVideoQuality.value;
const maxVideoWidth = parseInt(e.target.value || '0', 10) || 0;
fillQuality(selectVideoInNetworkQuality, true, 'Video', maxVideoWidth);
fillQuality(selectVideoInternetQuality, false, 'Video', maxVideoWidth);
fillChromecastQuality(selectChromecastVideoQuality, maxVideoWidth);
setSelectValue(selectVideoInNetworkQuality, selectVideoInNetworkQualityValue, '');
setSelectValue(selectVideoInternetQuality, selectVideoInternetQualityValue, '');
setSelectValue(selectChromecastVideoQuality, selectChromecastVideoQualityValue, '');
}
function onSubmit(e) {
const self = this;
const apiClient = ServerConnections.getApiClient(self.options.serverId);
@ -274,6 +314,8 @@ import template from './playbackSettings.template.html';
options.element.querySelector('.btnSave').classList.remove('hide');
}
options.element.querySelector('.selectLabelMaxVideoWidth').addEventListener('change', onMaxVideoWidthChange.bind(self));
self.loadData();
if (options.autoFocus) {

View File

@ -41,6 +41,19 @@
<div class="selectContainer fldChromecastQuality hide">
<select is="emby-select" class="selectChromecastVideoQuality" label="${LabelMaxChromecastBitrate}"></select>
</div>
<div class="selectContainer">
<select is="emby-select" class="selectLabelMaxVideoWidth" label="${LabelMaxVideoResolution}">
<option value="0">${Auto}</option>
<option value="-1">${ScreenResolution}</option>
<option value="640">360p</option>
<option value="852">480p</option>
<option value="1280">720p</option>
<option value="1920">1080p</option>
<option value="3840">4K</option>
<option value="7680">8K</option>
</select>
</div>
</div>
<div class="verticalSection verticalSection-extrabottompadding musicQualitySection hide">

View File

@ -1,5 +1,6 @@
import { appHost } from '../components/apphost';
import globalize from '../scripts/globalize';
import appSettings from '../scripts/settings/appSettings';
export function getVideoQualityOptions(options) {
const maxStreamingBitrate = options.currentMaxBitrate;
@ -12,7 +13,9 @@ export function getVideoQualityOptions(options) {
videoWidth = videoHeight * (16 / 9);
}
const hostScreenWidth = appHost.screen()?.maxAllowedWidth || 4096;
const maxVideoWidth = options.maxVideoWidth == null ? appSettings.maxVideoWidth() : options.maxVideoWidth;
const hostScreenWidth = (maxVideoWidth < 0 ? appHost.screen()?.maxAllowedWidth : maxVideoWidth) || 4096;
const maxAllowedWidth = videoWidth || 4096;
const qualityOptions = [];

View File

@ -92,6 +92,19 @@ class AppSettings {
return val ? parseInt(val) : null;
}
/**
* Get or set 'Maximum video width'
* @param {number|undefined} val - Maximum video width or undefined.
* @return {number} Maximum video width.
*/
maxVideoWidth(val) {
if (val !== undefined) {
return this.set('maxVideoWidth', val.toString());
}
return parseInt(this.get('maxVideoWidth') || '0', 10) || 0;
}
set(name, value, userId) {
const currentValue = this.get(name, userId);
AppStorage.setItem(this.#getKey(name, userId), value);

View File

@ -708,6 +708,7 @@
"LabelLibraryPageSizeHelp": "Set the amount of items to show on a library page. Set to 0 in order to disable paging.",
"LabelMaxDaysForNextUp": "Max days in 'Next Up':",
"LabelMaxDaysForNextUpHelp": "Set the maximum amount of days a show should stay in the 'Next Up' list without watching it.",
"LabelMaxVideoResolution": "Maximum Allowed Video Transcoding Resolution",
"LabelLineup": "Lineup:",
"LabelLocalCustomCss": "Custom CSS code for styling which applies to this client only. You may want to disable server custom CSS code.",
"LabelLocalHttpServerPortNumber": "Local HTTP port number:",
@ -1377,6 +1378,7 @@
"ScanForNewAndUpdatedFiles": "Scan for new and updated files",
"ScanLibrary": "Scan library",
"Schedule": "Schedule",
"ScreenResolution": "Screen Resolution",
"Screenshot": "Screenshot",
"Screenshots": "Screenshots",
"Search": "Search",