mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-18 03:18:19 -07:00
Add maximum allowed video resolution selector
This commit is contained in:
parent
0bd774dd45
commit
f06cd961d5
@ -39,7 +39,8 @@ function getDeviceProfile(item) {
|
|||||||
profile = profileBuilder(builderOpts);
|
profile = profileBuilder(builderOpts);
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxTranscodingVideoWidth = appHost.screen()?.maxAllowedWidth;
|
const maxVideoWidth = appSettings.maxVideoWidth();
|
||||||
|
const maxTranscodingVideoWidth = maxVideoWidth < 0 ? appHost.screen()?.maxAllowedWidth : maxVideoWidth;
|
||||||
|
|
||||||
if (maxTranscodingVideoWidth) {
|
if (maxTranscodingVideoWidth) {
|
||||||
profile.TranscodingProfiles.forEach((transcodingProfile) => {
|
profile.TranscodingProfiles.forEach((transcodingProfile) => {
|
||||||
|
@ -41,7 +41,7 @@ import template from './playbackSettings.template.html';
|
|||||||
select.innerHTML = html;
|
select.innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMaxBitrateIntoField(select, isInNetwork, mediatype) {
|
function fillQuality(select, isInNetwork, mediatype, maxVideoWidth) {
|
||||||
const options = mediatype === 'Audio' ? qualityoptions.getAudioQualityOptions({
|
const options = mediatype === 'Audio' ? qualityoptions.getAudioQualityOptions({
|
||||||
|
|
||||||
currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype),
|
currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype),
|
||||||
@ -52,7 +52,8 @@ import template from './playbackSettings.template.html';
|
|||||||
|
|
||||||
currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype),
|
currentMaxBitrate: appSettings.maxStreamingBitrate(isInNetwork, mediatype),
|
||||||
isAutomaticBitrateEnabled: appSettings.enableAutomaticBitrateDetection(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
|
// render empty string instead of 0 for the auto option
|
||||||
return `<option value="${i.bitrate || ''}">${i.name}</option>`;
|
return `<option value="${i.bitrate || ''}">${i.name}</option>`;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMaxBitrateIntoField(select, isInNetwork, mediatype) {
|
||||||
|
fillQuality(select, isInNetwork, mediatype);
|
||||||
|
|
||||||
if (appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype)) {
|
if (appSettings.enableAutomaticBitrateDetection(isInNetwork, mediatype)) {
|
||||||
select.value = '';
|
select.value = '';
|
||||||
@ -68,12 +73,13 @@ import template from './playbackSettings.template.html';
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillChromecastQuality(select) {
|
function fillChromecastQuality(select, maxVideoWidth) {
|
||||||
const options = qualityoptions.getVideoQualityOptions({
|
const options = qualityoptions.getVideoQualityOptions({
|
||||||
|
|
||||||
currentMaxBitrate: appSettings.maxChromecastBitrate(),
|
currentMaxBitrate: appSettings.maxChromecastBitrate(),
|
||||||
isAutomaticBitrateEnabled: !appSettings.maxChromecastBitrate(),
|
isAutomaticBitrateEnabled: !appSettings.maxChromecastBitrate(),
|
||||||
enableAuto: true
|
enableAuto: true,
|
||||||
|
maxVideoWidth
|
||||||
});
|
});
|
||||||
|
|
||||||
select.innerHTML = options.map(i => {
|
select.innerHTML = options.map(i => {
|
||||||
@ -192,6 +198,9 @@ import template from './playbackSettings.template.html';
|
|||||||
const selectChromecastVersion = context.querySelector('.selectChromecastVersion');
|
const selectChromecastVersion = context.querySelector('.selectChromecastVersion');
|
||||||
selectChromecastVersion.value = userSettings.chromecastVersion();
|
selectChromecastVersion.value = userSettings.chromecastVersion();
|
||||||
|
|
||||||
|
const selectLabelMaxVideoWidth = context.querySelector('.selectLabelMaxVideoWidth');
|
||||||
|
selectLabelMaxVideoWidth.value = appSettings.maxVideoWidth();
|
||||||
|
|
||||||
const selectSkipForwardLength = context.querySelector('.selectSkipForwardLength');
|
const selectSkipForwardLength = context.querySelector('.selectSkipForwardLength');
|
||||||
fillSkipLengths(selectSkipForwardLength);
|
fillSkipLengths(selectSkipForwardLength);
|
||||||
selectSkipForwardLength.value = userSettings.skipForwardLength();
|
selectSkipForwardLength.value = userSettings.skipForwardLength();
|
||||||
@ -209,6 +218,7 @@ import template from './playbackSettings.template.html';
|
|||||||
appSettings.enableSystemExternalPlayers(context.querySelector('.chkExternalVideoPlayer').checked);
|
appSettings.enableSystemExternalPlayers(context.querySelector('.chkExternalVideoPlayer').checked);
|
||||||
|
|
||||||
appSettings.maxChromecastBitrate(context.querySelector('.selectChromecastVideoQuality').value);
|
appSettings.maxChromecastBitrate(context.querySelector('.selectChromecastVideoQuality').value);
|
||||||
|
appSettings.maxVideoWidth(context.querySelector('.selectLabelMaxVideoWidth').value);
|
||||||
|
|
||||||
setMaxBitrateFromField(context.querySelector('.selectVideoInNetworkQuality'), true, 'Video');
|
setMaxBitrateFromField(context.querySelector('.selectVideoInNetworkQuality'), true, 'Video');
|
||||||
setMaxBitrateFromField(context.querySelector('.selectVideoInternetQuality'), false, '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) {
|
function onSubmit(e) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const apiClient = ServerConnections.getApiClient(self.options.serverId);
|
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('.btnSave').classList.remove('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.element.querySelector('.selectLabelMaxVideoWidth').addEventListener('change', onMaxVideoWidthChange.bind(self));
|
||||||
|
|
||||||
self.loadData();
|
self.loadData();
|
||||||
|
|
||||||
if (options.autoFocus) {
|
if (options.autoFocus) {
|
||||||
|
@ -41,6 +41,19 @@
|
|||||||
<div class="selectContainer fldChromecastQuality hide">
|
<div class="selectContainer fldChromecastQuality hide">
|
||||||
<select is="emby-select" class="selectChromecastVideoQuality" label="${LabelMaxChromecastBitrate}"></select>
|
<select is="emby-select" class="selectChromecastVideoQuality" label="${LabelMaxChromecastBitrate}"></select>
|
||||||
</div>
|
</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>
|
||||||
|
|
||||||
<div class="verticalSection verticalSection-extrabottompadding musicQualitySection hide">
|
<div class="verticalSection verticalSection-extrabottompadding musicQualitySection hide">
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { appHost } from '../components/apphost';
|
import { appHost } from '../components/apphost';
|
||||||
import globalize from '../scripts/globalize';
|
import globalize from '../scripts/globalize';
|
||||||
|
import appSettings from '../scripts/settings/appSettings';
|
||||||
|
|
||||||
export function getVideoQualityOptions(options) {
|
export function getVideoQualityOptions(options) {
|
||||||
const maxStreamingBitrate = options.currentMaxBitrate;
|
const maxStreamingBitrate = options.currentMaxBitrate;
|
||||||
@ -12,7 +13,9 @@ export function getVideoQualityOptions(options) {
|
|||||||
videoWidth = videoHeight * (16 / 9);
|
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 maxAllowedWidth = videoWidth || 4096;
|
||||||
|
|
||||||
const qualityOptions = [];
|
const qualityOptions = [];
|
||||||
|
@ -92,6 +92,19 @@ class AppSettings {
|
|||||||
return val ? parseInt(val) : null;
|
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) {
|
set(name, value, userId) {
|
||||||
const currentValue = this.get(name, userId);
|
const currentValue = this.get(name, userId);
|
||||||
AppStorage.setItem(this.#getKey(name, userId), value);
|
AppStorage.setItem(this.#getKey(name, userId), value);
|
||||||
|
@ -708,6 +708,7 @@
|
|||||||
"LabelLibraryPageSizeHelp": "Set the amount of items to show on a library page. Set to 0 in order to disable paging.",
|
"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':",
|
"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.",
|
"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:",
|
"LabelLineup": "Lineup:",
|
||||||
"LabelLocalCustomCss": "Custom CSS code for styling which applies to this client only. You may want to disable server custom CSS code.",
|
"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:",
|
"LabelLocalHttpServerPortNumber": "Local HTTP port number:",
|
||||||
@ -1377,6 +1378,7 @@
|
|||||||
"ScanForNewAndUpdatedFiles": "Scan for new and updated files",
|
"ScanForNewAndUpdatedFiles": "Scan for new and updated files",
|
||||||
"ScanLibrary": "Scan library",
|
"ScanLibrary": "Scan library",
|
||||||
"Schedule": "Schedule",
|
"Schedule": "Schedule",
|
||||||
|
"ScreenResolution": "Screen Resolution",
|
||||||
"Screenshot": "Screenshot",
|
"Screenshot": "Screenshot",
|
||||||
"Screenshots": "Screenshots",
|
"Screenshots": "Screenshots",
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
|
Loading…
Reference in New Issue
Block a user