mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Move trickplay settings to react
This commit is contained in:
parent
fc664090cc
commit
08f9ec9f01
6 changed files with 326 additions and 146 deletions
|
@ -9,5 +9,6 @@ export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [
|
||||||
{ path: 'users/add', type: AsyncRouteType.Dashboard },
|
{ path: 'users/add', type: AsyncRouteType.Dashboard },
|
||||||
{ path: 'users/parentalcontrol', type: AsyncRouteType.Dashboard },
|
{ path: 'users/parentalcontrol', type: AsyncRouteType.Dashboard },
|
||||||
{ path: 'users/password', type: AsyncRouteType.Dashboard },
|
{ path: 'users/password', type: AsyncRouteType.Dashboard },
|
||||||
{ path: 'users/profile', type: AsyncRouteType.Dashboard }
|
{ path: 'users/profile', type: AsyncRouteType.Dashboard },
|
||||||
|
{ path: 'playback/trickplay', type: AsyncRouteType.Dashboard }
|
||||||
];
|
];
|
||||||
|
|
|
@ -145,11 +145,5 @@ export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [
|
||||||
view: 'dashboard/streaming.html',
|
view: 'dashboard/streaming.html',
|
||||||
controller: 'dashboard/streaming'
|
controller: 'dashboard/streaming'
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
path: 'playback/trickplay',
|
|
||||||
pageProps: {
|
|
||||||
view: 'dashboard/trickplay.html',
|
|
||||||
controller: 'dashboard/trickplay'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
291
src/apps/dashboard/routes/playback/trickplay.tsx
Normal file
291
src/apps/dashboard/routes/playback/trickplay.tsx
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
import type { ProcessPriorityClass, ServerConfiguration, TrickplayScanBehavior } from '@jellyfin/sdk/lib/generated-client';
|
||||||
|
import React, { FunctionComponent, useCallback, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
import globalize from '../../../../scripts/globalize';
|
||||||
|
import Page from '../../../../components/Page';
|
||||||
|
import SectionTitleContainer from '../../../../elements/SectionTitleContainer';
|
||||||
|
import ButtonElement from '../../../../elements/ButtonElement';
|
||||||
|
import CheckBoxElement from '../../../../elements/CheckBoxElement';
|
||||||
|
import SelectElement from '../../../../elements/SelectElement';
|
||||||
|
import InputElement from '../../../../elements/InputElement';
|
||||||
|
import LinkTrickplayAcceleration from '../../../../components/dashboard/playback/trickplay/LinkTrickplayAcceleration';
|
||||||
|
import loading from '../../../../components/loading/loading';
|
||||||
|
import toast from '../../../../components/toast/toast';
|
||||||
|
|
||||||
|
function onSaveComplete() {
|
||||||
|
loading.hide();
|
||||||
|
toast(globalize.translate('SettingsSaved'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const PlaybackTrickplay: FunctionComponent = () => {
|
||||||
|
const element = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const loadConfig = useCallback((config) => {
|
||||||
|
const page = element.current;
|
||||||
|
const options = config.TrickplayOptions;
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
console.error('Unexpected null reference');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(page.querySelector('.chkEnableHwAcceleration') as HTMLInputElement).checked = options.EnableHwAcceleration;
|
||||||
|
(page.querySelector('#selectScanBehavior') as HTMLSelectElement).value = options.ScanBehavior;
|
||||||
|
(page.querySelector('#selectProcessPriority') as HTMLSelectElement).value = options.ProcessPriority;
|
||||||
|
(page.querySelector('#txtInterval') as HTMLInputElement).value = options.Interval;
|
||||||
|
(page.querySelector('#txtWidthResolutions') as HTMLInputElement).value = options.WidthResolutions.join(',');
|
||||||
|
(page.querySelector('#txtTileWidth') as HTMLInputElement).value = options.TileWidth;
|
||||||
|
(page.querySelector('#txtTileHeight') as HTMLInputElement).value = options.TileHeight;
|
||||||
|
(page.querySelector('#txtQscale') as HTMLInputElement).value = options.Qscale;
|
||||||
|
(page.querySelector('#txtJpegQuality') as HTMLInputElement).value = options.JpegQuality;
|
||||||
|
(page.querySelector('#txtProcessThreads') as HTMLInputElement).value = options.ProcessThreads;
|
||||||
|
|
||||||
|
loading.hide();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const loadData = useCallback(() => {
|
||||||
|
loading.show();
|
||||||
|
|
||||||
|
window.ApiClient.getServerConfiguration().then(function (config) {
|
||||||
|
loadConfig(config);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('[playbacktrickplay] failed to fetch server config', err);
|
||||||
|
});
|
||||||
|
}, [loadConfig]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const page = element.current;
|
||||||
|
|
||||||
|
if (!page) {
|
||||||
|
console.error('Unexpected null reference');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveConfig = (config: ServerConfiguration) => {
|
||||||
|
if (!config.TrickplayOptions) {
|
||||||
|
throw new Error('Unexpected null TrickplayOptions');
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = config.TrickplayOptions;
|
||||||
|
options.EnableHwAcceleration = (page.querySelector('.chkEnableHwAcceleration') as HTMLInputElement).checked;
|
||||||
|
options.ScanBehavior = (page.querySelector('#selectScanBehavior') as HTMLSelectElement).value as TrickplayScanBehavior;
|
||||||
|
options.ProcessPriority = (page.querySelector('#selectProcessPriority') as HTMLSelectElement).value as ProcessPriorityClass;
|
||||||
|
options.Interval = Math.max(1, parseInt((page.querySelector('#txtInterval') as HTMLInputElement).value || '10000', 10));
|
||||||
|
options.WidthResolutions = (page.querySelector('#txtWidthResolutions') as HTMLInputElement).value.replace(' ', '').split(',').map(Number);
|
||||||
|
options.TileWidth = Math.max(1, parseInt((page.querySelector('#txtTileWidth') as HTMLInputElement).value || '10', 10));
|
||||||
|
options.TileHeight = Math.max(1, parseInt((page.querySelector('#txtTileHeight') as HTMLInputElement).value || '10', 10));
|
||||||
|
options.Qscale = Math.min(31, parseInt((page.querySelector('#txtQscale') as HTMLInputElement).value || '4', 10));
|
||||||
|
options.JpegQuality = Math.min(100, parseInt((page.querySelector('#txtJpegQuality') as HTMLInputElement).value || '90', 10));
|
||||||
|
options.ProcessThreads = parseInt((page.querySelector('#txtProcessThreads') as HTMLInputElement).value || '1', 10);
|
||||||
|
|
||||||
|
window.ApiClient.updateServerConfiguration(config).then(() => {
|
||||||
|
onSaveComplete();
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('[playbacktrickplay] failed to update config', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSubmit = (e: Event) => {
|
||||||
|
loading.show();
|
||||||
|
|
||||||
|
window.ApiClient.getServerConfiguration().then(function (config) {
|
||||||
|
saveConfig(config);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('[playbacktrickplay] failed to fetch server config', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
(page.querySelector('.trickplayConfigurationForm') as HTMLFormElement).addEventListener('submit', onSubmit);
|
||||||
|
|
||||||
|
loadData();
|
||||||
|
}, [loadData]);
|
||||||
|
|
||||||
|
const optionScanBehavior = () => {
|
||||||
|
let content = '';
|
||||||
|
content += `<option value='NonBlocking'>${globalize.translate('NonBlockingScan')}</option>`;
|
||||||
|
content += `<option value='Blocking'>${globalize.translate('BlockingScan')}</option>`;
|
||||||
|
return content;
|
||||||
|
};
|
||||||
|
|
||||||
|
const optionProcessPriority = () => {
|
||||||
|
let content = '';
|
||||||
|
content += `<option value='High'>${globalize.translate('PriorityHigh')}</option>`;
|
||||||
|
content += `<option value='AboveNormal'>${globalize.translate('PriorityAboveNormal')}</option>`;
|
||||||
|
content += `<option value='Normal'>${globalize.translate('PriorityNormal')}</option>`;
|
||||||
|
content += `<option value='BelowNormal'>${globalize.translate('PriorityBelowNormal')}</option>`;
|
||||||
|
content += `<option value='Idle'>${globalize.translate('PriorityIdle')}</option>`;
|
||||||
|
return content;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Page
|
||||||
|
id='trickplayConfigurationPage'
|
||||||
|
className='mainAnimatedPage type-interior playbackConfigurationPage'
|
||||||
|
>
|
||||||
|
<div ref={element} className='content-primary'>
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<SectionTitleContainer
|
||||||
|
title={globalize.translate('Trickplay')}
|
||||||
|
isLinkVisible={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form className='trickplayConfigurationForm'>
|
||||||
|
<div className='checkboxContainer checkboxContainer-withDescription'>
|
||||||
|
<CheckBoxElement
|
||||||
|
className='chkEnableHwAcceleration'
|
||||||
|
title='LabelTrickplayAccel'
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription checkboxFieldDescription'>
|
||||||
|
<LinkTrickplayAcceleration
|
||||||
|
title='LabelTrickplayAccelHelp'
|
||||||
|
href='#/dashboard/playback/transcoding'
|
||||||
|
className='button-link'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='selectContainer fldSelectScanBehavior'>
|
||||||
|
<SelectElement
|
||||||
|
id='selectScanBehavior'
|
||||||
|
label='LabelScanBehavior'
|
||||||
|
>
|
||||||
|
{optionScanBehavior()}
|
||||||
|
</SelectElement>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelScanBehaviorHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='selectContainer fldSelectProcessPriority'>
|
||||||
|
<SelectElement
|
||||||
|
id='selectProcessPriority'
|
||||||
|
label='LabelProcessPriority'
|
||||||
|
>
|
||||||
|
{optionProcessPriority()}
|
||||||
|
</SelectElement>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelProcessPriorityHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='inputContainer'>
|
||||||
|
<InputElement
|
||||||
|
type='number'
|
||||||
|
id='txtInterval'
|
||||||
|
label='LabelImageInterval'
|
||||||
|
options={'required inputMode="numeric" pattern="[0-9]*" min="1"'}
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelImageIntervalHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='inputContainer'>
|
||||||
|
<InputElement
|
||||||
|
type='text'
|
||||||
|
id='txtWidthResolutions'
|
||||||
|
label='LabelWidthResolutions'
|
||||||
|
options={'required pattern="[0-9,]*"'}
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelWidthResolutionsHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='inputContainer'>
|
||||||
|
<InputElement
|
||||||
|
type='number'
|
||||||
|
id='txtTileWidth'
|
||||||
|
label='LabelTileWidth'
|
||||||
|
options={'required inputMode="numeric" pattern="[0-9]*" min="1"'}
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelTileWidthHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='inputContainer'>
|
||||||
|
<InputElement
|
||||||
|
type='number'
|
||||||
|
id='txtTileHeight'
|
||||||
|
label='LabelTileHeight'
|
||||||
|
options={'required inputMode="numeric" pattern="[0-9]*" min="1"'}
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelTileHeightHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='inputContainer'>
|
||||||
|
<InputElement
|
||||||
|
type='number'
|
||||||
|
id='txtJpegQuality'
|
||||||
|
label='LabelJpegQuality'
|
||||||
|
options={'required inputMode="numeric" pattern="[0-9]*" min="1" max="100"'}
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelJpegQualityHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='inputContainer'>
|
||||||
|
<InputElement
|
||||||
|
type='number'
|
||||||
|
id='txtQscale'
|
||||||
|
label='LabelQscale'
|
||||||
|
options={'required inputMode="numeric" pattern="[0-9]*" min="2" max="31"'}
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelQscaleHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='verticalSection'>
|
||||||
|
<div className='inputContainer'>
|
||||||
|
<InputElement
|
||||||
|
type='number'
|
||||||
|
id='txtProcessThreads'
|
||||||
|
label='LabelTrickplayThreads'
|
||||||
|
options={'required inputMode="numeric" pattern="[0-9]*" min="0"'}
|
||||||
|
/>
|
||||||
|
<div className='fieldDescription'>
|
||||||
|
{globalize.translate('LabelTrickplayThreadsHelp')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ButtonElement
|
||||||
|
type='submit'
|
||||||
|
className='raised button-submit block'
|
||||||
|
title='Save'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PlaybackTrickplay;
|
|
@ -0,0 +1,33 @@
|
||||||
|
import React, { FunctionComponent } from 'react';
|
||||||
|
import globalize from '../../../../scripts/globalize';
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
title?: string;
|
||||||
|
className?: string;
|
||||||
|
href?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createLinkElement = ({ className, title, href }: IProps) => ({
|
||||||
|
__html: `<a
|
||||||
|
is="emby-linkbutton"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="${className}"
|
||||||
|
href="${href}"
|
||||||
|
>
|
||||||
|
${title}
|
||||||
|
</a>`
|
||||||
|
});
|
||||||
|
|
||||||
|
const LinkTrickplayAcceleration: FunctionComponent<IProps> = ({ className, title, href }: IProps) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
dangerouslySetInnerHTML={createLinkElement({
|
||||||
|
className: className,
|
||||||
|
title: globalize.translate(title),
|
||||||
|
href: href
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LinkTrickplayAcceleration;
|
|
@ -1,68 +0,0 @@
|
||||||
<div id="trickplayConfigurationPage" data-role="page" class="page type-interior playbackConfigurationPage withTabs">
|
|
||||||
<div>
|
|
||||||
<div class="content-primary">
|
|
||||||
<form class="trickplayConfigurationForm">
|
|
||||||
<div class="sectionTitleContainer flex align-items-center">
|
|
||||||
<h2 class="sectionTitle">${Trickplay}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="checkboxListContainer">
|
|
||||||
<div class="checkboxList">
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" is="emby-checkbox" id="chkEnableHwAcceleration" />
|
|
||||||
<span>${LabelTrickplayAccel}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="fieldDescription">
|
|
||||||
<a is="emby-linkbutton" rel="noopener noreferrer" class="button-link" href="#/dashboard/playback/transcoding">${LabelTrickplayAccelHelp}</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<select is="emby-select" id="selectScanBehavior" name="Scan Behavior" label="${LabelScanBehavior}">
|
|
||||||
<option id="optNonBlocking" value="NonBlocking">${NonBlockingScan}</option>
|
|
||||||
<option id="optBlocking" value="Blocking">${BlockingScan}</option>
|
|
||||||
</select>
|
|
||||||
<div class="fieldDescription">${LabelScanBehaviorHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<select is="emby-select" id="selectProcessPriority" name="Process Priority" label="${LabelProcessPriority}">
|
|
||||||
<option id="optPriorityHigh" value="High">${PriorityHigh}</option>
|
|
||||||
<option id="optPriorityAboveNormal" value="AboveNormal">${PriorityAboveNormal}</option>
|
|
||||||
<option id="optPriorityNormal" value="Normal">${PriorityNormal}</option>
|
|
||||||
<option id="optPriorityBelowNormal" value="BelowNormal">${PriorityBelowNormal}</option>
|
|
||||||
<option id="optPriorityIdle" value="Idle">${PriorityIdle}</option>
|
|
||||||
</select>
|
|
||||||
<div class="fieldDescription">${LabelProcessPriorityHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" type="number" id="txtInterval" pattern="[0-9]*" min="0" required label="${LabelImageInterval}" />
|
|
||||||
<div class="fieldDescription">${LabelImageIntervalHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" id="txtWidthResolutions" pattern="[0-9,]*" required label="${LabelWidthResolutions}">
|
|
||||||
<div class="fieldDescription">${LabelWidthResolutionsHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" type="number" id="txtTileWidth" pattern="[0-9]*" min="1" required label="${LabelTileWidth}">
|
|
||||||
<div class="fieldDescription">${LabelTileWidthHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" type="number" id="txtTileHeight" pattern="[0-9]*" min="1" required label="${LabelTileHeight}">
|
|
||||||
<div class="fieldDescription">${LabelTileHeightHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" type="number" id="txtJpegQuality" pattern="[0-9]*" min="1" max="100" required label="${LabelJpegQuality}">
|
|
||||||
<div class="fieldDescription">${LabelJpegQualityHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" type="number" id="txtQscale" pattern="[0-9]*" min="2" max="31" required label="${LabelQscale}">
|
|
||||||
<div class="fieldDescription">${LabelQscaleHelp}</div>
|
|
||||||
</div>
|
|
||||||
<div class="inputContainer">
|
|
||||||
<input is="emby-input" type="number" id="txtProcessThreads" pattern="[0-9]*" required="" label="${LabelTrickplayThreads}">
|
|
||||||
<div class="fieldDescription"></div>
|
|
||||||
</div>
|
|
||||||
<div><button is="emby-button" type="submit" class="raised button-submit block"><span>${Save}</span></button></div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,71 +0,0 @@
|
||||||
import 'jquery';
|
|
||||||
import loading from '../../components/loading/loading';
|
|
||||||
import libraryMenu from '../../scripts/libraryMenu';
|
|
||||||
import globalize from '../../scripts/globalize';
|
|
||||||
import Dashboard from '../../utils/dashboard';
|
|
||||||
|
|
||||||
function loadPage(page, config) {
|
|
||||||
const trickplayOptions = config.TrickplayOptions;
|
|
||||||
|
|
||||||
page.querySelector('#chkEnableHwAcceleration').checked = trickplayOptions.EnableHwAcceleration;
|
|
||||||
$('#selectScanBehavior', page).val(trickplayOptions.ScanBehavior);
|
|
||||||
$('#selectProcessPriority', page).val(trickplayOptions.ProcessPriority);
|
|
||||||
$('#txtInterval', page).val(trickplayOptions.Interval);
|
|
||||||
$('#txtWidthResolutions', page).val(trickplayOptions.WidthResolutions.join(','));
|
|
||||||
$('#txtTileWidth', page).val(trickplayOptions.TileWidth);
|
|
||||||
$('#txtTileHeight', page).val(trickplayOptions.TileHeight);
|
|
||||||
$('#txtQscale', page).val(trickplayOptions.Qscale);
|
|
||||||
$('#txtJpegQuality', page).val(trickplayOptions.JpegQuality);
|
|
||||||
$('#txtProcessThreads', page).val(trickplayOptions.ProcessThreads);
|
|
||||||
loading.hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSubmit() {
|
|
||||||
loading.show();
|
|
||||||
const form = this;
|
|
||||||
ApiClient.getServerConfiguration().then(function (config) {
|
|
||||||
const trickplayOptions = config.TrickplayOptions;
|
|
||||||
|
|
||||||
trickplayOptions.EnableHwAcceleration = form.querySelector('#chkEnableHwAcceleration').checked;
|
|
||||||
trickplayOptions.ScanBehavior = $('#selectScanBehavior', form).val();
|
|
||||||
trickplayOptions.ProcessPriority = $('#selectProcessPriority', form).val();
|
|
||||||
trickplayOptions.Interval = Math.max(0, parseInt($('#txtInterval', form).val() || '10000', 10));
|
|
||||||
trickplayOptions.WidthResolutions = $('#txtWidthResolutions', form).val().replace(' ', '').split(',').map(Number);
|
|
||||||
trickplayOptions.TileWidth = Math.max(1, parseInt($('#txtTileWidth', form).val() || '10', 10));
|
|
||||||
trickplayOptions.TileHeight = Math.max(1, parseInt($('#txtTileHeight', form).val() || '10', 10));
|
|
||||||
trickplayOptions.Qscale = Math.min(31, parseInt($('#txtQscale', form).val() || '10', 10));
|
|
||||||
trickplayOptions.JpegQuality = Math.min(100, parseInt($('#txtJpegQuality', form).val() || '80', 10));
|
|
||||||
trickplayOptions.ProcessThreads = parseInt($('#txtProcessThreads', form).val() || '0', 10);
|
|
||||||
|
|
||||||
ApiClient.updateServerConfiguration(config).then(Dashboard.processServerConfigurationUpdateResult);
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTabs() {
|
|
||||||
return [{
|
|
||||||
href: '#/dashboard/playback/transcoding',
|
|
||||||
name: globalize.translate('Transcoding')
|
|
||||||
}, {
|
|
||||||
href: '#/dashboard/playback/resume',
|
|
||||||
name: globalize.translate('ButtonResume')
|
|
||||||
}, {
|
|
||||||
href: '#/dashboard/playback/streaming',
|
|
||||||
name: globalize.translate('TabStreaming')
|
|
||||||
}, {
|
|
||||||
href: '#/dashboard/playback/trickplay',
|
|
||||||
name: globalize.translate('Trickplay')
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).on('pageinit', '#trickplayConfigurationPage', function () {
|
|
||||||
$('.trickplayConfigurationForm').off('submit', onSubmit).on('submit', onSubmit);
|
|
||||||
}).on('pageshow', '#trickplayConfigurationPage', function () {
|
|
||||||
loading.show();
|
|
||||||
libraryMenu.setTabs('playback', 3, getTabs);
|
|
||||||
const page = this;
|
|
||||||
ApiClient.getServerConfiguration().then(function (config) {
|
|
||||||
loadPage(page, config);
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Add table
Add a link
Reference in a new issue