mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Add trickplay functionality
This commit is contained in:
parent
675a59adc4
commit
8045b95d93
16 changed files with 335 additions and 8 deletions
|
@ -135,6 +135,12 @@
|
|||
<span>${AllowAv1Encoding}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="checkboxList">
|
||||
<label>
|
||||
<input type="checkbox" is="emby-checkbox" id="chkAllowMjpegEncoding" />
|
||||
<span>${AllowMjpegEncoding}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="vppTonemappingOptions hide">
|
||||
|
|
|
@ -19,6 +19,7 @@ function loadPage(page, config, systemInfo) {
|
|||
page.querySelector('#chkHardwareEncoding').checked = config.EnableHardwareEncoding;
|
||||
page.querySelector('#chkAllowHevcEncoding').checked = config.AllowHevcEncoding;
|
||||
page.querySelector('#chkAllowAv1Encoding').checked = config.AllowAv1Encoding;
|
||||
page.querySelector('#chkAllowMjpegEncoding').checked = config.AllowMjpegEncoding;
|
||||
$('#selectVideoDecoder', page).val(config.HardwareAccelerationType);
|
||||
$('#selectThreadCount', page).val(config.EncodingThreadCount);
|
||||
page.querySelector('#chkEnableAudioVbr').checked = config.EnableAudioVbr;
|
||||
|
@ -125,6 +126,7 @@ function onSubmit() {
|
|||
config.EnableHardwareEncoding = form.querySelector('#chkHardwareEncoding').checked;
|
||||
config.AllowHevcEncoding = form.querySelector('#chkAllowHevcEncoding').checked;
|
||||
config.AllowAv1Encoding = form.querySelector('#chkAllowAv1Encoding').checked;
|
||||
config.AllowMjpegEncoding = form.querySelector('#chkAllowMjpegEncoding').checked;
|
||||
ApiClient.updateNamedConfiguration('encoding', config).then(function () {
|
||||
updateEncoder(form);
|
||||
}, function () {
|
||||
|
@ -175,6 +177,9 @@ function getTabs() {
|
|||
}, {
|
||||
href: '#/dashboard/playback/streaming',
|
||||
name: globalize.translate('TabStreaming')
|
||||
}, {
|
||||
href: '#/dashboard/playback/trickplay',
|
||||
name: globalize.translate('Trickplay')
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@ function getTabs() {
|
|||
}, {
|
||||
href: '#/dashboard/playback/streaming',
|
||||
name: globalize.translate('TabStreaming')
|
||||
}, {
|
||||
href: '#/dashboard/playback/trickplay',
|
||||
name: globalize.translate('Trickplay')
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -52,4 +55,3 @@ $(document).on('pageinit', '#playbackConfigurationPage', function () {
|
|||
loadPage(page, config);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ function getTabs() {
|
|||
}, {
|
||||
href: '#/dashboard/playback/streaming',
|
||||
name: globalize.translate('TabStreaming')
|
||||
}, {
|
||||
href: '#/dashboard/playback/trickplay',
|
||||
name: globalize.translate('Trickplay')
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
65
src/controllers/dashboard/trickplay.html
Normal file
65
src/controllers/dashboard/trickplay.html
Normal file
|
@ -0,0 +1,65 @@
|
|||
<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>${TrickplayHardwareAccel}</span>
|
||||
</label>
|
||||
</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>
|
71
src/controllers/dashboard/trickplay.js
Normal file
71
src/controllers/dashboard/trickplay.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
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