1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge branch 'unstable' into show-mobile-seek

This commit is contained in:
Ian Walton 2020-08-25 22:19:59 -04:00
commit 201685a60b
137 changed files with 3677 additions and 4123 deletions

View file

@ -1,3 +1,5 @@
const restrictedGlobals = require('confusing-browser-globals');
module.exports = { module.exports = {
root: true, root: true,
plugins: [ plugins: [
@ -39,14 +41,15 @@ module.exports = {
'no-floating-decimal': ['error'], 'no-floating-decimal': ['error'],
'no-multi-spaces': ['error'], 'no-multi-spaces': ['error'],
'no-multiple-empty-lines': ['error', { 'max': 1 }], 'no-multiple-empty-lines': ['error', { 'max': 1 }],
'no-restricted-globals': ['error'].concat(restrictedGlobals),
'no-trailing-spaces': ['error'], 'no-trailing-spaces': ['error'],
'no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }], '@babel/no-unused-expressions': ['error', { 'allowShortCircuit': true, 'allowTernary': true, 'allowTaggedTemplates': true }],
'no-unused-vars': ['error', { 'vars': 'all', 'args': 'none', 'ignoreRestSiblings': true }], //'no-unused-vars': ['error', { 'vars': 'all', 'args': 'none', 'ignoreRestSiblings': true }],
'one-var': ['error', 'never'], 'one-var': ['error', 'never'],
'padded-blocks': ['error', 'never'], 'padded-blocks': ['error', 'never'],
//'prefer-const': ['error', {'destructuring': 'all'}], //'prefer-const': ['error', {'destructuring': 'all'}],
'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }], 'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }],
'semi': ['error'], '@babel/semi': ['error'],
'space-before-blocks': ['error'], 'space-before-blocks': ['error'],
'space-infix-ops': 'error', 'space-infix-ops': 'error',
'yoda': 'error' 'yoda': 'error'
@ -106,6 +109,7 @@ module.exports = {
// TODO: Fix warnings and remove these rules // TODO: Fix warnings and remove these rules
'no-redeclare': ['off'], 'no-redeclare': ['off'],
'no-useless-escape': ['off'], 'no-useless-escape': ['off'],
'no-unused-vars': ['off'],
// TODO: Remove after ES6 migration is complete // TODO: Remove after ES6 migration is complete
'import/no-unresolved': ['off'] 'import/no-unresolved': ['off']
}, },

View file

@ -5,8 +5,8 @@
"repository": "https://github.com/jellyfin/jellyfin-web", "repository": "https://github.com/jellyfin/jellyfin-web",
"license": "GPL-2.0-or-later", "license": "GPL-2.0-or-later",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.11.1", "@babel/core": "^7.11.4",
"@babel/eslint-parser": "^7.11.3", "@babel/eslint-parser": "^7.11.4",
"@babel/eslint-plugin": "^7.11.3", "@babel/eslint-plugin": "^7.11.3",
"@babel/plugin-proposal-class-properties": "^7.10.1", "@babel/plugin-proposal-class-properties": "^7.10.1",
"@babel/plugin-proposal-private-methods": "^7.10.1", "@babel/plugin-proposal-private-methods": "^7.10.1",
@ -16,8 +16,9 @@
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"browser-sync": "^2.26.12", "browser-sync": "^2.26.12",
"confusing-browser-globals": "^1.0.9",
"copy-webpack-plugin": "^5.1.1", "copy-webpack-plugin": "^5.1.1",
"css-loader": "^4.2.1", "css-loader": "^4.2.2",
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"del": "^5.1.0", "del": "^5.1.0",
"eslint": "^7.7.0", "eslint": "^7.7.0",
@ -38,7 +39,7 @@
"gulp-postcss": "^8.0.0", "gulp-postcss": "^8.0.0",
"gulp-sass": "^4.0.2", "gulp-sass": "^4.0.2",
"gulp-sourcemaps": "^2.6.5", "gulp-sourcemaps": "^2.6.5",
"gulp-terser": "^1.3.2", "gulp-terser": "^1.4.0",
"html-webpack-plugin": "^4.3.0", "html-webpack-plugin": "^4.3.0",
"lazypipe": "^1.0.2", "lazypipe": "^1.0.2",
"node-sass": "^4.13.1", "node-sass": "^4.13.1",
@ -63,7 +64,7 @@
"fast-text-encoding": "^1.0.3", "fast-text-encoding": "^1.0.3",
"flv.js": "^1.5.0", "flv.js": "^1.5.0",
"headroom.js": "^0.11.0", "headroom.js": "^0.11.0",
"hls.js": "^0.14.8", "hls.js": "^0.14.9",
"howler": "^2.2.0", "howler": "^2.2.0",
"intersection-observer": "^0.11.0", "intersection-observer": "^0.11.0",
"jellyfin-apiclient": "^1.4.1", "jellyfin-apiclient": "^1.4.1",
@ -96,6 +97,7 @@
"src/components/alphaPicker/alphaPicker.js", "src/components/alphaPicker/alphaPicker.js",
"src/components/appFooter/appFooter.js", "src/components/appFooter/appFooter.js",
"src/components/apphost.js", "src/components/apphost.js",
"src/components/appRouter.js",
"src/components/autoFocuser.js", "src/components/autoFocuser.js",
"src/components/backdrop/backdrop.js", "src/components/backdrop/backdrop.js",
"src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/cardBuilder.js",
@ -144,6 +146,7 @@
"src/components/multiSelect/multiSelect.js", "src/components/multiSelect/multiSelect.js",
"src/components/notifications/notifications.js", "src/components/notifications/notifications.js",
"src/components/nowPlayingBar/nowPlayingBar.js", "src/components/nowPlayingBar/nowPlayingBar.js",
"src/components/packageManager.js",
"src/components/playback/brightnessosd.js", "src/components/playback/brightnessosd.js",
"src/components/playback/mediasession.js", "src/components/playback/mediasession.js",
"src/components/playback/nowplayinghelper.js", "src/components/playback/nowplayinghelper.js",
@ -159,16 +162,21 @@
"src/components/playerstats/playerstats.js", "src/components/playerstats/playerstats.js",
"src/components/playlisteditor/playlisteditor.js", "src/components/playlisteditor/playlisteditor.js",
"src/components/playmenu.js", "src/components/playmenu.js",
"src/components/pluginManager.js",
"src/components/prompt/prompt.js", "src/components/prompt/prompt.js",
"src/components/recordingcreator/recordingbutton.js", "src/components/recordingcreator/recordingbutton.js",
"src/components/recordingcreator/recordingcreator.js", "src/components/recordingcreator/recordingcreator.js",
"src/components/recordingcreator/seriesrecordingeditor.js", "src/components/recordingcreator/seriesrecordingeditor.js",
"src/components/recordingcreator/recordinghelper.js", "src/components/recordingcreator/recordinghelper.js",
"src/components/refreshdialog/refreshdialog.js", "src/components/refreshdialog/refreshdialog.js",
"src/components/recordingcreator/recordingeditor.js",
"src/components/recordingcreator/recordingfields.js",
"src/components/qualityOptions.js", "src/components/qualityOptions.js",
"src/components/remotecontrol/remotecontrol.js", "src/components/remotecontrol/remotecontrol.js",
"src/components/sanatizefilename.js", "src/components/sanatizefilename.js",
"src/components/scrollManager.js", "src/components/scrollManager.js",
"src/plugins/experimentalWarnings/plugin.js",
"src/plugins/sessionPlayer/plugin.js",
"src/plugins/htmlAudioPlayer/plugin.js", "src/plugins/htmlAudioPlayer/plugin.js",
"src/plugins/chromecastPlayer/plugin.js", "src/plugins/chromecastPlayer/plugin.js",
"src/components/slideshow/slideshow.js", "src/components/slideshow/slideshow.js",
@ -313,11 +321,13 @@
"src/plugins/backdropScreensaver/plugin.js", "src/plugins/backdropScreensaver/plugin.js",
"src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/plugin.js",
"src/plugins/bookPlayer/tableOfContents.js", "src/plugins/bookPlayer/tableOfContents.js",
"src/plugins/chromecastPlayer/chromecastHelper.js",
"src/plugins/photoPlayer/plugin.js", "src/plugins/photoPlayer/plugin.js",
"src/plugins/youtubePlayer/plugin.js", "src/plugins/youtubePlayer/plugin.js",
"src/scripts/alphanumericshortcuts.js", "src/scripts/alphanumericshortcuts.js",
"src/scripts/autoBackdrops.js", "src/scripts/autoBackdrops.js",
"src/scripts/browser.js", "src/scripts/browser.js",
"src/scripts/clientUtils.js",
"src/scripts/datetime.js", "src/scripts/datetime.js",
"src/scripts/deleteHelper.js", "src/scripts/deleteHelper.js",
"src/scripts/dfnshelper.js", "src/scripts/dfnshelper.js",

File diff suppressed because it is too large Load diff

View file

@ -55,7 +55,7 @@ function replaceAll(originalString, strReplace, strWith) {
function generateDeviceId() { function generateDeviceId() {
const keys = []; const keys = [];
if (keys.push(navigator.userAgent), keys.push(new Date().getTime()), self.btoa) { if (keys.push(navigator.userAgent), keys.push(new Date().getTime()), window.btoa) {
const result = replaceAll(btoa(keys.join('|')), '=', '1'); const result = replaceAll(btoa(keys.join('|')), '=', '1');
return Promise.resolve(result); return Promise.resolve(result);
} }
@ -404,9 +404,9 @@ document.addEventListener(visibilityChange, function () {
} }
}, false); }, false);
if (self.addEventListener) { if (window.addEventListener) {
self.addEventListener('focus', onAppVisible); window.addEventListener('focus', onAppVisible);
self.addEventListener('blur', onAppHidden); window.addEventListener('blur', onAppHidden);
} }
export default appHost; export default appHost;

View file

@ -239,33 +239,13 @@ button::-moz-focus-inner {
border: none; border: none;
} }
.cardImage-img {
max-height: 100%;
max-width: 100%;
/* This is simply for lazy image purposes, to ensure the image is visible sooner when scrolling */
min-height: 70%;
min-width: 70%;
margin: auto;
}
.coveredImage-img {
width: 100%;
height: 100%;
}
.coveredImage-noscale-img {
max-height: none;
max-width: none;
}
.coveredImage { .coveredImage {
background-size: cover; background-size: cover;
background-position: center center; background-position: center center;
} }
.coveredImage-noScale { .coveredImage.coveredImage-contain {
background-size: cover; background-size: contain;
} }
.cardFooter { .cardFooter {
@ -372,6 +352,8 @@ button::-moz-focus-inner {
.cardDefaultText { .cardDefaultText {
white-space: normal; white-space: normal;
text-align: center; text-align: center;
font-size: 2em;
font-weight: bold;
} }
.cardImageContainer .cardImageIcon { .cardImageContainer .cardImageIcon {

View file

@ -986,6 +986,10 @@ import 'programStyles';
lines = []; lines = [];
} }
if (overlayText && showTitle) {
lines = [item.Name];
}
const addRightTextMargin = isOuterFooter && options.cardLayout && !options.centerText && options.cardFooterAside !== 'none' && layoutManager.mobile; const addRightTextMargin = isOuterFooter && options.cardLayout && !options.centerText && options.cardFooterAside !== 'none' && layoutManager.mobile;
html += getCardTextLines(lines, cssClass, !options.overlayText, isOuterFooter, options.cardLayout, addRightTextMargin, options.lines); html += getCardTextLines(lines, cssClass, !options.overlayText, isOuterFooter, options.cardLayout, addRightTextMargin, options.lines);
@ -1117,7 +1121,7 @@ import 'programStyles';
function importRefreshIndicator() { function importRefreshIndicator() {
if (!refreshIndicatorLoaded) { if (!refreshIndicatorLoaded) {
refreshIndicatorLoaded = true; refreshIndicatorLoaded = true;
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('emby-itemrefreshindicator'); import('emby-itemrefreshindicator');
} }
} }
@ -1212,8 +1216,8 @@ import 'programStyles';
if (coveredImage) { if (coveredImage) {
cardImageContainerClass += ' coveredImage'; cardImageContainerClass += ' coveredImage';
if (item.MediaType === 'Photo' || item.Type === 'PhotoAlbum' || item.Type === 'Folder' || item.ProgramInfo || item.Type === 'Program' || item.Type === 'Recording') { if (item.Type === 'TvChannel') {
cardImageContainerClass += ' coveredImage-noScale'; cardImageContainerClass += ' coveredImage-contain';
} }
} }
@ -1449,7 +1453,7 @@ import 'programStyles';
const userData = item.UserData || {}; const userData = item.UserData || {};
if (itemHelper.canMarkPlayed(item)) { if (itemHelper.canMarkPlayed(item)) {
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('emby-playstatebutton'); import('emby-playstatebutton');
html += '<button is="emby-playstatebutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-played="' + (userData.Played) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover check"></span></button>'; html += '<button is="emby-playstatebutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-played="' + (userData.Played) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover check"></span></button>';
} }
@ -1457,7 +1461,7 @@ import 'programStyles';
if (itemHelper.canRate(item)) { if (itemHelper.canRate(item)) {
const likes = userData.Likes == null ? '' : userData.Likes; const likes = userData.Likes == null ? '' : userData.Likes;
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('emby-ratingbutton'); import('emby-ratingbutton');
html += '<button is="emby-ratingbutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover favorite"></span></button>'; html += '<button is="emby-ratingbutton" type="button" data-action="none" class="' + btnCssClass + '" data-id="' + item.Id + '" data-serverid="' + item.ServerId + '" data-itemtype="' + item.Type + '" data-likes="' + likes + '" data-isfavorite="' + (userData.IsFavorite) + '"><span class="material-icons cardOverlayButtonIcon cardOverlayButtonIcon-hover favorite"></span></button>';
} }

View file

@ -19,7 +19,7 @@ export default (() => {
} }
const text = replaceAll(options.text || '', '<br/>', '\n'); const text = replaceAll(options.text || '', '<br/>', '\n');
const result = confirm(text); const result = window.confirm(text);
if (result) { if (result) {
return Promise.resolve(); return Promise.resolve();

View file

@ -85,9 +85,9 @@ import 'scrollStyles';
} }
if (!self.closedByBack && isHistoryEnabled(dlg)) { if (!self.closedByBack && isHistoryEnabled(dlg)) {
const state = history.state || {}; const state = window.history.state || {};
if (state.dialogId === hash) { if (state.dialogId === hash) {
history.back(); window.history.back();
} }
} }
@ -213,7 +213,7 @@ import 'scrollStyles';
export function close(dlg) { export function close(dlg) {
if (isOpened(dlg)) { if (isOpened(dlg)) {
if (isHistoryEnabled(dlg)) { if (isHistoryEnabled(dlg)) {
history.back(); window.history.back();
} else { } else {
closeDialog(dlg); closeDialog(dlg);
} }
@ -375,7 +375,7 @@ import 'scrollStyles';
dlg.setAttribute('data-lockscroll', 'true'); dlg.setAttribute('data-lockscroll', 'true');
} }
if (options.enableHistory !== false && appRouter.enableNativeHistory()) { if (options.enableHistory !== false) {
dlg.setAttribute('data-history', 'true'); dlg.setAttribute('data-history', 'true');
} }

View file

@ -125,7 +125,7 @@ import 'emby-button';
html += `<input is="emby-input" id="txtDirectoryPickerPath" type="text" required="required" ${readOnlyAttribute} label="${globalize.translate(labelKey)}"/>`; html += `<input is="emby-input" id="txtDirectoryPickerPath" type="text" required="required" ${readOnlyAttribute} label="${globalize.translate(labelKey)}"/>`;
html += '</div>'; html += '</div>';
if (!readOnlyAttribute) { if (!readOnlyAttribute) {
html += `<button type="button" is="paper-icon-button-light" class="btnRefreshDirectories emby-input-iconbutton" title="${globalize.translate('ButtonRefresh')}"><span class="material-icons search"></span></button>`; html += `<button type="button" is="paper-icon-button-light" class="btnRefreshDirectories emby-input-iconbutton" title="${globalize.translate('Refresh')}"><span class="material-icons search"></span></button>`;
} }
html += '</div>'; html += '</div>';
if (!readOnlyAttribute) { if (!readOnlyAttribute) {

View file

@ -170,7 +170,7 @@
<div class="checkboxContainer checkboxContainer-withDescription fldThemeSong hide"> <div class="checkboxContainer checkboxContainer-withDescription fldThemeSong hide">
<label> <label>
<input type="checkbox" is="emby-checkbox" id="chkThemeSong" /> <input type="checkbox" is="emby-checkbox" id="chkThemeSong" />
<span>${EnableThemeSongs}</span> <span>${ThemeSongs}</span>
</label> </label>
<div class="fieldDescription checkboxFieldDescription">${EnableThemeSongsHelp}</div> <div class="fieldDescription checkboxFieldDescription">${EnableThemeSongsHelp}</div>
</div> </div>
@ -178,7 +178,7 @@
<div class="checkboxContainer checkboxContainer-withDescription fldThemeVideo hide"> <div class="checkboxContainer checkboxContainer-withDescription fldThemeVideo hide">
<label> <label>
<input type="checkbox" is="emby-checkbox" id="chkThemeVideo" /> <input type="checkbox" is="emby-checkbox" id="chkThemeVideo" />
<span>${EnableThemeVideos}</span> <span>${ThemeVideos}</span>
</label> </label>
<div class="fieldDescription checkboxFieldDescription">${EnableThemeVideosHelp}</div> <div class="fieldDescription checkboxFieldDescription">${EnableThemeVideosHelp}</div>
</div> </div>

View file

@ -70,6 +70,10 @@
contain: strict; contain: strict;
} }
.programContainer.emby-scroller {
margin: 0;
}
.channelPrograms { .channelPrograms {
height: 4.42em; height: 4.42em;
contain: strict; contain: strict;

View file

@ -1,6 +1,6 @@
<form style="margin:0 auto;"> <form style="margin:0 auto;">
<div class="verticalSection verticalSection-extrabottompadding"> <div class="verticalSection verticalSection-extrabottompadding">
<h2 class="sectionTitle">${HeaderHome}</h2> <h2 class="sectionTitle">${Home}</h2>
<div class="selectContainer hide selectTVHomeScreenContainer"> <div class="selectContainer hide selectTVHomeScreenContainer">
<select is="emby-select" class="selectTVHomeScreen" label="${LabelTVHomeScreen}"> <select is="emby-select" class="selectTVHomeScreen" label="${LabelTVHomeScreen}">

View file

@ -87,6 +87,9 @@ import 'css!./style';
requestAnimationFrame(() => { requestAnimationFrame(() => {
if (elem.tagName !== 'IMG') { if (elem.tagName !== 'IMG') {
elem.style.backgroundImage = "url('" + url + "')"; elem.style.backgroundImage = "url('" + url + "')";
if (elem.classList.contains('blurhashed')) {
elem.style.backgroundColor = '#fff';
}
} else { } else {
elem.setAttribute('src', url); elem.setAttribute('src', url);
} }
@ -108,6 +111,7 @@ import 'css!./style';
if (elem.tagName !== 'IMG') { if (elem.tagName !== 'IMG') {
url = elem.style.backgroundImage.slice(4, -1).replace(/"/g, ''); url = elem.style.backgroundImage.slice(4, -1).replace(/"/g, '');
elem.style.backgroundImage = 'none'; elem.style.backgroundImage = 'none';
elem.style.backgroundColor = null;
} else { } else {
url = elem.getAttribute('src'); url = elem.getAttribute('src');
elem.setAttribute('src', ''); elem.setAttribute('src', '');

View file

@ -8,7 +8,6 @@ import browser from 'browser';
import actionsheet from 'actionsheet'; import actionsheet from 'actionsheet';
/* eslint-disable indent */ /* eslint-disable indent */
export function getCommands(options) { export function getCommands(options) {
const item = options.item; const item = options.item;
const user = options.user; const user = options.user;

View file

@ -2,7 +2,7 @@
<button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1"> <button is="paper-icon-button-light" class="btnCancel autoSize" tabindex="-1">
<span class="material-icons arrow_back"></span> <span class="material-icons arrow_back"></span>
</button> </button>
<h3 class="formDialogHeaderTitle">${HeaderMediaInfo}</h3> <h3 class="formDialogHeaderTitle">${MoreMediaInfo}</h3>
</div> </div>
<div class="formDialogContent smoothScrollY"> <div class="formDialogContent smoothScrollY">

View file

@ -88,7 +88,7 @@
<div class="checkboxContainer checkboxContainer-withDescription hide chkImportMissingEpisodesContainer advanced"> <div class="checkboxContainer checkboxContainer-withDescription hide chkImportMissingEpisodesContainer advanced">
<label> <label>
<input is="emby-checkbox" type="checkbox" id="chkImportMissingEpisodes" /> <input is="emby-checkbox" type="checkbox" id="chkImportMissingEpisodes" />
<span>${LabelDisplayMissingEpisodesWithinSeasons}</span> <span>${DisplayMissingEpisodesWithinSeasons}</span>
</label> </label>
<div class="fieldDescription checkboxFieldDescription">${ImportMissingEpisodesHelp}</div> <div class="fieldDescription checkboxFieldDescription">${ImportMissingEpisodesHelp}</div>
</div> </div>

View file

@ -9,7 +9,6 @@ import 'programStyles';
import 'emby-button'; import 'emby-button';
/* eslint-disable indent */ /* eslint-disable indent */
function getTimerIndicator(item) { function getTimerIndicator(item) {
let status; let status;

View file

@ -1,134 +1,140 @@
define(['appSettings', 'pluginManager'], function (appSettings, pluginManager) { import appSettings from 'appSettings';
'use strict'; import pluginManager from 'pluginManager';
/* eslint-disable indent */
var settingsKey = 'installedpackages1'; class PackageManager {
#packagesList = [];
#settingsKey = 'installedpackages1';
function addPackage(packageManager, pkg) { init() {
packageManager.packagesList = packageManager.packagesList.filter(function (p) { console.groupCollapsed('loading packages');
return p.name !== pkg.name; var manifestUrls = JSON.parse(appSettings.get(this.#settingsKey) || '[]');
});
packageManager.packagesList.push(pkg); return Promise.all(manifestUrls.map((url) => {
} return this.loadPackage(url);
}))
.then(() => {
console.debug('finished loading packages');
return Promise.resolve();
})
.catch(() => {
return Promise.resolve();
}).finally(() => {
console.groupEnd('loading packages');
});
}
function removeUrl(url) { get packages() {
var manifestUrls = JSON.parse(appSettings.get(settingsKey) || '[]'); return this.#packagesList.slice(0);
}
manifestUrls = manifestUrls.filter(function (i) { install(url) {
return i !== url; return this.loadPackage(url, true).then((pkg) => {
}); var manifestUrls = JSON.parse(appSettings.get(this.#settingsKey) || '[]');
appSettings.set(settingsKey, JSON.stringify(manifestUrls)); if (!manifestUrls.includes(url)) {
} manifestUrls.push(url);
appSettings.set(this.#settingsKey, JSON.stringify(manifestUrls));
function loadPackage(packageManager, url, throwError) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
var originalUrl = url;
url += url.indexOf('?') === -1 ? '?' : '&';
url += 't=' + new Date().getTime();
xhr.open('GET', url, true);
var onError = function () {
if (throwError === true) {
reject();
} else {
removeUrl(originalUrl);
resolve();
} }
};
xhr.onload = function (e) { return pkg;
if (this.status < 400) { });
var pkg = JSON.parse(this.response); }
pkg.url = originalUrl;
addPackage(packageManager, pkg); uninstall(name) {
var pkg = this.#packagesList.filter((p) => {
return p.name === name;
})[0];
var plugins = pkg.plugins || []; if (pkg) {
if (pkg.plugin) { this.#packagesList = this.#packagesList.filter((p) => {
plugins.push(pkg.plugin); return p.name !== name;
} });
var promises = plugins.map(function (pluginUrl) {
return pluginManager.loadPlugin(packageManager.mapPath(pkg, pluginUrl));
});
Promise.all(promises).then(resolve, resolve);
} else {
onError();
}
};
xhr.onerror = onError; this.removeUrl(pkg.url);
xhr.send();
});
}
function PackageManager() {
this.packagesList = [];
}
PackageManager.prototype.init = function () {
var manifestUrls = JSON.parse(appSettings.get(settingsKey) || '[]');
var instance = this;
return Promise.all(manifestUrls.map(function (u) {
return loadPackage(instance, u);
})).then(function () {
return Promise.resolve();
}, function () {
return Promise.resolve();
});
};
PackageManager.prototype.packages = function () {
return this.packagesList.slice(0);
};
PackageManager.prototype.install = function (url) {
return loadPackage(this, url, true).then(function (pkg) {
var manifestUrls = JSON.parse(appSettings.get(settingsKey) || '[]');
if (manifestUrls.indexOf(url) === -1) {
manifestUrls.push(url);
appSettings.set(settingsKey, JSON.stringify(manifestUrls));
} }
return pkg; return Promise.resolve();
}); }
};
PackageManager.prototype.uninstall = function (name) { mapPath(pkg, pluginUrl) {
var pkg = this.packagesList.filter(function (p) { var urlLower = pluginUrl.toLowerCase();
return p.name === name; if (urlLower.startsWith('http:') || urlLower.startsWith('https:') || urlLower.startsWith('file:')) {
})[0]; return pluginUrl;
}
if (pkg) { var packageUrl = pkg.url;
this.packagesList = this.packagesList.filter(function (p) { packageUrl = packageUrl.substring(0, packageUrl.lastIndexOf('/'));
return p.name !== name;
packageUrl += '/';
packageUrl += pluginUrl;
return packageUrl;
}
addPackage(pkg) {
this.#packagesList = this.#packagesList.filter((p) => {
return p.name !== pkg.name;
}); });
removeUrl(pkg.url); this.#packagesList.push(pkg);
} }
return Promise.resolve(); removeUrl(url) {
}; var manifestUrls = JSON.parse(appSettings.get(this.#settingsKey) || '[]');
PackageManager.prototype.mapPath = function (pkg, pluginUrl) { manifestUrls = manifestUrls.filter((i) => {
var urlLower = pluginUrl.toLowerCase(); return i !== url;
if (urlLower.indexOf('http:') === 0 || urlLower.indexOf('https:') === 0 || urlLower.indexOf('file:') === 0) { });
return pluginUrl;
appSettings.set(this.#settingsKey, JSON.stringify(manifestUrls));
} }
var packageUrl = pkg.url; loadPackage(url, throwError = false) {
packageUrl = packageUrl.substring(0, packageUrl.lastIndexOf('/')); return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
var originalUrl = url;
url += url.indexOf('?') === -1 ? '?' : '&';
url += 't=' + new Date().getTime();
packageUrl += '/'; xhr.open('GET', url, true);
packageUrl += pluginUrl;
return packageUrl; var onError = () => {
}; if (throwError === true) {
reject();
} else {
this.removeUrl(originalUrl);
resolve();
}
};
return new PackageManager(); xhr.onload = () => {
}); if (this.status < 400) {
var pkg = JSON.parse(this.response);
pkg.url = originalUrl;
this.addPackage(pkg);
var plugins = pkg.plugins || [];
if (pkg.plugin) {
plugins.push(pkg.plugin);
}
var promises = plugins.map((pluginUrl) => {
return pluginManager.loadPlugin(this.mapPath(pkg, pluginUrl));
});
Promise.all(promises).then(resolve, resolve);
} else {
onError();
}
};
xhr.onerror = onError;
xhr.send();
});
}
}
/* eslint-enable indent */
export default new PackageManager();

View file

@ -1112,6 +1112,52 @@ class PlaybackManager {
} }
}; };
self.increasePlaybackRate = function (player) {
player = player || self._currentPlayer;
if (player) {
let current = self.getPlaybackRate(player);
let supported = self.getSupportedPlaybackRates(player);
let index = -1;
for (let i = 0, length = supported.length; i < length; i++) {
if (supported[i].id === current) {
index = i;
break;
}
}
index = Math.min(index + 1, supported.length - 1);
self.setPlaybackRate(supported[index].id, player);
}
};
self.decreasePlaybackRate = function (player) {
player = player || self._currentPlayer;
if (player) {
let current = self.getPlaybackRate(player);
let supported = self.getSupportedPlaybackRates(player);
let index = -1;
for (let i = 0, length = supported.length; i < length; i++) {
if (supported[i].id === current) {
index = i;
break;
}
}
index = Math.max(index - 1, 0);
self.setPlaybackRate(supported[index].id, player);
}
};
self.getSupportedPlaybackRates = function (player) {
player = player || self._currentPlayer;
if (player && player.getSupportedPlaybackRates) {
return player.getSupportedPlaybackRates();
}
return [];
};
let brightnessOsdLoaded; let brightnessOsdLoaded;
self.setBrightness = function (val, player) { self.setBrightness = function (val, player) {
player = player || self._currentPlayer; player = player || self._currentPlayer;
@ -1416,8 +1462,8 @@ class PlaybackManager {
self.toggleFullscreen = function (player) { self.toggleFullscreen = function (player) {
player = player || self._currentPlayer; player = player || self._currentPlayer;
if (!player.isLocalPlayer || player.toggleFulscreen) { if (!player.isLocalPlayer || player.toggleFullscreen) {
return player.toggleFulscreen(); return player.toggleFullscreen();
} }
if (screenfull.isEnabled) { if (screenfull.isEnabled) {
@ -3697,6 +3743,9 @@ class PlaybackManager {
case 'SetAspectRatio': case 'SetAspectRatio':
this.setAspectRatio(cmd.Arguments.AspectRatio, player); this.setAspectRatio(cmd.Arguments.AspectRatio, player);
break; break;
case 'PlaybackRate':
this.setPlaybackRate(cmd.Arguments.PlaybackRate, player);
break;
case 'SetBrightness': case 'SetBrightness':
this.setBrightness(cmd.Arguments.Brightness, player); this.setBrightness(cmd.Arguments.Brightness, player);
break; break;

View file

@ -18,7 +18,7 @@ events.on(playbackManager, 'playbackstart', function (e, player, state) {
if (isLocalVideo && layoutManager.mobile) { if (isLocalVideo && layoutManager.mobile) {
/* eslint-disable-next-line compat/compat */ /* eslint-disable-next-line compat/compat */
var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation || (screen.orientation && screen.orientation.lock); var lockOrientation = window.screen.lockOrientation || window.screen.mozLockOrientation || window.screen.msLockOrientation || (window.screen.orientation && window.screen.orientation.lock);
if (lockOrientation) { if (lockOrientation) {
try { try {
@ -39,7 +39,7 @@ events.on(playbackManager, 'playbackstart', function (e, player, state) {
events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) { events.on(playbackManager, 'playbackstop', function (e, playbackStopInfo) {
if (orientationLocked && !playbackStopInfo.nextMediaType) { if (orientationLocked && !playbackStopInfo.nextMediaType) {
/* eslint-disable-next-line compat/compat */ /* eslint-disable-next-line compat/compat */
var unlockOrientation = screen.unlockOrientation || screen.mozUnlockOrientation || screen.msUnlockOrientation || (screen.orientation && screen.orientation.unlock); var unlockOrientation = window.screen.unlockOrientation || window.screen.mozUnlockOrientation || window.screen.msUnlockOrientation || (window.screen.orientation && window.screen.orientation.unlock);
if (unlockOrientation) { if (unlockOrientation) {
try { try {

View file

@ -149,6 +149,28 @@ function showAspectRatioMenu(player, btn) {
}); });
} }
function showPlaybackRateMenu(player, btn) {
// each has a name and id
const currentId = playbackManager.getPlaybackRate(player);
const menuItems = playbackManager.getSupportedPlaybackRates(player).map(i => ({
id: i.id,
name: i.name,
selected: i.id === currentId
}));
return actionsheet.show({
items: menuItems,
positionTo: btn
}).then(function (id) {
if (id) {
playbackManager.setPlaybackRate(id, player);
return Promise.resolve();
}
return Promise.reject();
});
}
function showWithUser(options, player, user) { function showWithUser(options, player, user) {
var supportedCommands = playbackManager.getSupportedCommands(player); var supportedCommands = playbackManager.getSupportedCommands(player);
@ -166,6 +188,17 @@ function showWithUser(options, player, user) {
}); });
} }
if (supportedCommands.indexOf('PlaybackRate') !== -1) {
const currentPlaybackRateId = playbackManager.getPlaybackRate(player);
const currentPlaybackRate = playbackManager.getSupportedPlaybackRates(player).filter(i => i.id === currentPlaybackRateId)[0];
menuItems.push({
name: globalize.translate('PlaybackRate'),
id: 'playbackrate',
asideText: currentPlaybackRate ? currentPlaybackRate.name : null
});
}
if (user && user.Policy.EnableVideoPlaybackTranscoding) { if (user && user.Policy.EnableVideoPlaybackTranscoding) {
var secondaryQualityText = getQualitySecondaryText(player); var secondaryQualityText = getQualitySecondaryText(player);
@ -230,6 +263,8 @@ function handleSelectedOption(id, options, player) {
return showQualityMenu(player, options.positionTo); return showQualityMenu(player, options.positionTo);
case 'aspectratio': case 'aspectratio':
return showAspectRatioMenu(player, options.positionTo); return showAspectRatioMenu(player, options.positionTo);
case 'playbackrate':
return showPlaybackRateMenu(player, options.positionTo);
case 'repeatmode': case 'repeatmode':
return showRepeatModeMenu(player, options.positionTo); return showRepeatModeMenu(player, options.positionTo);
case 'stats': case 'stats':

View file

@ -1,37 +1,38 @@
define(['events', 'globalize'], function (events, globalize) { import events from 'events';
'use strict'; import globalize from 'globalize';
/* eslint-disable indent */
// TODO: replace with each plugin version // TODO: replace with each plugin version
var cacheParam = new Date().getTime(); var cacheParam = new Date().getTime();
function loadStrings(plugin) { class PluginManager {
var strings = plugin.getTranslations ? plugin.getTranslations() : []; pluginsList = [];
return globalize.loadStrings({
name: plugin.id || plugin.packageName,
strings: strings
});
}
function definePluginRoute(pluginManager, route, plugin) { get plugins() {
route.contentPath = pluginManager.mapPath(plugin, route.path); return this.pluginsList;
route.path = pluginManager.mapRoute(plugin, route); }
Emby.App.defineRoute(route, plugin.id); #loadStrings(plugin) {
} var strings = plugin.getTranslations ? plugin.getTranslations() : [];
return globalize.loadStrings({
name: plugin.id || plugin.packageName,
strings: strings
});
}
function PluginManager() { #definePluginRoute(route, plugin) {
this.pluginsList = []; route.contentPath = this.mapPath(plugin, route.path);
} route.path = this.#mapRoute(plugin, route);
PluginManager.prototype.loadPlugin = function(pluginSpec) { Emby.App.defineRoute(route, plugin.id);
var instance = this; }
function registerPlugin(plugin) { #registerPlugin(plugin) {
instance.register(plugin); this.#register(plugin);
if (plugin.getRoutes) { if (plugin.getRoutes) {
plugin.getRoutes().forEach(function (route) { plugin.getRoutes().forEach((route) => {
definePluginRoute(instance, route, plugin); this.#definePluginRoute(route, plugin);
}); });
} }
@ -40,7 +41,7 @@ define(['events', 'globalize'], function (events, globalize) {
return Promise.resolve(plugin); return Promise.resolve(plugin);
} else { } else {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
loadStrings(plugin) this.#loadStrings(plugin)
.then(function () { .then(function () {
resolve(plugin); resolve(plugin);
}) })
@ -49,103 +50,102 @@ define(['events', 'globalize'], function (events, globalize) {
} }
} }
if (typeof pluginSpec === 'string') { loadPlugin(pluginSpec) {
console.debug('Loading plugin (via deprecated requirejs method): ' + pluginSpec); if (typeof pluginSpec === 'string') {
console.debug('Loading plugin (via deprecated requirejs method): ' + pluginSpec);
return new Promise(function (resolve, reject) { return new Promise((resolve, reject) => {
require([pluginSpec], (pluginFactory) => { require([pluginSpec], (pluginFactory) => {
var plugin = pluginFactory.default ? new pluginFactory.default() : new pluginFactory(); var plugin = pluginFactory.default ? new pluginFactory.default() : new pluginFactory();
// See if it's already installed // See if it's already installed
var existing = instance.pluginsList.filter(function (p) { var existing = this.pluginsList.filter(function (p) {
return p.id === plugin.id; return p.id === plugin.id;
})[0]; })[0];
if (existing) { if (existing) {
resolve(pluginSpec); resolve(pluginSpec);
} }
plugin.installUrl = pluginSpec; plugin.installUrl = pluginSpec;
var separatorIndex = Math.max(pluginSpec.lastIndexOf('/'), pluginSpec.lastIndexOf('\\')); var separatorIndex = Math.max(pluginSpec.lastIndexOf('/'), pluginSpec.lastIndexOf('\\'));
plugin.baseUrl = pluginSpec.substring(0, separatorIndex); plugin.baseUrl = pluginSpec.substring(0, separatorIndex);
var paths = {}; var paths = {};
paths[plugin.id] = plugin.baseUrl; paths[plugin.id] = plugin.baseUrl;
requirejs.config({ requirejs.config({
waitSeconds: 0, waitSeconds: 0,
paths: paths paths: paths
});
this.#registerPlugin(plugin).then(resolve).catch(reject);
}); });
registerPlugin(plugin).then(resolve).catch(reject);
}); });
} else if (pluginSpec.then) {
return pluginSpec.then(pluginBuilder => {
return pluginBuilder();
}).then((plugin) => {
console.debug(`Plugin loaded: ${plugin.id}`);
return this.#registerPlugin(plugin);
});
} else {
const err = new TypeError('Plugins have to be a Promise that resolves to a plugin builder function or a RequireJS url (deprecated)');
console.error(err);
return Promise.reject(err);
}
}
// In lieu of automatic discovery, plugins will register dynamic objects
// Each object will have the following properties:
// name
// type (skin, screensaver, etc)
#register(obj) {
this.pluginsList.push(obj);
events.trigger(this, 'registered', [obj]);
}
ofType(type) {
return this.pluginsList.filter((o) => {
return o.type === type;
}); });
} else if (pluginSpec.then) {
return pluginSpec.then(pluginBuilder => {
return pluginBuilder();
}).then(plugin => {
console.debug(`Plugin loaded: ${plugin.id}`);
return registerPlugin(plugin);
});
} else {
const err = new Error('Plugins have to be a Promise that resolves to a plugin builder function or a requirejs urls (deprecated)');
console.error(err);
return Promise.reject(err);
}
};
// In lieu of automatic discovery, plugins will register dynamic objects
// Each object will have the following properties:
// name
// type (skin, screensaver, etc)
PluginManager.prototype.register = function (obj) {
this.pluginsList.push(obj);
events.trigger(this, 'registered', [obj]);
};
PluginManager.prototype.ofType = function (type) {
return this.pluginsList.filter(function (o) {
return o.type === type;
});
};
PluginManager.prototype.plugins = function () {
return this.pluginsList;
};
PluginManager.prototype.mapRoute = function (plugin, route) {
if (typeof plugin === 'string') {
plugin = this.pluginsList.filter(function (p) {
return (p.id || p.packageName) === plugin;
})[0];
} }
route = route.path || route; #mapRoute(plugin, route) {
if (typeof plugin === 'string') {
plugin = this.pluginsList.filter((p) => {
return (p.id || p.packageName) === plugin;
})[0];
}
if (route.toLowerCase().indexOf('http') === 0) { route = route.path || route;
return route;
if (route.toLowerCase().startsWith('http')) {
return route;
}
return '/plugins/' + plugin.id + '/' + route;
} }
return '/plugins/' + plugin.id + '/' + route; mapPath(plugin, path, addCacheParam) {
}; if (typeof plugin === 'string') {
plugin = this.pluginsList.filter((p) => {
return (p.id || p.packageName) === plugin;
})[0];
}
PluginManager.prototype.mapPath = function (plugin, path, addCacheParam) { var url = plugin.baseUrl + '/' + path;
if (typeof plugin === 'string') {
plugin = this.pluginsList.filter(function (p) { if (addCacheParam) {
return (p.id || p.packageName) === plugin; url += url.includes('?') ? '&' : '?';
})[0]; url += 'v=' + cacheParam;
}
return url;
} }
}
var url = plugin.baseUrl + '/' + path; /* eslint-enable indent */
if (addCacheParam) { export default new PluginManager();
url += url.indexOf('?') === -1 ? '?' : '&';
url += 'v=' + cacheParam;
}
return url;
};
return new PluginManager();
});

View file

@ -118,7 +118,7 @@ function reload(context, programId, serverId, refreshRecordingStateOnly) {
function executeCloseAction(action, programId, serverId) { function executeCloseAction(action, programId, serverId) {
if (action === 'play') { if (action === 'play') {
import('playbackManager').then(({default: playbackManager}) => { import('playbackManager').then(({ default: playbackManager }) => {
const apiClient = connectionManager.getApiClient(serverId); const apiClient = connectionManager.getApiClient(serverId);
apiClient.getLiveTvProgram(programId, apiClient.getCurrentUserId()).then(function (item) { apiClient.getLiveTvProgram(programId, apiClient.getCurrentUserId()).then(function (item) {
@ -138,7 +138,7 @@ function showEditor(itemId, serverId) {
loading.show(); loading.show();
import('text!./recordingcreator.template.html').then(({default: template}) => { import('text!./recordingcreator.template.html').then(({ default: template }) => {
const dialogOptions = { const dialogOptions = {
removeOnClose: true, removeOnClose: true,
scrollY: false scrollY: false

View file

@ -1,151 +1,155 @@
define(['dialogHelper', 'globalize', 'layoutManager', 'mediaInfo', 'apphost', 'connectionManager', 'require', 'loading', 'scrollHelper', 'imageLoader', 'scrollStyles', 'emby-button', 'emby-collapse', 'emby-input', 'paper-icon-button-light', 'css!./../formdialog', 'css!./recordingcreator', 'material-icons', 'flexStyles'], function (dialogHelper, globalize, layoutManager, mediaInfo, appHost, connectionManager, require, loading, scrollHelper, imageLoader) { import dialogHelper from 'dialogHelper';
'use strict'; import globalize from 'globalize';
import layoutManager from 'layoutManager';
import connectionManager from 'connectionManager';
import loading from 'loading';
import scrollHelper from 'scrollHelper';
import 'scrollStyles';
import 'emby-button';
import 'emby-collapse';
import 'emby-input';
import 'paper-icon-button-light';
import 'css!./../formdialog';
import 'css!./recordingcreator';
import 'material-icons';
import 'flexStyles';
scrollHelper = scrollHelper.default || scrollHelper; let currentDialog;
loading = loading.default || loading; let recordingDeleted = false;
layoutManager = layoutManager.default || layoutManager; let currentItemId;
let currentServerId;
let currentResolve;
var currentDialog; function deleteTimer(apiClient, timerId) {
var recordingDeleted = false; return import('recordingHelper').then(({ default: recordingHelper }) => {
var currentItemId; recordingHelper.cancelTimerWithConfirmation(timerId, apiClient.serverId());
var currentServerId; });
var currentResolve; }
function deleteTimer(apiClient, timerId) { function renderTimer(context, item, apiClient) {
return new Promise(function (resolve, reject) { context.querySelector('#txtPrePaddingMinutes').value = item.PrePaddingSeconds / 60;
require(['recordingHelper'], function (recordingHelper) { context.querySelector('#txtPostPaddingMinutes').value = item.PostPaddingSeconds / 60;
recordingHelper = recordingHelper.default || recordingHelper;
recordingHelper.cancelTimerWithConfirmation(timerId, apiClient.serverId()).then(resolve, reject); loading.hide();
}); }
function closeDialog(isDeleted) {
recordingDeleted = isDeleted;
dialogHelper.close(currentDialog);
}
function onSubmit(e) {
const form = this;
const apiClient = connectionManager.getApiClient(currentServerId);
apiClient.getLiveTvTimer(currentItemId).then(function (item) {
item.PrePaddingSeconds = form.querySelector('#txtPrePaddingMinutes').value * 60;
item.PostPaddingSeconds = form.querySelector('#txtPostPaddingMinutes').value * 60;
apiClient.updateLiveTvTimer(item).then(currentResolve);
});
e.preventDefault();
// Disable default form submission
return false;
}
function init(context) {
context.querySelector('.btnCancel').addEventListener('click', function () {
closeDialog(false);
});
context.querySelector('.btnCancelRecording').addEventListener('click', function () {
const apiClient = connectionManager.getApiClient(currentServerId);
deleteTimer(apiClient, currentItemId).then(function () {
closeDialog(true);
}); });
} });
function renderTimer(context, item, apiClient) { context.querySelector('form').addEventListener('submit', onSubmit);
context.querySelector('#txtPrePaddingMinutes').value = item.PrePaddingSeconds / 60; }
context.querySelector('#txtPostPaddingMinutes').value = item.PostPaddingSeconds / 60;
function reload(context, id) {
loading.show();
currentItemId = id;
const apiClient = connectionManager.getApiClient(currentServerId);
apiClient.getLiveTvTimer(id).then(function (result) {
renderTimer(context, result, apiClient);
loading.hide(); loading.hide();
} });
}
function closeDialog(isDeleted) { function showEditor(itemId, serverId, options) {
recordingDeleted = isDeleted; return new Promise(function (resolve, reject) {
recordingDeleted = false;
dialogHelper.close(currentDialog); currentServerId = serverId;
}
function onSubmit(e) {
var form = this;
var apiClient = connectionManager.getApiClient(currentServerId);
apiClient.getLiveTvTimer(currentItemId).then(function (item) {
item.PrePaddingSeconds = form.querySelector('#txtPrePaddingMinutes').value * 60;
item.PostPaddingSeconds = form.querySelector('#txtPostPaddingMinutes').value * 60;
apiClient.updateLiveTvTimer(item).then(currentResolve);
});
e.preventDefault();
// Disable default form submission
return false;
}
function init(context) {
context.querySelector('.btnCancel').addEventListener('click', function () {
closeDialog(false);
});
context.querySelector('.btnCancelRecording').addEventListener('click', function () {
var apiClient = connectionManager.getApiClient(currentServerId);
deleteTimer(apiClient, currentItemId).then(function () {
closeDialog(true);
});
});
context.querySelector('form').addEventListener('submit', onSubmit);
}
function reload(context, id) {
loading.show(); loading.show();
currentItemId = id; options = options || {};
currentResolve = resolve;
var apiClient = connectionManager.getApiClient(currentServerId); import('text!./recordingeditor.template.html').then(({default: template}) => {
apiClient.getLiveTvTimer(id).then(function (result) { const dialogOptions = {
renderTimer(context, result, apiClient); removeOnClose: true,
loading.hide(); scrollY: false
}); };
}
function showEditor(itemId, serverId, options) { if (layoutManager.tv) {
return new Promise(function (resolve, reject) { dialogOptions.size = 'fullscreen';
recordingDeleted = false; }
currentServerId = serverId;
loading.show();
options = options || {};
currentResolve = resolve;
require(['text!./recordingeditor.template.html'], function (template) { const dlg = dialogHelper.createDialog(dialogOptions);
var dialogOptions = {
removeOnClose: true,
scrollY: false
};
if (layoutManager.tv) { dlg.classList.add('formDialog');
dialogOptions.size = 'fullscreen'; dlg.classList.add('recordingDialog');
if (!layoutManager.tv) {
dlg.style['min-width'] = '20%';
dlg.classList.add('dialog-fullscreen-lowres');
}
let html = '';
html += globalize.translateHtml(template, 'core');
dlg.innerHTML = html;
if (options.enableCancel === false) {
dlg.querySelector('.formDialogFooter').classList.add('hide');
}
currentDialog = dlg;
dlg.addEventListener('closing', function () {
if (!recordingDeleted) {
dlg.querySelector('.btnSubmit').click();
} }
var dlg = dialogHelper.createDialog(dialogOptions);
dlg.classList.add('formDialog');
dlg.classList.add('recordingDialog');
if (!layoutManager.tv) {
dlg.style['min-width'] = '20%';
dlg.classList.add('dialog-fullscreen-lowres');
}
var html = '';
html += globalize.translateHtml(template, 'core');
dlg.innerHTML = html;
if (options.enableCancel === false) {
dlg.querySelector('.formDialogFooter').classList.add('hide');
}
currentDialog = dlg;
dlg.addEventListener('closing', function () {
if (!recordingDeleted) {
dlg.querySelector('.btnSubmit').click();
}
});
dlg.addEventListener('close', function () {
if (recordingDeleted) {
resolve({
updated: true,
deleted: true
});
}
});
if (layoutManager.tv) {
scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false);
}
init(dlg);
reload(dlg, itemId);
dialogHelper.open(dlg);
}); });
});
}
return { dlg.addEventListener('close', function () {
show: showEditor if (recordingDeleted) {
}; resolve({
}); updated: true,
deleted: true
});
}
});
if (layoutManager.tv) {
scrollHelper.centerFocus.on(dlg.querySelector('.formDialogContent'), false);
}
init(dlg);
reload(dlg, itemId);
dialogHelper.open(dlg);
});
});
}
export default {
show: showEditor
};

View file

@ -1,223 +1,126 @@
define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loading', 'apphost', 'dom', 'recordingHelper', 'events', 'paper-icon-button-light', 'emby-button', 'css!./recordingfields', 'flexStyles'], function (globalize, connectionManager, serverNotifications, require, loading, appHost, dom, recordingHelper, events) { import globalize from 'globalize';
'use strict'; import connectionManager from 'connectionManager';
import serverNotifications from 'serverNotifications';
import loading from 'loading';
import dom from 'dom';
import recordingHelper from 'recordingHelper';
import events from 'events';
import 'paper-icon-button-light';
import 'emby-button';
import 'css!./recordingfields';
import 'flexStyles';
serverNotifications = serverNotifications.default || serverNotifications; /*eslint prefer-const: "error"*/
recordingHelper = recordingHelper.default || recordingHelper;
loading = loading.default || loading;
function loadData(parent, program, apiClient) { function loadData(parent, program, apiClient) {
if (program.IsSeries) { if (program.IsSeries) {
parent.querySelector('.recordSeriesContainer').classList.remove('hide'); parent.querySelector('.recordSeriesContainer').classList.remove('hide');
} else {
parent.querySelector('.recordSeriesContainer').classList.add('hide');
}
if (program.SeriesTimerId) {
parent.querySelector('.btnManageSeriesRecording').classList.remove('hide');
parent.querySelector('.seriesRecordingButton .recordingIcon').classList.add('recordingIcon-active');
parent.querySelector('.seriesRecordingButton .buttonText').innerHTML = globalize.translate('CancelSeries');
} else {
parent.querySelector('.btnManageSeriesRecording').classList.add('hide');
parent.querySelector('.seriesRecordingButton .recordingIcon').classList.remove('recordingIcon-active');
parent.querySelector('.seriesRecordingButton .buttonText').innerHTML = globalize.translate('RecordSeries');
}
if (program.TimerId && program.Status !== 'Cancelled') {
parent.querySelector('.btnManageRecording').classList.remove('hide');
parent.querySelector('.singleRecordingButton .recordingIcon').classList.add('recordingIcon-active');
if (program.Status === 'InProgress') {
parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('StopRecording');
} else { } else {
parent.querySelector('.recordSeriesContainer').classList.add('hide'); parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('DoNotRecord');
} }
} else {
parent.querySelector('.btnManageRecording').classList.add('hide');
parent.querySelector('.singleRecordingButton .recordingIcon').classList.remove('recordingIcon-active');
parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('Record');
}
}
if (program.SeriesTimerId) { function fetchData(instance) {
parent.querySelector('.btnManageSeriesRecording').classList.remove('hide'); const options = instance.options;
parent.querySelector('.seriesRecordingButton .recordingIcon').classList.add('recordingIcon-active'); const apiClient = connectionManager.getApiClient(options.serverId);
parent.querySelector('.seriesRecordingButton .buttonText').innerHTML = globalize.translate('CancelSeries');
} else { options.parent.querySelector('.recordingFields').classList.remove('hide');
parent.querySelector('.btnManageSeriesRecording').classList.add('hide'); return apiClient.getLiveTvProgram(options.programId, apiClient.getCurrentUserId()).then(function (program) {
parent.querySelector('.seriesRecordingButton .recordingIcon').classList.remove('recordingIcon-active'); instance.TimerId = program.TimerId;
parent.querySelector('.seriesRecordingButton .buttonText').innerHTML = globalize.translate('RecordSeries'); instance.Status = program.Status;
instance.SeriesTimerId = program.SeriesTimerId;
loadData(options.parent, program, apiClient);
});
}
function onTimerChangedExternally(e, apiClient, data) {
const options = this.options;
let refresh = false;
if (data.Id) {
if (this.TimerId === data.Id) {
refresh = true;
} }
}
if (program.TimerId && program.Status !== 'Cancelled') { if (data.ProgramId && options) {
parent.querySelector('.btnManageRecording').classList.remove('hide'); if (options.programId === data.ProgramId) {
parent.querySelector('.singleRecordingButton .recordingIcon').classList.add('recordingIcon-active'); refresh = true;
if (program.Status === 'InProgress') {
parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('StopRecording');
} else {
parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('DoNotRecord');
}
} else {
parent.querySelector('.btnManageRecording').classList.add('hide');
parent.querySelector('.singleRecordingButton .recordingIcon').classList.remove('recordingIcon-active');
parent.querySelector('.singleRecordingButton .buttonText').innerHTML = globalize.translate('Record');
} }
} }
function fetchData(instance) { if (refresh) {
var options = instance.options; this.refresh();
var apiClient = connectionManager.getApiClient(options.serverId);
options.parent.querySelector('.recordingFields').classList.remove('hide');
return apiClient.getLiveTvProgram(options.programId, apiClient.getCurrentUserId()).then(function (program) {
instance.TimerId = program.TimerId;
instance.Status = program.Status;
instance.SeriesTimerId = program.SeriesTimerId;
loadData(options.parent, program, apiClient);
});
} }
}
function onTimerChangedExternally(e, apiClient, data) { function onSeriesTimerChangedExternally(e, apiClient, data) {
var options = this.options; const options = this.options;
var refresh = false; let refresh = false;
if (data.Id) { if (data.Id) {
if (this.TimerId === data.Id) { if (this.SeriesTimerId === data.Id) {
refresh = true; refresh = true;
}
} }
if (data.ProgramId && options) { }
if (options.programId === data.ProgramId) { if (data.ProgramId && options) {
refresh = true; if (options.programId === data.ProgramId) {
} refresh = true;
}
if (refresh) {
this.refresh();
} }
} }
function onSeriesTimerChangedExternally(e, apiClient, data) { if (refresh) {
var options = this.options; this.refresh();
var refresh = false;
if (data.Id) {
if (this.SeriesTimerId === data.Id) {
refresh = true;
}
}
if (data.ProgramId && options) {
if (options.programId === data.ProgramId) {
refresh = true;
}
}
if (refresh) {
this.refresh();
}
} }
}
function RecordingEditor(options) { class RecordingEditor {
constructor(options) {
this.options = options; this.options = options;
this.embed(); this.embed();
var timerChangedHandler = onTimerChangedExternally.bind(this); const timerChangedHandler = onTimerChangedExternally.bind(this);
this.timerChangedHandler = timerChangedHandler; this.timerChangedHandler = timerChangedHandler;
events.on(serverNotifications, 'TimerCreated', timerChangedHandler); events.on(serverNotifications, 'TimerCreated', timerChangedHandler);
events.on(serverNotifications, 'TimerCancelled', timerChangedHandler); events.on(serverNotifications, 'TimerCancelled', timerChangedHandler);
var seriesTimerChangedHandler = onSeriesTimerChangedExternally.bind(this); const seriesTimerChangedHandler = onSeriesTimerChangedExternally.bind(this);
this.seriesTimerChangedHandler = seriesTimerChangedHandler; this.seriesTimerChangedHandler = seriesTimerChangedHandler;
events.on(serverNotifications, 'SeriesTimerCreated', seriesTimerChangedHandler); events.on(serverNotifications, 'SeriesTimerCreated', seriesTimerChangedHandler);
events.on(serverNotifications, 'SeriesTimerCancelled', seriesTimerChangedHandler); events.on(serverNotifications, 'SeriesTimerCancelled', seriesTimerChangedHandler);
} }
function onManageRecordingClick(e) { embed() {
var options = this.options; const self = this;
if (!this.TimerId || this.Status === 'Cancelled') {
return;
}
var self = this;
require(['recordingEditor'], function (recordingEditor) {
recordingEditor.show(self.TimerId, options.serverId, {
enableCancel: false
}).then(function () {
self.changed = true;
});
});
}
function onManageSeriesRecordingClick(e) {
var options = this.options;
if (!this.SeriesTimerId) {
return;
}
var self = this;
require(['seriesRecordingEditor'], function (seriesRecordingEditor) {
seriesRecordingEditor.show(self.SeriesTimerId, options.serverId, {
enableCancel: false
}).then(function () {
self.changed = true;
});
});
}
function onRecordChange(e) {
this.changed = true;
var self = this;
var options = this.options;
var apiClient = connectionManager.getApiClient(options.serverId);
var button = dom.parentWithTag(e.target, 'BUTTON');
var isChecked = !button.querySelector('.material-icons').classList.contains('recordingIcon-active');
var hasEnabledTimer = this.TimerId && this.Status !== 'Cancelled';
if (isChecked) {
if (!hasEnabledTimer) {
loading.show();
recordingHelper.createRecording(apiClient, options.programId, false).then(function () {
events.trigger(self, 'recordingchanged');
fetchData(self);
loading.hide();
});
}
} else {
if (hasEnabledTimer) {
loading.show();
recordingHelper.cancelTimer(apiClient, this.TimerId, true).then(function () {
events.trigger(self, 'recordingchanged');
fetchData(self);
loading.hide();
});
}
}
}
function sendToast(msg) {
require(['toast'], function (toast) {
toast(msg);
});
}
function onRecordSeriesChange(e) {
this.changed = true;
var self = this;
var options = this.options;
var apiClient = connectionManager.getApiClient(options.serverId);
var button = dom.parentWithTag(e.target, 'BUTTON');
var isChecked = !button.querySelector('.material-icons').classList.contains('recordingIcon-active');
if (isChecked) {
options.parent.querySelector('.recordSeriesContainer').classList.remove('hide');
if (!this.SeriesTimerId) {
var promise = this.TimerId ?
recordingHelper.changeRecordingToSeries(apiClient, this.TimerId, options.programId) :
recordingHelper.createRecording(apiClient, options.programId, true);
promise.then(function () {
fetchData(self);
});
}
} else {
if (this.SeriesTimerId) {
apiClient.cancelLiveTvSeriesTimer(this.SeriesTimerId).then(function () {
sendToast(globalize.translate('RecordingCancelled'));
fetchData(self);
});
}
}
}
RecordingEditor.prototype.embed = function () {
var self = this;
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['text!./recordingfields.template.html'], function (template) { import('text!./recordingfields.template.html').then(({default: template}) => {
var options = self.options; const options = self.options;
var context = options.parent; const context = options.parent;
context.innerHTML = globalize.translateHtml(template, 'core'); context.innerHTML = globalize.translateHtml(template, 'core');
context.querySelector('.singleRecordingButton').addEventListener('click', onRecordChange.bind(self)); context.querySelector('.singleRecordingButton').addEventListener('click', onRecordChange.bind(self));
@ -228,29 +131,134 @@ define(['globalize', 'connectionManager', 'serverNotifications', 'require', 'loa
fetchData(self).then(resolve); fetchData(self).then(resolve);
}); });
}); });
}; }
RecordingEditor.prototype.hasChanged = function () { hasChanged() {
return this.changed; return this.changed;
}; }
RecordingEditor.prototype.refresh = function () { refresh() {
fetchData(this); fetchData(this);
}; }
RecordingEditor.prototype.destroy = function () { destroy() {
var timerChangedHandler = this.timerChangedHandler; const timerChangedHandler = this.timerChangedHandler;
this.timerChangedHandler = null; this.timerChangedHandler = null;
events.off(serverNotifications, 'TimerCreated', timerChangedHandler); events.off(serverNotifications, 'TimerCreated', timerChangedHandler);
events.off(serverNotifications, 'TimerCancelled', timerChangedHandler); events.off(serverNotifications, 'TimerCancelled', timerChangedHandler);
var seriesTimerChangedHandler = this.seriesTimerChangedHandler; const seriesTimerChangedHandler = this.seriesTimerChangedHandler;
this.seriesTimerChangedHandler = null; this.seriesTimerChangedHandler = null;
events.off(serverNotifications, 'SeriesTimerCreated', seriesTimerChangedHandler); events.off(serverNotifications, 'SeriesTimerCreated', seriesTimerChangedHandler);
events.off(serverNotifications, 'SeriesTimerCancelled', seriesTimerChangedHandler); events.off(serverNotifications, 'SeriesTimerCancelled', seriesTimerChangedHandler);
}; }
}
return RecordingEditor; function onManageRecordingClick(e) {
}); const options = this.options;
if (!this.TimerId || this.Status === 'Cancelled') {
return;
}
const self = this;
import('recordingEditor').then(({default: recordingEditor}) => {
recordingEditor.show(self.TimerId, options.serverId, {
enableCancel: false
}).then(function () {
self.changed = true;
});
});
}
function onManageSeriesRecordingClick(e) {
const options = this.options;
if (!this.SeriesTimerId) {
return;
}
const self = this;
import('seriesRecordingEditor').then(({default: seriesRecordingEditor}) => {
seriesRecordingEditor.show(self.SeriesTimerId, options.serverId, {
enableCancel: false
}).then(function () {
self.changed = true;
});
});
}
function onRecordChange(e) {
this.changed = true;
const self = this;
const options = this.options;
const apiClient = connectionManager.getApiClient(options.serverId);
const button = dom.parentWithTag(e.target, 'BUTTON');
const isChecked = !button.querySelector('.material-icons').classList.contains('recordingIcon-active');
const hasEnabledTimer = this.TimerId && this.Status !== 'Cancelled';
if (isChecked) {
if (!hasEnabledTimer) {
loading.show();
recordingHelper.createRecording(apiClient, options.programId, false).then(function () {
events.trigger(self, 'recordingchanged');
fetchData(self);
loading.hide();
});
}
} else {
if (hasEnabledTimer) {
loading.show();
recordingHelper.cancelTimer(apiClient, this.TimerId, true).then(function () {
events.trigger(self, 'recordingchanged');
fetchData(self);
loading.hide();
});
}
}
}
function sendToast(msg) {
import('toast').then(({default: toast}) => {
toast(msg);
});
}
function onRecordSeriesChange(e) {
this.changed = true;
const self = this;
const options = this.options;
const apiClient = connectionManager.getApiClient(options.serverId);
const button = dom.parentWithTag(e.target, 'BUTTON');
const isChecked = !button.querySelector('.material-icons').classList.contains('recordingIcon-active');
if (isChecked) {
options.parent.querySelector('.recordSeriesContainer').classList.remove('hide');
if (!this.SeriesTimerId) {
const promise = this.TimerId ?
recordingHelper.changeRecordingToSeries(apiClient, this.TimerId, options.programId) :
recordingHelper.createRecording(apiClient, options.programId, true);
promise.then(function () {
fetchData(self);
});
}
} else {
if (this.SeriesTimerId) {
apiClient.cancelLiveTvSeriesTimer(this.SeriesTimerId).then(function () {
sendToast(globalize.translate('RecordingCancelled'));
fetchData(self);
});
}
}
}
export default RecordingEditor;

View file

@ -66,7 +66,7 @@ function showSubtitleMenu(context, player, button, item) {
}); });
menuItems.unshift({ menuItems.unshift({
id: -1, id: -1,
name: globalize.translate('ButtonOff'), name: globalize.translate('Off'),
selected: currentIndex == null selected: currentIndex == null
}); });

View file

@ -2,7 +2,7 @@ define(function () {
'use strict'; 'use strict';
// hack to work around the server's auto-redirection feature // hack to work around the server's auto-redirection feature
var addRedirectPrevention = self.dashboardVersion != null && self.Dashboard && !self.AppInfo.isNativeApp; var addRedirectPrevention = window.dashboardVersion != null && window.Dashboard && !window.AppInfo.isNativeApp;
return { return {

View file

@ -26,7 +26,7 @@
}); });
} }
self.addEventListener('notificationclick', function (event) { window.addEventListener('notificationclick', function (event) {
var notification = event.notification; var notification = event.notification;
notification.close(); notification.close();

View file

@ -9,7 +9,7 @@
</div> </div>
<div class="inputContainer"> <div class="inputContainer">
<input is="emby-input" type="text" id="txtCustomName" label="${LabelCustomDeviceDisplayName}" /> <input is="emby-input" type="text" id="txtCustomName" label="${LabelDisplayName}" />
<div class="fieldDescription">${LabelCustomDeviceDisplayNameHelp}</div> <div class="fieldDescription">${LabelCustomDeviceDisplayNameHelp}</div>
</div> </div>
</div> </div>

View file

@ -8,7 +8,7 @@
</div> </div>
</div> </div>
<div data-role="controlgroup" data-type="horizontal" data-mini="true"> <div data-role="controlgroup" data-type="horizontal" data-mini="true">
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioInfo" data-value="tabInfo">${TabInfo}</a> <a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioInfo" data-value="tabInfo">${ButtonInfo}</a>
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioDirectPlay" data-value="tabDirectPlayProfiles">${TabDirectPlay}</a> <a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioDirectPlay" data-value="tabDirectPlayProfiles">${TabDirectPlay}</a>
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioTranscoding" data-value="tabTranscodingProfiles">${Transcoding}</a> <a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioTranscoding" data-value="tabTranscodingProfiles">${Transcoding}</a>
<a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioContainers" data-value="tabContainerProfiles">${TabContainers}</a> <a href="#" is="emby-linkbutton" data-role="button" class="radioTabButton" id="radioContainers" data-value="tabContainerProfiles">${TabContainers}</a>
@ -319,7 +319,7 @@
<div data-role="content"> <div data-role="content">
<div data-role="controlgroup" data-type="horizontal" data-mini="true"> <div data-role="controlgroup" data-type="horizontal" data-mini="true">
<input type="radio" name="radioTranscodingTab" class="radioTabButton" id="radioTranscodingBasics" value="tabTranscodingBasics"> <input type="radio" name="radioTranscodingTab" class="radioTabButton" id="radioTranscodingBasics" value="tabTranscodingBasics">
<label for="radioTranscodingBasics">${TabInfo}</label> <label for="radioTranscodingBasics">${ButtonInfo}</label>
<input type="radio" name="radioTranscodingTab" class="radioTabButton" id="radioTranscodingAdvanced" value="tabTranscodingAdvanced"> <input type="radio" name="radioTranscodingTab" class="radioTabButton" id="radioTranscodingAdvanced" value="tabTranscodingAdvanced">
<label for="radioTranscodingAdvanced">${TabAdvanced}</label> <label for="radioTranscodingAdvanced">${TabAdvanced}</label>
</div> </div>
@ -341,16 +341,16 @@
</div> </div>
</div> </div>
<div class="inputContainer"> <div class="inputContainer">
<input is="emby-input" type="text" id="txtTranscodingContainer" label="${LabelTranscodingContainer}"; required="required" /> <input is="emby-input" type="text" id="txtTranscodingContainer" label="${LabelProfileContainer}"; required="required" />
</div> </div>
<div id="fldTranscodingVideoCodec" style="margin: 1em 0;"> <div id="fldTranscodingVideoCodec" style="margin: 1em 0;">
<div class="inputContainer"> <div class="inputContainer">
<input is="emby-input" type="text" id="txtTranscodingVideoCodec" label="${LabelTranscodingVideoCodec}" /> <input is="emby-input" type="text" id="txtTranscodingVideoCodec" label="${LabelVideoCodec}" />
</div> </div>
</div> </div>
<div id="fldTranscodingAudioCodec" style="margin: 1em 0;"> <div id="fldTranscodingAudioCodec" style="margin: 1em 0;">
<div class="inputContainer"> <div class="inputContainer">
<input is="emby-input" type="text" id="txtTranscodingAudioCodec" label="${LabelTranscodingAudioCodec}" /> <input is="emby-input" type="text" id="txtTranscodingAudioCodec" label="${LabelAudioCodec}" />
</div> </div>
</div> </div>
</div> </div>

View file

@ -128,7 +128,7 @@ import libraryMenu from 'libraryMenu';
name: globalize.translate('Transcoding') name: globalize.translate('Transcoding')
}, { }, {
href: 'playbackconfiguration.html', href: 'playbackconfiguration.html',
name: globalize.translate('TabResumeSettings') name: globalize.translate('ButtonResume')
}, { }, {
href: 'streamingsettings.html', href: 'streamingsettings.html',
name: globalize.translate('TabStreaming') name: globalize.translate('TabStreaming')

View file

@ -17,7 +17,7 @@
<div class="selectContainer"> <div class="selectContainer">
<select is="emby-select" id="selectLocalizationLanguage" label="${LabelPreferredDisplayLanguage}"></select> <select is="emby-select" id="selectLocalizationLanguage" label="${LabelPreferredDisplayLanguage}"></select>
<div class="fieldDescription"> <div class="fieldDescription">
<div>${LabelPreferredDisplayLanguageHelp}</div> <div>${LabelDisplayLanguageHelp}</div>
<div style="margin-top: .25em;"> <div style="margin-top: .25em;">
<a is="emby-linkbutton" rel="noopener noreferrer" class="button-link" href="https://docs.jellyfin.org/general/contributing/index.html" target="_blank">${LearnHowYouCanContribute}</a> <a is="emby-linkbutton" rel="noopener noreferrer" class="button-link" href="https://docs.jellyfin.org/general/contributing/index.html" target="_blank">${LearnHowYouCanContribute}</a>
</div> </div>

View file

@ -93,7 +93,7 @@ import 'emby-itemrefreshindicator';
const virtualFolder = virtualFolders[index]; const virtualFolder = virtualFolders[index];
const menuItems = []; const menuItems = [];
menuItems.push({ menuItems.push({
name: globalize.translate('ButtonEditImages'), name: globalize.translate('EditImages'),
id: 'editimages', id: 'editimages',
icon: 'photo' icon: 'photo'
}); });

View file

@ -3,7 +3,7 @@
<div class="content-primary"> <div class="content-primary">
<form class="playbackConfigurationForm"> <form class="playbackConfigurationForm">
<div class="sectionTitleContainer flex align-items-center"> <div class="sectionTitleContainer flex align-items-center">
<h2 class="sectionTitle">${TabResumeSettings}</h2> <h2 class="sectionTitle">${ButtonResume}</h2>
</div> </div>
<div class="inputContainer"> <div class="inputContainer">
<input is="emby-input" type="number" id="txtMinResumePct" name="txtMinResumePct" pattern="[0-9]*" required min="0" max="100" label="${LabelMinResumePercentage}"></input> <input is="emby-input" type="number" id="txtMinResumePct" name="txtMinResumePct" pattern="[0-9]*" required min="0" max="100" label="${LabelMinResumePercentage}"></input>

View file

@ -32,7 +32,7 @@ import globalize from 'globalize';
name: globalize.translate('Transcoding') name: globalize.translate('Transcoding')
}, { }, {
href: 'playbackconfiguration.html', href: 'playbackconfiguration.html',
name: globalize.translate('TabResumeSettings') name: globalize.translate('ButtonResume')
}, { }, {
href: 'streamingsettings.html', href: 'streamingsettings.html',
name: globalize.translate('TabStreaming') name: globalize.translate('TabStreaming')

View file

@ -23,7 +23,7 @@
<div data-role="popup" id="popupAddTrigger" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;"> <div data-role="popup" id="popupAddTrigger" class="dialog dialog-fixedSize dialog-medium hide" style="position: fixed; top: 10%;">
<form class="addTriggerForm" style="padding:1em;"> <form class="addTriggerForm" style="padding:1em;">
<div class="ui-bar-a"> <div class="ui-bar-a">
<h3>${HeaderAddScheduledTaskTrigger}</h3> <h3>${ButtonAddScheduledTaskTrigger}</h3>
</div> </div>
<div data-role="content"> <div data-role="content">
<div class="selectContainer"> <div class="selectContainer">

View file

@ -27,7 +27,7 @@ import globalize from 'globalize';
name: globalize.translate('Transcoding') name: globalize.translate('Transcoding')
}, { }, {
href: 'playbackconfiguration.html', href: 'playbackconfiguration.html',
name: globalize.translate('TabResumeSettings') name: globalize.translate('ButtonResume')
}, { }, {
href: 'streamingsettings.html', href: 'streamingsettings.html',
name: globalize.translate('TabStreaming') name: globalize.translate('TabStreaming')

View file

@ -4,7 +4,7 @@
<form class="newUserProfileForm"> <form class="newUserProfileForm">
<div class="verticalSection"> <div class="verticalSection">
<div class="sectionTitleContainer flex align-items-center"> <div class="sectionTitleContainer flex align-items-center">
<h2 class="sectionTitle">${HeaderAddUser}</h2> <h2 class="sectionTitle">${ButtonAddUser}</h2>
<a is="emby-linkbutton" rel="noopener noreferrer" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/server/users/">${Help}</a> <a is="emby-linkbutton" rel="noopener noreferrer" class="raised button-alt headerHelpButton" target="_blank" href="https://docs.jellyfin.org/general/server/users/">${Help}</a>
</div> </div>

View file

@ -83,7 +83,7 @@ import 'emby-button';
loading.hide(); loading.hide();
import('toast').then(({default: toast}) => { import('toast').then(({default: toast}) => {
toast(globalize.translate('MessageSettingsSaved')); toast(globalize.translate('SettingsSaved'));
}); });
loadUser(view, params); loadUser(view, params);

View file

@ -18,7 +18,7 @@
</div> </div>
</button> </button>
<button is="emby-button" type="button" class="button-flat btnPlay hide detailButton" title="${ButtonPlay}" data-mode="play"> <button is="emby-button" type="button" class="button-flat btnPlay hide detailButton" title="${Play}" data-mode="play">
<div class="detailButton-content"> <div class="detailButton-content">
<span class="material-icons detailButton-icon play_arrow"></span> <span class="material-icons detailButton-icon play_arrow"></span>
</div> </div>
@ -193,7 +193,7 @@
</div> </div>
<div id="castCollapsible" class="verticalSection detailVerticalSection hide"> <div id="castCollapsible" class="verticalSection detailVerticalSection hide">
<h2 id="peopleHeader" class="sectionTitle sectionTitle-cards padded-right">${HeaderCastCrew}</h2> <h2 id="peopleHeader" class="sectionTitle sectionTitle-cards padded-right">${HeaderCastAndCrew}</h2>
<div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true"> <div is="emby-scroller" class="padded-top-focusscale padded-bottom-focusscale" data-centerfocus="true">
<div id="castContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div> <div id="castContent" is="emby-itemscontainer" class="scrollSlider focuscontainer-x itemsContainer"></div>
</div> </div>

View file

@ -1,6 +1,7 @@
import appHost from 'apphost'; import appHost from 'apphost';
import loading from 'loading'; import loading from 'loading';
import appRouter from 'appRouter'; import appRouter from 'appRouter';
import itemShortcuts from 'itemShortcuts';
import layoutManager from 'layoutManager'; import layoutManager from 'layoutManager';
import connectionManager from 'connectionManager'; import connectionManager from 'connectionManager';
import * as userSettings from 'userSettings'; import * as userSettings from 'userSettings';
@ -242,7 +243,7 @@ import 'emby-select';
return m.Type === 'Audio'; return m.Type === 'Audio';
}); });
const select = page.querySelector('.selectAudio'); const select = page.querySelector('.selectAudio');
select.setLabel(globalize.translate('LabelAudio')); select.setLabel(globalize.translate('Audio'));
const selectedId = mediaSource.DefaultAudioStreamIndex; const selectedId = mediaSource.DefaultAudioStreamIndex;
select.innerHTML = tracks.map(function (v) { select.innerHTML = tracks.map(function (v) {
const selected = v.Index === selectedId ? ' selected' : ''; const selected = v.Index === selectedId ? ' selected' : '';
@ -271,7 +272,7 @@ import 'emby-select';
return m.Type === 'Subtitle'; return m.Type === 'Subtitle';
}); });
const select = page.querySelector('.selectSubtitles'); const select = page.querySelector('.selectSubtitles');
select.setLabel(globalize.translate('LabelSubtitles')); select.setLabel(globalize.translate('Subtitles'));
const selectedId = mediaSource.DefaultSubtitleStreamIndex == null ? -1 : mediaSource.DefaultSubtitleStreamIndex; const selectedId = mediaSource.DefaultSubtitleStreamIndex == null ? -1 : mediaSource.DefaultSubtitleStreamIndex;
const videoTracks = mediaSource.MediaStreams.filter(function (m) { const videoTracks = mediaSource.MediaStreams.filter(function (m) {
@ -758,8 +759,8 @@ import 'emby-select';
overlayText: false, overlayText: false,
transition: false, transition: false,
disableIndicators: true, disableIndicators: true,
disableHoverMenu: true,
overlayPlayButton: true, overlayPlayButton: true,
action: 'play',
width: dom.getWindowSize().innerWidth * 0.25 width: dom.getWindowSize().innerWidth * 0.25
}); });
@ -1066,7 +1067,7 @@ import 'emby-select';
} }
function enableScrollX() { function enableScrollX() {
return browser.mobile && screen.availWidth <= 1000; return browser.mobile && window.screen.availWidth <= 1000;
} }
function getPortraitShape(scrollX) { function getPortraitShape(scrollX) {
@ -1438,7 +1439,7 @@ import 'emby-select';
name: globalize.translate('Albums'), name: globalize.translate('Albums'),
type: 'MusicAlbum' type: 'MusicAlbum'
}, { }, {
name: globalize.translate('HeaderBooks'), name: globalize.translate('Books'),
type: 'Book' type: 'Book'
}]; }];
renderCollectionItems(page, item, collectionItemTypes, result.Items); renderCollectionItems(page, item, collectionItemTypes, result.Items);
@ -1446,7 +1447,7 @@ import 'emby-select';
}); });
if (item.Type == 'Season') { if (item.Type == 'Season') {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderEpisodes'); page.querySelector('#childrenTitle').innerHTML = globalize.translate('Episodes');
} else if (item.Type == 'Series') { } else if (item.Type == 'Series') {
page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderSeasons'); page.querySelector('#childrenTitle').innerHTML = globalize.translate('HeaderSeasons');
} else if (item.Type == 'MusicAlbum') { } else if (item.Type == 'MusicAlbum') {
@ -1895,6 +1896,10 @@ import 'emby-select';
playCurrentItem(this, this.getAttribute('data-mode')); playCurrentItem(this, this.getAttribute('data-mode'));
} }
function onPosterClick(e) {
itemShortcuts.onClick.call(view.querySelector('.detailImageContainer'), e);
}
function onInstantMixClick() { function onInstantMixClick() {
playbackManager.instantMix(currentItem); playbackManager.instantMix(currentItem);
} }
@ -1935,14 +1940,19 @@ import 'emby-select';
} }
function onMoreCommandsClick() { function onMoreCommandsClick() {
const button = this; var button = this;
apiClient.getCurrentUser().then(function (user) { var selectedItem = currentItem;
itemContextMenu.show(getContextMenuOptions(currentItem, user, button)).then(function (result) { apiClient.getItem(apiClient.getCurrentUserId(), view.querySelector('.selectSource').value).then(function (item) {
if (result.deleted) { selectedItem = item;
appRouter.goHome();
} else if (result.updated) { apiClient.getCurrentUser().then(function (user) {
reload(self, view, params); itemContextMenu.show(getContextMenuOptions(selectedItem, user, button)).then(function (result) {
} if (result.deleted) {
appRouter.goHome();
} else if (result.updated) {
reload(self, view, params);
}
});
}); });
}); });
} }
@ -1981,6 +1991,7 @@ import 'emby-select';
bindAll(view, '.btnCancelSeriesTimer', 'click', onCancelSeriesTimerClick); bindAll(view, '.btnCancelSeriesTimer', 'click', onCancelSeriesTimerClick);
bindAll(view, '.btnCancelTimer', 'click', onCancelTimerClick); bindAll(view, '.btnCancelTimer', 'click', onCancelTimerClick);
bindAll(view, '.btnDownload', 'click', onDownloadClick); bindAll(view, '.btnDownload', 'click', onDownloadClick);
view.querySelector('.detailImageContainer').addEventListener('click', onPosterClick);
view.querySelector('.trackSelections').addEventListener('submit', onTrackSelectionsSubmit); view.querySelector('.trackSelections').addEventListener('submit', onTrackSelectionsSubmit);
view.querySelector('.btnSplitVersions').addEventListener('click', function () { view.querySelector('.btnSplitVersions').addEventListener('click', function () {
splitVersions(self, view, apiClient, params); splitVersions(self, view, apiClient, params);

View file

@ -63,7 +63,7 @@
<div class="pageTabContent" id="channelsTab" data-index="2"> <div class="pageTabContent" id="channelsTab" data-index="2">
<div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom"> <div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom">
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnFilter sectionTitleButton" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter sectionTitleButton" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div is="emby-itemscontainer" id="items" class="itemsContainer vertical-wrap padded-left padded-right"></div> <div is="emby-itemscontainer" id="items" class="itemsContainer vertical-wrap padded-left padded-right"></div>
</div> </div>

View file

@ -11,7 +11,7 @@
<form class="liveTvSettingsForm"> <form class="liveTvSettingsForm">
<div class="selectContainer"> <div class="selectContainer">
<select is="emby-select" id="selectGuideDays" label="${LabelNumberOfGuideDays}"> <select is="emby-select" id="selectGuideDays" label="${LabelNumberOfGuideDays}">
<option value="">${OptionAutomatic}</option> <option value="">${OptionAuto}</option>
<option value="1">1</option> <option value="1">1</option>
<option value="2">2</option> <option value="2">2</option>
<option value="3">3</option> <option value="3">3</option>

View file

@ -259,7 +259,7 @@ function showDeviceMenu(button, tunerDeviceId) {
id: 'delete' id: 'delete'
}); });
items.push({ items.push({
name: globalize.translate('ButtonEdit'), name: globalize.translate('Edit'),
id: 'edit' id: 'edit'
}); });

View file

@ -5,7 +5,7 @@
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button> <button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button>
<button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button> <button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div class="alphaPicker alphaPicker-fixed alphaPicker-vertical"> <div class="alphaPicker alphaPicker-fixed alphaPicker-vertical">
@ -47,7 +47,7 @@
<div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom"> <div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom">
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button> <button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div class="alphaPicker alphaPicker-fixed alphaPicker-fixed-right alphaPicker-vertical"> <div class="alphaPicker alphaPicker-fixed alphaPicker-fixed-right alphaPicker-vertical">

View file

@ -229,7 +229,7 @@ import 'emby-button';
}, { }, {
name: globalize.translate('Suggestions') name: globalize.translate('Suggestions')
}, { }, {
name: globalize.translate('TabTrailers') name: globalize.translate('Trailers')
}, { }, {
name: globalize.translate('Favorites') name: globalize.translate('Favorites')
}, { }, {

View file

@ -41,7 +41,7 @@
<button is="paper-icon-button-light" class="btnShuffle musicglobalButton" title="${Shuffle}"><span class="material-icons shuffle"></span></button> <button is="paper-icon-button-light" class="btnShuffle musicglobalButton" title="${Shuffle}"><span class="material-icons shuffle"></span></button>
<button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button> <button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button>
<button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button> <button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div class="alphaPicker alphaPicker-fixed alphaPicker-vertical"> <div class="alphaPicker alphaPicker-fixed alphaPicker-vertical">
@ -57,7 +57,7 @@
<div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom"> <div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom">
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button> <button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div class="alphaPicker alphaPicker-fixed alphaPicker-vertical"> <div class="alphaPicker alphaPicker-fixed alphaPicker-vertical">
@ -73,7 +73,7 @@
<div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom"> <div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom">
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button> <button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div class="alphaPicker alphaPicker-fixed alphaPicker-vertical"> <div class="alphaPicker alphaPicker-fixed alphaPicker-vertical">
@ -93,7 +93,7 @@
<div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom"> <div class="flex align-items-center justify-content-center flex-wrap-wrap padded-top padded-left padded-right padded-bottom">
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button> <button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div is="emby-itemscontainer" id="items" class="itemsContainer vertical-list" style="max-width:67.5em;margin: 0 auto;"></div> <div is="emby-itemscontainer" id="items" class="itemsContainer vertical-list" style="max-width:67.5em;margin: 0 auto;"></div>

View file

@ -69,8 +69,8 @@ import 'emby-itemscontainer';
return savedQueryKey; return savedQueryKey;
} }
function onViewStyleChange() { const onViewStyleChange = () => {
const viewStyle = self.getCurrentViewStyle(); const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer'); const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') { if (viewStyle == 'List') {
@ -82,13 +82,13 @@ import 'emby-itemscontainer';
} }
itemsContainer.innerHTML = ''; itemsContainer.innerHTML = '';
} };
function reloadItems(page) { const reloadItems = (page) => {
loading.show(); loading.show();
isLoading = true; isLoading = true;
const query = getQuery(); const query = getQuery();
ApiClient.getItems(ApiClient.getCurrentUserId(), query).then(function (result) { ApiClient.getItems(ApiClient.getCurrentUserId(), query).then((result) => {
function onNextPageClick() { function onNextPageClick() {
if (isLoading) { if (isLoading) {
return; return;
@ -124,7 +124,7 @@ import 'emby-itemscontainer';
sortButton: false, sortButton: false,
filterButton: false filterButton: false
}); });
const viewStyle = self.getCurrentViewStyle(); const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'List') { if (viewStyle == 'List') {
html = listView.getListViewHtml({ html = listView.getListViewHtml({
items: result.Items, items: result.Items,
@ -182,19 +182,18 @@ import 'emby-itemscontainer';
autoFocuser.autoFocus(tabContent); autoFocuser.autoFocus(tabContent);
}); });
}); });
} };
function updateFilterControls(tabContent) { const updateFilterControls = (tabContent) => {
const query = getQuery(); const query = getQuery();
self.alphaPicker.value(query.NameStartsWithOrGreater); this.alphaPicker.value(query.NameStartsWithOrGreater);
} };
let savedQueryKey; let savedQueryKey;
let pageData; let pageData;
const self = this;
let isLoading = false; let isLoading = false;
self.showFilterMenu = function () { this.showFilterMenu = function () {
import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
const filterDialog = new filterDialogFactory({ const filterDialog = new filterDialogFactory({
query: getQuery(), query: getQuery(),
@ -209,11 +208,11 @@ import 'emby-itemscontainer';
}); });
}; };
self.getCurrentViewStyle = function () { this.getCurrentViewStyle = function () {
return getPageData().view; return getPageData().view;
}; };
function initPage(tabContent) { const initPage = (tabContent) => {
const alphaPickerElement = tabContent.querySelector('.alphaPicker'); const alphaPickerElement = tabContent.querySelector('.alphaPicker');
const itemsContainer = tabContent.querySelector('.itemsContainer'); const itemsContainer = tabContent.querySelector('.itemsContainer');
@ -224,7 +223,7 @@ import 'emby-itemscontainer';
query.StartIndex = 0; query.StartIndex = 0;
reloadItems(tabContent); reloadItems(tabContent);
}); });
self.alphaPicker = new AlphaPicker({ this.alphaPicker = new AlphaPicker({
element: alphaPickerElement, element: alphaPickerElement,
valueChangeEvent: 'click' valueChangeEvent: 'click'
}); });
@ -233,10 +232,10 @@ import 'emby-itemscontainer';
alphaPickerElement.classList.add('alphaPicker-fixed-right'); alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker'); itemsContainer.classList.add('padded-right-withalphapicker');
tabContent.querySelector('.btnFilter').addEventListener('click', function () { tabContent.querySelector('.btnFilter').addEventListener('click', () => {
self.showFilterMenu(); this.showFilterMenu();
}); });
tabContent.querySelector('.btnSort').addEventListener('click', function (e) { tabContent.querySelector('.btnSort').addEventListener('click', (e) => {
libraryBrowser.showSortMenu({ libraryBrowser.showSortMenu({
items: [{ items: [{
name: globalize.translate('OptionNameSort'), name: globalize.translate('OptionNameSort'),
@ -269,8 +268,8 @@ import 'emby-itemscontainer';
}); });
}); });
const btnSelectView = tabContent.querySelector('.btnSelectView'); const btnSelectView = tabContent.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', function (e) { btnSelectView.addEventListener('click', (e) => {
libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(',')); libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
}); });
btnSelectView.addEventListener('layoutchange', function (e) { btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle; const viewStyle = e.detail.viewStyle;
@ -282,17 +281,17 @@ import 'emby-itemscontainer';
}); });
tabContent.querySelector('.btnPlayAll').addEventListener('click', playAll); tabContent.querySelector('.btnPlayAll').addEventListener('click', playAll);
tabContent.querySelector('.btnShuffle').addEventListener('click', shuffle); tabContent.querySelector('.btnShuffle').addEventListener('click', shuffle);
} };
initPage(tabContent); initPage(tabContent);
onViewStyleChange(); onViewStyleChange();
self.renderTab = function () { this.renderTab = function () {
reloadItems(tabContent); reloadItems(tabContent);
updateFilterControls(tabContent); updateFilterControls(tabContent);
}; };
self.destroy = function () {}; this.destroy = function () {};
} }
/* eslint-enable indent */ /* eslint-enable indent */

View file

@ -45,16 +45,16 @@ import 'emby-itemscontainer';
return getPageData(context).query; return getPageData(context).query;
} }
function getSavedQueryKey(context) { const getSavedQueryKey = (context) => {
if (!context.savedQueryKey) { if (!context.savedQueryKey) {
context.savedQueryKey = libraryBrowser.getSavedQueryKey(self.mode); context.savedQueryKey = libraryBrowser.getSavedQueryKey(this.mode);
} }
return context.savedQueryKey; return context.savedQueryKey;
} };
function onViewStyleChange() { const onViewStyleChange = () => {
const viewStyle = self.getCurrentViewStyle(); const viewStyle = this.getCurrentViewStyle();
const itemsContainer = tabContent.querySelector('.itemsContainer'); const itemsContainer = tabContent.querySelector('.itemsContainer');
if (viewStyle == 'List') { if (viewStyle == 'List') {
@ -66,16 +66,16 @@ import 'emby-itemscontainer';
} }
itemsContainer.innerHTML = ''; itemsContainer.innerHTML = '';
} };
function reloadItems(page) { const reloadItems = (page) => {
loading.show(); loading.show();
isLoading = true; isLoading = true;
const query = getQuery(page); const query = getQuery(page);
const promise = self.mode == 'albumartists' ? const promise = this.mode == 'albumartists' ?
ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) : ApiClient.getAlbumArtists(ApiClient.getCurrentUserId(), query) :
ApiClient.getArtists(ApiClient.getCurrentUserId(), query); ApiClient.getArtists(ApiClient.getCurrentUserId(), query);
promise.then(function (result) { promise.then((result) => {
function onNextPageClick() { function onNextPageClick() {
if (isLoading) { if (isLoading) {
return; return;
@ -111,7 +111,7 @@ import 'emby-itemscontainer';
sortButton: false, sortButton: false,
filterButton: false filterButton: false
}); });
const viewStyle = self.getCurrentViewStyle(); const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'List') { if (viewStyle == 'List') {
html = listView.getListViewHtml({ html = listView.getListViewHtml({
items: result.Items, items: result.Items,
@ -165,22 +165,21 @@ import 'emby-itemscontainer';
autoFocuser.autoFocus(tabContent); autoFocuser.autoFocus(tabContent);
}); });
}); });
} };
function updateFilterControls(tabContent) { const updateFilterControls = (tabContent) => {
const query = getQuery(tabContent); const query = getQuery(tabContent);
self.alphaPicker.value(query.NameStartsWithOrGreater); this.alphaPicker.value(query.NameStartsWithOrGreater);
} };
const self = this;
const data = {}; const data = {};
let isLoading = false; let isLoading = false;
self.showFilterMenu = function () { this.showFilterMenu = function () {
import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => { import('components/filterdialog/filterdialog').then(({default: filterDialogFactory}) => {
const filterDialog = new filterDialogFactory({ const filterDialog = new filterDialogFactory({
query: getQuery(tabContent), query: getQuery(tabContent),
mode: self.mode, mode: this.mode,
serverId: ApiClient.serverId() serverId: ApiClient.serverId()
}); });
events.on(filterDialog, 'filterchange', function () { events.on(filterDialog, 'filterchange', function () {
@ -191,11 +190,11 @@ import 'emby-itemscontainer';
}); });
}; };
self.getCurrentViewStyle = function () { this.getCurrentViewStyle = function () {
return getPageData(tabContent).view; return getPageData(tabContent).view;
}; };
function initPage(tabContent) { const initPage = (tabContent) => {
const alphaPickerElement = tabContent.querySelector('.alphaPicker'); const alphaPickerElement = tabContent.querySelector('.alphaPicker');
const itemsContainer = tabContent.querySelector('.itemsContainer'); const itemsContainer = tabContent.querySelector('.itemsContainer');
@ -206,7 +205,7 @@ import 'emby-itemscontainer';
query.StartIndex = 0; query.StartIndex = 0;
reloadItems(tabContent); reloadItems(tabContent);
}); });
self.alphaPicker = new AlphaPicker({ this.alphaPicker = new AlphaPicker({
element: alphaPickerElement, element: alphaPickerElement,
valueChangeEvent: 'click' valueChangeEvent: 'click'
}); });
@ -215,12 +214,12 @@ import 'emby-itemscontainer';
alphaPickerElement.classList.add('alphaPicker-fixed-right'); alphaPickerElement.classList.add('alphaPicker-fixed-right');
itemsContainer.classList.add('padded-right-withalphapicker'); itemsContainer.classList.add('padded-right-withalphapicker');
tabContent.querySelector('.btnFilter').addEventListener('click', function () { tabContent.querySelector('.btnFilter').addEventListener('click', () => {
self.showFilterMenu(); this.showFilterMenu();
}); });
const btnSelectView = tabContent.querySelector('.btnSelectView'); const btnSelectView = tabContent.querySelector('.btnSelectView');
btnSelectView.addEventListener('click', function (e) { btnSelectView.addEventListener('click', function (e) {
libraryBrowser.showLayoutMenu(e.target, self.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(',')); libraryBrowser.showLayoutMenu(e.target, this.getCurrentViewStyle(), 'List,Poster,PosterCard'.split(','));
}); });
btnSelectView.addEventListener('layoutchange', function (e) { btnSelectView.addEventListener('layoutchange', function (e) {
const viewStyle = e.detail.viewStyle; const viewStyle = e.detail.viewStyle;
@ -230,17 +229,17 @@ import 'emby-itemscontainer';
onViewStyleChange(); onViewStyleChange();
reloadItems(tabContent); reloadItems(tabContent);
}); });
} };
initPage(tabContent); initPage(tabContent);
onViewStyleChange(); onViewStyleChange();
self.renderTab = function () { this.renderTab = function () {
reloadItems(tabContent); reloadItems(tabContent);
updateFilterControls(tabContent); updateFilterControls(tabContent);
}; };
self.destroy = function () {}; this.destroy = function () {};
} }
/* eslint-enable indent */ /* eslint-enable indent */

View file

@ -42,11 +42,11 @@ import loading from 'loading';
return ApiClient.getGenres(ApiClient.getCurrentUserId(), query); return ApiClient.getGenres(ApiClient.getCurrentUserId(), query);
} }
function reloadItems(context, promise) { const reloadItems = (context, promise) => {
const query = getQuery(); const query = getQuery();
promise.then(function (result) { promise.then((result) => {
let html = ''; let html = '';
const viewStyle = self.getCurrentViewStyle(); const viewStyle = this.getCurrentViewStyle();
if (viewStyle == 'Thumb') { if (viewStyle == 'Thumb') {
html = cardBuilder.getCardsHtml({ html = cardBuilder.getCardsHtml({
@ -96,38 +96,37 @@ import loading from 'loading';
autoFocuser.autoFocus(context); autoFocuser.autoFocus(context);
}); });
}); });
} };
function fullyReload() { function fullyReload() {
self.preRender(); this.preRender();
self.renderTab(); this.renderTab();
} }
const self = this;
const data = {}; const data = {};
self.getViewStyles = function () { this.getViewStyles = function () {
return 'Poster,PosterCard,Thumb,ThumbCard'.split(','); return 'Poster,PosterCard,Thumb,ThumbCard'.split(',');
}; };
self.getCurrentViewStyle = function () { this.getCurrentViewStyle = function () {
return getPageData().view; return getPageData().view;
}; };
self.setCurrentViewStyle = function (viewStyle) { this.setCurrentViewStyle = function (viewStyle) {
getPageData().view = viewStyle; getPageData().view = viewStyle;
libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle); libraryBrowser.saveViewSetting(getSavedQueryKey(), viewStyle);
fullyReload(); fullyReload();
}; };
self.enableViewSelection = true; this.enableViewSelection = true;
let promise; let promise;
self.preRender = function () { this.preRender = function () {
promise = getPromise(); promise = getPromise();
}; };
self.renderTab = function () { this.renderTab = function () {
reloadItems(tabContent, promise); reloadItems(tabContent, promise);
}; };
} }

View file

@ -69,20 +69,19 @@ import loading from 'loading';
}); });
} }
const self = this;
const data = {}; const data = {};
self.getCurrentViewStyle = function () { this.getCurrentViewStyle = function () {
return getPageData().view; return getPageData().view;
}; };
let promise; let promise;
self.preRender = function () { this.preRender = function () {
promise = getPromise(); promise = getPromise();
}; };
self.renderTab = function () { this.renderTab = function () {
reloadItems(tabContent, promise); reloadItems(tabContent, promise);
}; };
} }

View file

@ -181,7 +181,7 @@ import 'flexStyles';
}, { }, {
name: globalize.translate('Albums') name: globalize.translate('Albums')
}, { }, {
name: globalize.translate('TabAlbumArtists') name: globalize.translate('HeaderAlbumArtists')
}, { }, {
name: globalize.translate('Artists') name: globalize.translate('Artists')
}, { }, {
@ -263,7 +263,7 @@ import 'flexStyles';
mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange); mainTabsManager.setTabs(view, currentTabIndex, getTabs, getTabContainers, onBeforeTabChange, onTabChange);
} }
function getTabController(page, index, callback) { const getTabController = (page, index, callback) => {
let depends; let depends;
switch (index) { switch (index) {
@ -298,7 +298,7 @@ import 'flexStyles';
if (index == 0) { if (index == 0) {
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
self.tabContent = tabContent; this.tabContent = tabContent;
} }
let controller = tabControllers[index]; let controller = tabControllers[index];
@ -307,7 +307,7 @@ import 'flexStyles';
tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']"); tabContent = view.querySelector(".pageTabContent[data-index='" + index + "']");
if (index === 0) { if (index === 0) {
controller = self; controller = this;
} else if (index === 7) { } else if (index === 7) {
controller = new controllerFactory(view, tabContent, { controller = new controllerFactory(view, tabContent, {
collectionType: 'music', collectionType: 'music',
@ -331,7 +331,7 @@ import 'flexStyles';
callback(controller); callback(controller);
}); });
} };
function preLoadTab(page, index) { function preLoadTab(page, index) {
getTabController(page, index, function (controller) { getTabController(page, index, function (controller) {
@ -359,10 +359,9 @@ import 'flexStyles';
} }
} }
var self = this; let currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId));
var currentTabIndex = parseInt(params.tab || getDefaultTabIndex(params.topParentId));
self.initTab = function () { this.initTab = function () {
const tabContent = view.querySelector(".pageTabContent[data-index='0']"); const tabContent = view.querySelector(".pageTabContent[data-index='0']");
const containers = tabContent.querySelectorAll('.itemsContainer'); const containers = tabContent.querySelectorAll('.itemsContainer');
@ -371,7 +370,7 @@ import 'flexStyles';
} }
}; };
self.renderTab = function () { this.renderTab = function () {
reload(); reload();
}; };

View file

@ -71,7 +71,7 @@
<span class="material-icons audiotrack"></span> <span class="material-icons audiotrack"></span>
</button> </button>
<button is="paper-icon-button-light" class="btnSubtitles videoButton btnPlayStateCommand autoSize" title="${ButtonSubtitles}" data-command="GoToSearch"> <button is="paper-icon-button-light" class="btnSubtitles videoButton btnPlayStateCommand autoSize" title="${Subtitles}" data-command="GoToSearch">
<span class="material-icons closed_caption"></span> <span class="material-icons closed_caption"></span>
</button> </button>
@ -129,7 +129,7 @@
</div> </div>
<br /> <br />
<div> <div>
<button is="paper-icon-button-light" class="btnGoHome btnCommand autoSize" title="${ButtonHome}" data-command="GoHome"> <button is="paper-icon-button-light" class="btnGoHome btnCommand autoSize" title="${Home}" data-command="GoHome">
<span class="material-icons home"></span> <span class="material-icons home"></span>
</button> </button>
<button is="paper-icon-button-light" class="btnShowSearch btnCommand autoSize" title="${Search}" data-command="GoToSearch"> <button is="paper-icon-button-light" class="btnShowSearch btnCommand autoSize" title="${Search}" data-command="GoToSearch">

View file

@ -767,7 +767,7 @@ import 'css!assets/css/videoosd';
if (isPaused) { if (isPaused) {
btnPlayPauseIcon.classList.add('play_arrow'); btnPlayPauseIcon.classList.add('play_arrow');
btnPlayPause.setAttribute('title', globalize.translate('ButtonPlay') + ' (k)'); btnPlayPause.setAttribute('title', globalize.translate('Play') + ' (k)');
} else { } else {
btnPlayPauseIcon.classList.add('pause'); btnPlayPauseIcon.classList.add('pause');
btnPlayPause.setAttribute('title', globalize.translate('ButtonPause') + ' (k)'); btnPlayPause.setAttribute('title', globalize.translate('ButtonPause') + ' (k)');
@ -1243,6 +1243,12 @@ import 'css!assets/css/videoosd';
} }
break; break;
} }
case '>':
playbackManager.increasePlaybackRate(currentPlayer);
break;
case '<':
playbackManager.decreasePlaybackRate(currentPlayer);
break;
} }
} }

View file

@ -2,7 +2,7 @@
<div class="padded-left padded-right padded-bottom-page"> <div class="padded-left padded-right padded-bottom-page">
<form class="forgotPasswordForm" style="text-align: center; margin: 0 auto;"> <form class="forgotPasswordForm" style="text-align: center; margin: 0 auto;">
<div style="text-align: left;"> <div style="text-align: left;">
<h1>${HeaderForgotPassword}</h1> <h1>${ButtonForgotPassword}</h1>
<div class="inputContainer"> <div class="inputContainer">
<input is="emby-input" type="text" id="txtName" label="${LabelUser}" autocomplete="off"/> <input is="emby-input" type="text" id="txtName" label="${LabelUser}" autocomplete="off"/>

View file

@ -6,14 +6,14 @@ import globalize from 'globalize';
if (result.Action == 'ContactAdmin') { if (result.Action == 'ContactAdmin') {
return void Dashboard.alert({ return void Dashboard.alert({
message: globalize.translate('MessageContactAdminToResetPassword'), message: globalize.translate('MessageContactAdminToResetPassword'),
title: globalize.translate('HeaderForgotPassword') title: globalize.translate('ButtonForgotPassword')
}); });
} }
if (result.Action == 'InNetworkRequired') { if (result.Action == 'InNetworkRequired') {
return void Dashboard.alert({ return void Dashboard.alert({
message: globalize.translate('MessageForgotPasswordInNetworkRequired'), message: globalize.translate('MessageForgotPasswordInNetworkRequired'),
title: globalize.translate('HeaderForgotPassword') title: globalize.translate('ButtonForgotPassword')
}); });
} }
@ -27,7 +27,7 @@ import globalize from 'globalize';
msg += '<br/>'; msg += '<br/>';
return void Dashboard.alert({ return void Dashboard.alert({
message: msg, message: msg,
title: globalize.translate('HeaderForgotPassword'), title: globalize.translate('ButtonForgotPassword'),
callback: function () { callback: function () {
Dashboard.navigate('forgotpasswordpin.html'); Dashboard.navigate('forgotpasswordpin.html');
} }

View file

@ -115,11 +115,11 @@ import 'emby-checkbox';
tag: user.PrimaryImageTag, tag: user.PrimaryImageTag,
type: 'Primary' type: 'Primary'
}); });
html += '<div class="cardImageContainer coveredImage coveredImage-noScale" style="background-image:url(\'' + imgUrl + "');\"></div>"; html += '<div class="cardImageContainer coveredImage" style="background-image:url(\'' + imgUrl + "');\"></div>";
} else { } else {
const background = getMetroColor(user.Id); const background = getMetroColor(user.Id);
imgUrl = 'assets/img/avatar.png'; imgUrl = 'assets/img/avatar.png';
html += '<div class="cardImageContainer coveredImage coveredImage-noScale" style="background-image:url(\'' + imgUrl + "');background-color:" + background + ';"></div>'; html += '<div class="cardImageContainer coveredImage" style="background-image:url(\'' + imgUrl + "');background-color:" + background + ';"></div>';
} }
html += '</div>'; html += '</div>';

View file

@ -5,7 +5,7 @@
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button> <button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button>
<button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button> <button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div is="emby-itemscontainer" class="itemsContainer padded-left padded-right"></div> <div is="emby-itemscontainer" class="itemsContainer padded-left padded-right"></div>
@ -61,7 +61,7 @@
<div class="paging"></div> <div class="paging"></div>
<button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button> <button is="paper-icon-button-light" class="btnSelectView autoSize" title="${ButtonSelectView}"><span class="material-icons view_comfy"></span></button>
<button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button> <button is="paper-icon-button-light" class="btnSort autoSize" title="${Sort}"><span class="material-icons sort_by_alpha"></span></button>
<button is="paper-icon-button-light" class="btnFilter autoSize" title="${ButtonFilter}"><span class="material-icons filter_list"></span></button> <button is="paper-icon-button-light" class="btnFilter autoSize" title="${Filter}"><span class="material-icons filter_list"></span></button>
</div> </div>
<div is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right"> <div is="emby-itemscontainer" class="itemsContainer vertical-wrap padded-left padded-right">
</div> </div>

View file

@ -29,7 +29,7 @@ import 'emby-button';
}, { }, {
name: globalize.translate('TabNetworks') name: globalize.translate('TabNetworks')
}, { }, {
name: globalize.translate('TabEpisodes') name: globalize.translate('Episodes')
}]; }];
} }

View file

@ -1,4 +1,4 @@
<div id="homeScreenPreferencesPage" data-role="page" class="page libraryPage userPreferencesPage noSecondaryNavPage" data-title="${HeaderHome}" data-backbutton="true"> <div id="homeScreenPreferencesPage" data-role="page" class="page libraryPage userPreferencesPage noSecondaryNavPage" data-title="${Home}" data-backbutton="true">
<div class="homeScreenSettingsContainer padded-left padded-right padded-bottom-page"> <div class="homeScreenSettingsContainer padded-left padded-right padded-bottom-page">
</div> </div>
</div> </div>

View file

@ -25,7 +25,7 @@
<div class="listItem"> <div class="listItem">
<span class="material-icons listItemIcon listItemIcon-transparent home"></span> <span class="material-icons listItemIcon listItemIcon-transparent home"></span>
<div class="listItemBody"> <div class="listItemBody">
<div class="listItemBodyText">${HeaderHome}</div> <div class="listItemBodyText">${Home}</div>
</div> </div>
</div> </div>
</a> </a>

View file

@ -12,7 +12,7 @@ import 'scrollStyles';
const buttonClass = 'emby-tab-button'; const buttonClass = 'emby-tab-button';
const activeButtonClass = buttonClass + '-active'; const activeButtonClass = buttonClass + '-active';
function setActiveTabButton(tabs, newButton, oldButton, animate) { function setActiveTabButton(newButton) {
newButton.classList.add(activeButtonClass); newButton.classList.add(activeButtonClass);
} }
@ -77,7 +77,7 @@ import 'scrollStyles';
const previousIndex = current ? parseInt(current.getAttribute('data-index')) : null; const previousIndex = current ? parseInt(current.getAttribute('data-index')) : null;
setActiveTabButton(tabs, tabButton, current, true); setActiveTabButton(tabButton);
const index = parseInt(tabButton.getAttribute('data-index')); const index = parseInt(tabButton.getAttribute('data-index'));
@ -101,6 +101,15 @@ import 'scrollStyles';
} }
} }
function onFocusOut(e) {
const parentContainer = e.target.parentNode;
const previousFocus = parentContainer.querySelector('.lastFocused');
if (previousFocus) {
previousFocus.classList.remove('lastFocused');
}
e.target.classList.add('lastFocused');
}
function initScroller(tabs) { function initScroller(tabs) {
if (tabs.scroller) { if (tabs.scroller) {
return; return;
@ -146,13 +155,18 @@ import 'scrollStyles';
dom.addEventListener(this, 'click', onClick, { dom.addEventListener(this, 'click', onClick, {
passive: true passive: true
}); });
dom.addEventListener(this, 'focusout', onFocusOut);
}; };
EmbyTabs.focus = function () { EmbyTabs.focus = function onFocusIn() {
const selected = this.querySelector('.' + activeButtonClass); const selectedTab = this.querySelector('.' + activeButtonClass);
const lastFocused = this.querySelector('.lastFocused');
if (selected) { if (lastFocused) {
focusManager.focus(selected); focusManager.focus(lastFocused);
} else if (selectedTab) {
focusManager.focus(selectedTab);
} else { } else {
focusManager.autoFocus(this); focusManager.autoFocus(this);
} }
@ -178,7 +192,7 @@ import 'scrollStyles';
const newTabButton = tabButtons[currentIndex]; const newTabButton = tabButtons[currentIndex];
if (newTabButton) { if (newTabButton) {
setActiveTabButton(this, newTabButton, current, false); setActiveTabButton(newTabButton);
} }
} }
@ -226,7 +240,7 @@ import 'scrollStyles';
})); }));
const currentTabButton = tabButtons[current]; const currentTabButton = tabButtons[current];
setActiveTabButton(tabs, tabButtons[selected], currentTabButton, false); setActiveTabButton(tabButtons[selected]);
if (current !== selected && currentTabButton) { if (current !== selected && currentTabButton) {
currentTabButton.classList.remove(activeButtonClass); currentTabButton.classList.remove(activeButtonClass);

View file

@ -1,4 +1,3 @@
// TODO: Move to external library (https://github.com/calvellido/focus-options-polyfill)
// Polyfill to add support for preventScroll by focus function // Polyfill to add support for preventScroll by focus function
if (HTMLElement.prototype.nativeFocus === undefined) { if (HTMLElement.prototype.nativeFocus === undefined) {

View file

@ -1,229 +1,229 @@
define(['events'], function (events) { import events from 'events';
'use strict';
// LinkParser // LinkParser
//
// https://github.com/ravisorg/LinkParser
//
// Locate and extract almost any URL within a string. Handles protocol-less domains, IPv4 and
// IPv6, unrecognised TLDs, and more.
//
// This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
// http://creativecommons.org/licenses/by-sa/4.0/
(function () {
// Original URL regex from the Android android.text.util.Linkify function, found here:
// http://stackoverflow.com/a/19696443
// //
// https://github.com/ravisorg/LinkParser // However there were problems with it, most probably related to the fact it was
// written in 2007, and it's been highly modified.
// //
// Locate and extract almost any URL within a string. Handles protocol-less domains, IPv4 and // 1) I didn't like the fact that it was tied to specific TLDs, since new ones
// IPv6, unrecognised TLDs, and more. // are being added all the time it wouldn't be reasonable to expect developer to
// be continually updating their regular expressions.
// //
// This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. // 2) It didn't allow unicode characters in the domains which are now allowed in
// http://creativecommons.org/licenses/by-sa/4.0/ // many languages, (including some IDN TLDs). Again these are constantly being
(function () { // added to and it doesn't seem reasonable to hard-code them. Note this ended up
// Original URL regex from the Android android.text.util.Linkify function, found here: // not being possible in standard JS due to the way it handles multibyte strings.
// http://stackoverflow.com/a/19696443 // It is possible using XRegExp, however a big performance hit results. Disabled
// // for now.
// However there were problems with it, most probably related to the fact it was //
// written in 2007, and it's been highly modified. // 3) It didn't allow for IPv6 hostnames
// // IPv6 regex from http://stackoverflow.com/a/17871737
// 1) I didn't like the fact that it was tied to specific TLDs, since new ones //
// are being added all the time it wouldn't be reasonable to expect developer to // 4) It was very poorly commented
// be continually updating their regular expressions. //
// // 5) It wasn't as smart as it could have been about what should be part of a
// 2) It didn't allow unicode characters in the domains which are now allowed in // URL and what should be part of human language.
// many languages, (including some IDN TLDs). Again these are constantly being
// added to and it doesn't seem reasonable to hard-code them. Note this ended up
// not being possible in standard JS due to the way it handles multibyte strings.
// It is possible using XRegExp, however a big performance hit results. Disabled
// for now.
//
// 3) It didn't allow for IPv6 hostnames
// IPv6 regex from http://stackoverflow.com/a/17871737
//
// 4) It was very poorly commented
//
// 5) It wasn't as smart as it could have been about what should be part of a
// URL and what should be part of human language.
var protocols = '(?:(?:http|https|rtsp|ftp):\\/\\/)'; const protocols = '(?:(?:http|https|rtsp|ftp):\\/\\/)';
var credentials = "(?:(?:[a-z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-f0-9]{2})){1,64}" // username (1-64 normal or url escaped characters) const credentials = "(?:(?:[a-z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-f0-9]{2})){1,64}" // username (1-64 normal or url escaped characters)
+ "(?:\\:(?:[a-z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-f0-9]{2})){1,25})?" // followed by optional password (: + 1-25 normal or url escaped characters) + "(?:\\:(?:[a-z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-f0-9]{2})){1,25})?" // followed by optional password (: + 1-25 normal or url escaped characters)
+ '\\@)'; + '\\@)';
// IPv6 Regex http://forums.intermapper.com/viewtopic.php?t=452 // IPv6 Regex http://forums.intermapper.com/viewtopic.php?t=452
// by Dartware, LLC is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License // by Dartware, LLC is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License
// http://intermapper.com/ // http://intermapper.com/
var ipv6 = '(' const ipv6 = '('
+ '(([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))' + '(([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))'
+ '|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))' + '|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))'
+ '|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))' + '|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))'
+ '|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))' + '|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))'
+ '|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))' + '|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))'
+ '|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))' + '|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))'
+ '|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))' + '|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))'
+ '|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))' + '|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))'
+ ')(%.+)?'; + ')(%.+)?';
var ipv4 = '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.' const ipv4 = '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.'
+ '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.' + '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.'
+ '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.' + '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.'
+ '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])'; + '(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])';
// This would have been a lot cleaner if JS RegExp supported conditionals... // This would have been a lot cleaner if JS RegExp supported conditionals...
var linkRegExpString = const linkRegExpString =
// begin match for protocol / username / password / host // begin match for protocol / username / password / host
'(?:' '(?:'
// ============================ // ============================
// If we have a recognized protocol at the beginning of the URL, we're // If we have a recognized protocol at the beginning of the URL, we're
// more relaxed about what we accept, because we assume the user wants // more relaxed about what we accept, because we assume the user wants
// this to be a URL, and we're not accidentally matching human language // this to be a URL, and we're not accidentally matching human language
+ protocols + '?' + protocols + '?'
// optional username:password@ // optional username:password@
+ credentials + '?' + credentials + '?'
// IP address (both v4 and v6) // IP address (both v4 and v6)
+ '(?:' + '(?:'
// IPv6 // IPv6
+ ipv6 + ipv6
// IPv4 // IPv4
+ '|' + ipv4 + '|' + ipv4
+ ')' + ')'
// end match for protocol / username / password / host // end match for protocol / username / password / host
+ ')' + ')'
// optional port number // optional port number
+ '(?:\\:\\d{1,5})?' + '(?:\\:\\d{1,5})?'
// plus optional path and query params (no unicode allowed here?) // plus optional path and query params (no unicode allowed here?)
+ '(?:' + '(?:'
+ '\\/(?:' + '\\/(?:'
// some characters we'll accept because it's unlikely human language // some characters we'll accept because it's unlikely human language
// would use them after a URL unless they were part of the url // would use them after a URL unless they were part of the url
+ '(?:[a-z0-9\\/\\@\\&\\#\\~\\*\\_\\-\\+])' + '(?:[a-z0-9\\/\\@\\&\\#\\~\\*\\_\\-\\+])'
+ '|(?:\\%[a-f0-9]{2})' + '|(?:\\%[a-f0-9]{2})'
// some characters are much more likely to be used AFTER a url and // some characters are much more likely to be used AFTER a url and
// were not intended to be included in the url itself. Mostly end // were not intended to be included in the url itself. Mostly end
// of sentence type things. It's also likely that the URL would // of sentence type things. It's also likely that the URL would
// still work if any of these characters were missing from the end // still work if any of these characters were missing from the end
// because we parsed it incorrectly. For these characters to be accepted // because we parsed it incorrectly. For these characters to be accepted
// they must be followed by another character that we're reasonably // they must be followed by another character that we're reasonably
// sure is part of the url // sure is part of the url
+ "|(?:[\\;\\?\\:\\.\\!\\'\\(\\)\\,\\=]+(?=(?:[a-z0-9\\/\\@\\&\\#\\~\\*\\_\\-\\+])|(?:\\%[a-f0-9]{2})))" + "|(?:[\\;\\?\\:\\.\\!\\'\\(\\)\\,\\=]+(?=(?:[a-z0-9\\/\\@\\&\\#\\~\\*\\_\\-\\+])|(?:\\%[a-f0-9]{2})))"
+ ')*' + ')*'
+ '|\\b|\$' + '|\\b|\$'
+ ')'; + ')';
// regex = XRegExp(regex,'gi'); // regex = XRegExp(regex,'gi');
var linkRegExp = RegExp(linkRegExpString, 'gi'); const linkRegExp = RegExp(linkRegExpString, 'gi');
var protocolRegExp = RegExp('^' + protocols, 'i'); const protocolRegExp = RegExp('^' + protocols, 'i');
// if url doesn't begin with a known protocol, add http by default // if url doesn't begin with a known protocol, add http by default
function ensureProtocol(url) { function ensureProtocol(url) {
if (!url.match(protocolRegExp)) { if (!url.match(protocolRegExp)) {
url = 'http://' + url; url = 'http://' + url;
}
return url;
} }
return url;
}
// look for links in the text // look for links in the text
var LinkParser = { const LinkParser = {
parse: function (text) { parse: function (text) {
var links = []; const links = [];
var match; let match;
// eslint-disable-next-line no-cond-assign // eslint-disable-next-line no-cond-assign
while (match = linkRegExp.exec(text)) { while (match = linkRegExp.exec(text)) {
console.debug(match); console.debug(match);
var txt = match[0]; const txt = match[0];
var pos = match.index; const pos = match.index;
var len = txt.length; const len = txt.length;
var url = ensureProtocol(text); const url = ensureProtocol(text);
links.push({ 'pos': pos, 'text': txt, 'len': len, 'url': url }); links.push({ 'pos': pos, 'text': txt, 'len': len, 'url': url });
}
return links;
} }
}; return links;
window.LinkParser = LinkParser;
})();
var cache = {};
function isValidIpAddress(address) {
var links = LinkParser.parse(address);
return links.length == 1;
}
function isLocalIpAddress(address) {
address = address.toLowerCase();
if (address.indexOf('127.0.0.1') !== -1) {
return true;
}
if (address.indexOf('localhost') !== -1) {
return true;
} }
return false;
}
function getServerAddress(apiClient) {
var serverAddress = apiClient.serverAddress();
if (isValidIpAddress(serverAddress) && !isLocalIpAddress(serverAddress)) {
return Promise.resolve(serverAddress);
}
var cachedValue = getCachedValue(serverAddress);
if (cachedValue) {
return Promise.resolve(cachedValue);
}
return apiClient.getEndpointInfo().then(function (endpoint) {
if (endpoint.IsInNetwork) {
return apiClient.getPublicSystemInfo().then(function (info) {
var localAddress = info.LocalAddress;
if (!localAddress) {
console.debug('No valid local address returned, defaulting to external one');
localAddress = serverAddress;
}
addToCache(serverAddress, localAddress);
return localAddress;
});
} else {
addToCache(serverAddress, serverAddress);
return serverAddress;
}
});
}
function clearCache() {
cache = {};
}
function addToCache(key, value) {
cache[key] = {
value: value,
time: new Date().getTime()
};
}
function getCachedValue(key) {
var obj = cache[key];
if (obj && (new Date().getTime() - obj.time) < 180000) {
return obj.value;
}
return null;
}
events.on(ConnectionManager, 'localusersignedin', clearCache);
events.on(ConnectionManager, 'localusersignedout', clearCache);
return {
getServerAddress: getServerAddress
}; };
});
window.LinkParser = LinkParser;
})();
let cache = {};
// TODO: Replace with isIP (https://www.npmjs.com/package/is-ip)
function isValidIpAddress(address) {
const links = LinkParser.parse(address);
return links.length == 1;
}
// TODO: Add IPv6 support. Potentially replace with isLocalhost (https://www.npmjs.com/package/is-localhost-ip)
function isLocalIpAddress(address) {
address = address.toLowerCase();
if (address.includes('127.0.0.1')) {
return true;
}
if (address.includes('localhost')) {
return true;
}
return false;
}
export function getServerAddress(apiClient) {
const serverAddress = apiClient.serverAddress();
if (isValidIpAddress(serverAddress) && !isLocalIpAddress(serverAddress)) {
return Promise.resolve(serverAddress);
}
const cachedValue = getCachedValue(serverAddress);
if (cachedValue) {
return Promise.resolve(cachedValue);
}
return apiClient.getEndpointInfo().then(function (endpoint) {
if (endpoint.IsInNetwork) {
return apiClient.getPublicSystemInfo().then(function (info) {
let localAddress = info.LocalAddress;
if (!localAddress) {
console.debug('No valid local address returned, defaulting to external one');
localAddress = serverAddress;
}
addToCache(serverAddress, localAddress);
return localAddress;
});
} else {
addToCache(serverAddress, serverAddress);
return serverAddress;
}
});
}
function clearCache() {
cache = {};
}
function addToCache(key, value) {
cache[key] = {
value: value,
time: new Date().getTime()
};
}
function getCachedValue(key) {
const obj = cache[key];
if (obj && (new Date().getTime() - obj.time) < 180000) {
return obj.value;
}
return null;
}
events.on(ConnectionManager, 'localusersignedin', clearCache);
events.on(ConnectionManager, 'localusersignedout', clearCache);
export default {
getServerAddress: getServerAddress
};

View file

@ -1,61 +1,61 @@
define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function (connectionManager, globalize, userSettings, appHost) { import globalize from 'globalize';
'use strict'; import * as userSettings from 'userSettings';
import appHost from 'apphost';
appHost = appHost.default || appHost; // TODO: Replace with date-fns
// https://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
function getWeek(date) {
const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
const dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
}
// TODO: Replace with date-fns function showMessage(text, userSettingsKey, appHostFeature) {
// https://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php if (appHost.supports(appHostFeature)) {
function getWeek(date) { return Promise.resolve();
var d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
var dayNum = d.getUTCDay() || 7;
d.setUTCDate(d.getUTCDate() + 4 - dayNum);
var yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
return Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
} }
function showMessage(text, userSettingsKey, appHostFeature) { const now = new Date();
if (appHost.supports(appHostFeature)) {
return Promise.resolve();
}
var now = new Date(); // TODO: Use date-fns
userSettingsKey += now.getFullYear() + '-w' + getWeek(now);
// TODO: Use date-fns if (userSettings.get(userSettingsKey, false) === '1') {
userSettingsKey += now.getFullYear() + '-w' + getWeek(now); return Promise.resolve();
}
if (userSettings.get(userSettingsKey, false) === '1') { return new Promise(function (resolve, reject) {
return Promise.resolve(); userSettings.set(userSettingsKey, '1', false);
}
return new Promise(function (resolve, reject) { import('alert').then(({default: alert}) => {
userSettings.set(userSettingsKey, '1', false); return alert(text).then(resolve, resolve);
require(['alert'], function (alert) {
return alert(text).then(resolve, resolve);
});
}); });
} });
}
function showBlurayMessage() { function showBlurayMessage() {
return showMessage(globalize.translate('UnsupportedPlayback'), 'blurayexpirementalinfo', 'nativeblurayplayback'); return showMessage(globalize.translate('UnsupportedPlayback'), 'blurayexpirementalinfo', 'nativeblurayplayback');
} }
function showDvdMessage() { function showDvdMessage() {
return showMessage(globalize.translate('UnsupportedPlayback'), 'dvdexpirementalinfo', 'nativedvdplayback'); return showMessage(globalize.translate('UnsupportedPlayback'), 'dvdexpirementalinfo', 'nativedvdplayback');
} }
function showIsoMessage() { function showIsoMessage() {
return showMessage(globalize.translate('UnsupportedPlayback'), 'isoexpirementalinfo', 'nativeisoplayback'); return showMessage(globalize.translate('UnsupportedPlayback'), 'isoexpirementalinfo', 'nativeisoplayback');
} }
function ExpirementalPlaybackWarnings() { class ExpirementalPlaybackWarnings {
constructor() {
this.name = 'Experimental playback warnings'; this.name = 'Experimental playback warnings';
this.type = 'preplayintercept'; this.type = 'preplayintercept';
this.id = 'expirementalplaybackwarnings'; this.id = 'expirementalplaybackwarnings';
} }
ExpirementalPlaybackWarnings.prototype.intercept = function (options) { intercept(options) {
var item = options.item; const item = options.item;
if (!item) { if (!item) {
return Promise.resolve(); return Promise.resolve();
} }
@ -73,7 +73,7 @@ define(['connectionManager', 'globalize', 'userSettings', 'apphost'], function (
} }
return Promise.resolve(); return Promise.resolve();
}; }
}
return ExpirementalPlaybackWarnings; export default ExpirementalPlaybackWarnings;
});

View file

@ -150,7 +150,7 @@ function tryRemoveElement(elem) {
/** /**
* @type {string} * @type {string}
*/ */
name name;
/** /**
* @type {string} * @type {string}
*/ */
@ -730,7 +730,7 @@ function tryRemoveElement(elem) {
const elem = e.target; const elem = e.target;
this.destroyCustomTrack(elem); this.destroyCustomTrack(elem);
onEndedInternal(this, elem, this.onError); onEndedInternal(this, elem, this.onError);
} };
/** /**
* @private * @private
@ -760,7 +760,7 @@ function tryRemoveElement(elem) {
} }
events.trigger(this, 'timeupdate'); events.trigger(this, 'timeupdate');
} };
/** /**
* @private * @private
@ -773,7 +773,7 @@ function tryRemoveElement(elem) {
const elem = e.target; const elem = e.target;
saveVolume(elem.volume); saveVolume(elem.volume);
events.trigger(this, 'volumechange'); events.trigger(this, 'volumechange');
} };
/** /**
* @private * @private
@ -785,7 +785,7 @@ function tryRemoveElement(elem) {
this.onStartedAndNavigatedToOsd(); this.onStartedAndNavigatedToOsd();
} }
} };
/** /**
* @private * @private
@ -832,14 +832,14 @@ function tryRemoveElement(elem) {
} }
} }
events.trigger(this, 'playing'); events.trigger(this, 'playing');
} };
/** /**
* @private * @private
*/ */
onPlay = () => { onPlay = () => {
events.trigger(this, 'unpause'); events.trigger(this, 'unpause');
} };
/** /**
* @private * @private
@ -865,21 +865,21 @@ function tryRemoveElement(elem) {
*/ */
onClick = () => { onClick = () => {
events.trigger(this, 'click'); events.trigger(this, 'click');
} };
/** /**
* @private * @private
*/ */
onDblClick = () => { onDblClick = () => {
events.trigger(this, 'dblclick'); events.trigger(this, 'dblclick');
} };
/** /**
* @private * @private
*/ */
onPause = () => { onPause = () => {
events.trigger(this, 'pause'); events.trigger(this, 'pause');
} };
onWaiting() { onWaiting() {
events.trigger(this, 'waiting'); events.trigger(this, 'waiting');
@ -929,7 +929,7 @@ function tryRemoveElement(elem) {
} }
onErrorInternal(this, type); onErrorInternal(this, type);
} };
/** /**
* @private * @private
@ -1634,6 +1634,31 @@ function tryRemoveElement(elem) {
return null; return null;
} }
getSupportedPlaybackRates() {
return [{
name: '0.5x',
id: 0.5
}, {
name: '0.75x',
id: 0.75
}, {
name: '1x',
id: 1.0
}, {
name: '1.25x',
id: 1.25
}, {
name: '1.5x',
id: 1.5
}, {
name: '1.75x',
id: 1.75
}, {
name: '2x',
id: 2.0
}];
}
setVolume(val) { setVolume(val) {
const mediaElement = this.#mediaElement; const mediaElement = this.#mediaElement;
if (mediaElement) { if (mediaElement) {

View file

@ -1,132 +1,123 @@
define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'], function (playbackManager, events, serverNotifications, connectionManager) { import playbackManager from 'playbackManager';
'use strict'; import events from 'events';
import serverNotifications from 'serverNotifications';
import connectionManager from 'connectionManager';
serverNotifications = serverNotifications.default || serverNotifications; function getActivePlayerId() {
playbackManager = playbackManager.default || playbackManager; const info = playbackManager.getPlayerInfo();
return info ? info.id : null;
}
function getActivePlayerId() { function sendPlayCommand(apiClient, options, playType) {
var info = playbackManager.getPlayerInfo(); const sessionId = getActivePlayerId();
return info ? info.id : null;
const ids = options.ids || options.items.map(function (i) {
return i.Id;
});
const remoteOptions = {
ItemIds: ids.join(','),
PlayCommand: playType
};
if (options.startPositionTicks) {
remoteOptions.StartPositionTicks = options.startPositionTicks;
} }
function sendPlayCommand(apiClient, options, playType) { if (options.mediaSourceId) {
var sessionId = getActivePlayerId(); remoteOptions.MediaSourceId = options.mediaSourceId;
var ids = options.ids || options.items.map(function (i) {
return i.Id;
});
var remoteOptions = {
ItemIds: ids.join(','),
PlayCommand: playType
};
if (options.startPositionTicks) {
remoteOptions.StartPositionTicks = options.startPositionTicks;
}
if (options.mediaSourceId) {
remoteOptions.MediaSourceId = options.mediaSourceId;
}
if (options.audioStreamIndex != null) {
remoteOptions.AudioStreamIndex = options.audioStreamIndex;
}
if (options.subtitleStreamIndex != null) {
remoteOptions.SubtitleStreamIndex = options.subtitleStreamIndex;
}
if (options.startIndex != null) {
remoteOptions.StartIndex = options.startIndex;
}
return apiClient.sendPlayCommand(sessionId, remoteOptions);
} }
function sendPlayStateCommand(apiClient, command, options) { if (options.audioStreamIndex != null) {
var sessionId = getActivePlayerId(); remoteOptions.AudioStreamIndex = options.audioStreamIndex;
apiClient.sendPlayStateCommand(sessionId, command, options);
} }
function getCurrentApiClient(instance) { if (options.subtitleStreamIndex != null) {
var currentServerId = instance.currentServerId; remoteOptions.SubtitleStreamIndex = options.subtitleStreamIndex;
if (currentServerId) {
return connectionManager.getApiClient(currentServerId);
}
return connectionManager.currentApiClient();
} }
function sendCommandByName(instance, name, options) { if (options.startIndex != null) {
var command = { remoteOptions.StartIndex = options.startIndex;
Name: name
};
if (options) {
command.Arguments = options;
}
instance.sendCommand(command);
} }
function unsubscribeFromPlayerUpdates(instance) { return apiClient.sendPlayCommand(sessionId, remoteOptions);
instance.isUpdating = true; }
var apiClient = getCurrentApiClient(instance); function sendPlayStateCommand(apiClient, command, options) {
apiClient.sendMessage('SessionsStop'); const sessionId = getActivePlayerId();
if (instance.pollInterval) {
clearInterval(instance.pollInterval); apiClient.sendPlayStateCommand(sessionId, command, options);
instance.pollInterval = null; }
}
function getCurrentApiClient(instance) {
const currentServerId = instance.currentServerId;
if (currentServerId) {
return connectionManager.getApiClient(currentServerId);
} }
function processUpdatedSessions(instance, sessions, apiClient) { return connectionManager.currentApiClient();
var serverId = apiClient.serverId(); }
sessions.map(function (s) { function sendCommandByName(instance, name, options) {
if (s.NowPlayingItem) { const command = {
s.NowPlayingItem.ServerId = serverId; Name: name
} };
});
var currentTargetId = getActivePlayerId(); if (options) {
command.Arguments = options;
var session = sessions.filter(function (s) {
return s.Id === currentTargetId;
})[0];
if (session) {
normalizeImages(session, apiClient);
var eventNames = getChangedEvents(instance.lastPlayerData, session);
instance.lastPlayerData = session;
for (var i = 0, length = eventNames.length; i < length; i++) {
events.trigger(instance, eventNames[i], [session]);
}
} else {
instance.lastPlayerData = session;
playbackManager.setDefaultPlayerActive();
}
} }
function getChangedEvents(state1, state2) { instance.sendCommand(command);
var names = []; }
if (!state1) { function unsubscribeFromPlayerUpdates(instance) {
names.push('statechange'); instance.isUpdating = true;
names.push('timeupdate');
names.push('pause');
return names; const apiClient = getCurrentApiClient(instance);
apiClient.sendMessage('SessionsStop');
if (instance.pollInterval) {
clearInterval(instance.pollInterval);
instance.pollInterval = null;
}
}
function processUpdatedSessions(instance, sessions, apiClient) {
const serverId = apiClient.serverId();
sessions.map(function (s) {
if (s.NowPlayingItem) {
s.NowPlayingItem.ServerId = serverId;
} }
});
// TODO: Trim these down to prevent the UI from over-refreshing const currentTargetId = getActivePlayerId();
const session = sessions.filter(function (s) {
return s.Id === currentTargetId;
})[0];
if (session) {
normalizeImages(session, apiClient);
const eventNames = getChangedEvents(instance.lastPlayerData, session);
instance.lastPlayerData = session;
for (let i = 0, length = eventNames.length; i < length; i++) {
events.trigger(instance, eventNames[i], [session]);
}
} else {
instance.lastPlayerData = session;
playbackManager.setDefaultPlayerActive();
}
}
function getChangedEvents(state1, state2) {
const names = [];
if (!state1) {
names.push('statechange'); names.push('statechange');
names.push('timeupdate'); names.push('timeupdate');
names.push('pause'); names.push('pause');
@ -134,53 +125,62 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
return names; return names;
} }
function onPollIntervalFired() { // TODO: Trim these down to prevent the UI from over-refreshing
var instance = this; names.push('statechange');
var apiClient = getCurrentApiClient(instance); names.push('timeupdate');
if (!apiClient.isMessageChannelOpen()) { names.push('pause');
apiClient.getSessions().then(function (sessions) {
processUpdatedSessions(instance, sessions, apiClient); return names;
}); }
}
function onPollIntervalFired() {
const instance = this;
const apiClient = getCurrentApiClient(instance);
if (!apiClient.isMessageChannelOpen()) {
apiClient.getSessions().then(function (sessions) {
processUpdatedSessions(instance, sessions, apiClient);
});
} }
}
function subscribeToPlayerUpdates(instance) { function subscribeToPlayerUpdates(instance) {
instance.isUpdating = true; instance.isUpdating = true;
var apiClient = getCurrentApiClient(instance); const apiClient = getCurrentApiClient(instance);
apiClient.sendMessage('SessionsStart', '100,800'); apiClient.sendMessage('SessionsStart', '100,800');
if (instance.pollInterval) { if (instance.pollInterval) {
clearInterval(instance.pollInterval); clearInterval(instance.pollInterval);
instance.pollInterval = null; instance.pollInterval = null;
}
instance.pollInterval = setInterval(onPollIntervalFired.bind(instance), 5000);
} }
instance.pollInterval = setInterval(onPollIntervalFired.bind(instance), 5000);
}
function normalizeImages(state, apiClient) { function normalizeImages(state, apiClient) {
if (state && state.NowPlayingItem) { if (state && state.NowPlayingItem) {
var item = state.NowPlayingItem; const item = state.NowPlayingItem;
if (!item.ImageTags || !item.ImageTags.Primary) { if (!item.ImageTags || !item.ImageTags.Primary) {
if (item.PrimaryImageTag) { if (item.PrimaryImageTag) {
item.ImageTags = item.ImageTags || {}; item.ImageTags = item.ImageTags || {};
item.ImageTags.Primary = item.PrimaryImageTag; item.ImageTags.Primary = item.PrimaryImageTag;
}
}
if (item.BackdropImageTag && item.BackdropItemId === item.Id) {
item.BackdropImageTags = [item.BackdropImageTag];
}
if (item.BackdropImageTag && item.BackdropItemId !== item.Id) {
item.ParentBackdropImageTags = [item.BackdropImageTag];
item.ParentBackdropItemId = item.BackdropItemId;
}
if (!item.ServerId) {
item.ServerId = apiClient.serverId();
} }
} }
if (item.BackdropImageTag && item.BackdropItemId === item.Id) {
item.BackdropImageTags = [item.BackdropImageTag];
}
if (item.BackdropImageTag && item.BackdropItemId !== item.Id) {
item.ParentBackdropImageTags = [item.BackdropImageTag];
item.ParentBackdropItemId = item.BackdropItemId;
}
if (!item.ServerId) {
item.ServerId = apiClient.serverId();
}
} }
}
function SessionPlayer() { class SessionPlayer {
var self = this; constructor() {
const self = this;
this.name = 'Remote Control'; this.name = 'Remote Control';
this.type = 'mediaplayer'; this.type = 'mediaplayer';
@ -192,7 +192,7 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
}); });
} }
SessionPlayer.prototype.beginPlayerUpdates = function () { beginPlayerUpdates() {
this.playerListenerCount = this.playerListenerCount || 0; this.playerListenerCount = this.playerListenerCount || 0;
if (this.playerListenerCount <= 0) { if (this.playerListenerCount <= 0) {
@ -202,9 +202,9 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
} }
this.playerListenerCount++; this.playerListenerCount++;
}; }
SessionPlayer.prototype.endPlayerUpdates = function () { endPlayerUpdates() {
this.playerListenerCount = this.playerListenerCount || 0; this.playerListenerCount = this.playerListenerCount || 0;
this.playerListenerCount--; this.playerListenerCount--;
@ -212,21 +212,21 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
unsubscribeFromPlayerUpdates(this); unsubscribeFromPlayerUpdates(this);
this.playerListenerCount = 0; this.playerListenerCount = 0;
} }
}; }
SessionPlayer.prototype.getPlayerState = function () { getPlayerState() {
return this.lastPlayerData || {}; return this.lastPlayerData || {};
}; }
SessionPlayer.prototype.getTargets = function () { getTargets() {
var apiClient = getCurrentApiClient(this); const apiClient = getCurrentApiClient(this);
var sessionQuery = { const sessionQuery = {
ControllableByUserId: apiClient.getCurrentUserId() ControllableByUserId: apiClient.getCurrentUserId()
}; };
if (apiClient) { if (apiClient) {
var name = this.name; const name = this.name;
return apiClient.getSessions(sessionQuery).then(function (sessions) { return apiClient.getSessions(sessionQuery).then(function (sessions) {
return sessions.filter(function (s) { return sessions.filter(function (s) {
@ -243,11 +243,9 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
isLocalPlayer: false, isLocalPlayer: false,
supportedCommands: s.Capabilities.SupportedCommands, supportedCommands: s.Capabilities.SupportedCommands,
user: s.UserId ? { user: s.UserId ? {
Id: s.UserId, Id: s.UserId,
Name: s.UserName, Name: s.UserName,
PrimaryImageTag: s.UserPrimaryImageTag PrimaryImageTag: s.UserPrimaryImageTag
} : null } : null
}; };
}); });
@ -255,16 +253,16 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
} else { } else {
return Promise.resolve([]); return Promise.resolve([]);
} }
}; }
SessionPlayer.prototype.sendCommand = function (command) { sendCommand(command) {
var sessionId = getActivePlayerId(); const sessionId = getActivePlayerId();
var apiClient = getCurrentApiClient(this); const apiClient = getCurrentApiClient(this);
apiClient.sendCommand(sessionId, command); apiClient.sendCommand(sessionId, command);
}; }
SessionPlayer.prototype.play = function (options) { play(options) {
options = Object.assign({}, options); options = Object.assign({}, options);
if (options.items) { if (options.items) {
@ -276,251 +274,233 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager']
} }
return sendPlayCommand(getCurrentApiClient(this), options, 'PlayNow'); return sendPlayCommand(getCurrentApiClient(this), options, 'PlayNow');
}; }
SessionPlayer.prototype.shuffle = function (item) { shuffle(item) {
sendPlayCommand(getCurrentApiClient(this), { ids: [item.Id] }, 'PlayShuffle'); sendPlayCommand(getCurrentApiClient(this), { ids: [item.Id] }, 'PlayShuffle');
}; }
SessionPlayer.prototype.instantMix = function (item) { instantMix(item) {
sendPlayCommand(getCurrentApiClient(this), { ids: [item.Id] }, 'PlayInstantMix'); sendPlayCommand(getCurrentApiClient(this), { ids: [item.Id] }, 'PlayInstantMix');
}; }
SessionPlayer.prototype.queue = function (options) { queue(options) {
sendPlayCommand(getCurrentApiClient(this), options, 'PlayNext'); sendPlayCommand(getCurrentApiClient(this), options, 'PlayNext');
}; }
SessionPlayer.prototype.queueNext = function (options) { queueNext(options) {
sendPlayCommand(getCurrentApiClient(this), options, 'PlayLast'); sendPlayCommand(getCurrentApiClient(this), options, 'PlayLast');
}; }
SessionPlayer.prototype.canPlayMediaType = function (mediaType) { canPlayMediaType(mediaType) {
mediaType = (mediaType || '').toLowerCase(); mediaType = (mediaType || '').toLowerCase();
return mediaType === 'audio' || mediaType === 'video'; return mediaType === 'audio' || mediaType === 'video';
}; }
SessionPlayer.prototype.canQueueMediaType = function (mediaType) { canQueueMediaType(mediaType) {
return this.canPlayMediaType(mediaType); return this.canPlayMediaType(mediaType);
}; }
SessionPlayer.prototype.stop = function () { stop() {
sendPlayStateCommand(getCurrentApiClient(this), 'stop'); sendPlayStateCommand(getCurrentApiClient(this), 'stop');
}; }
SessionPlayer.prototype.nextTrack = function () { nextTrack() {
sendPlayStateCommand(getCurrentApiClient(this), 'nextTrack'); sendPlayStateCommand(getCurrentApiClient(this), 'nextTrack');
}; }
SessionPlayer.prototype.previousTrack = function () { previousTrack() {
sendPlayStateCommand(getCurrentApiClient(this), 'previousTrack'); sendPlayStateCommand(getCurrentApiClient(this), 'previousTrack');
}; }
SessionPlayer.prototype.seek = function (positionTicks) { seek(positionTicks) {
sendPlayStateCommand(getCurrentApiClient(this), 'seek', sendPlayStateCommand(getCurrentApiClient(this), 'seek',
{ {
SeekPositionTicks: positionTicks SeekPositionTicks: positionTicks
}); });
}; }
SessionPlayer.prototype.currentTime = function (val) { currentTime(val) {
if (val != null) { if (val != null) {
return this.seek(val); return this.seek(val);
} }
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.PlayState || {}; state = state.PlayState || {};
return state.PositionTicks; return state.PositionTicks;
}; }
SessionPlayer.prototype.duration = function () { duration() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.NowPlayingItem || {}; state = state.NowPlayingItem || {};
return state.RunTimeTicks; return state.RunTimeTicks;
}; }
SessionPlayer.prototype.paused = function () { paused() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.PlayState || {}; state = state.PlayState || {};
return state.IsPaused; return state.IsPaused;
}; }
SessionPlayer.prototype.getVolume = function () { getVolume() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.PlayState || {}; state = state.PlayState || {};
return state.VolumeLevel; return state.VolumeLevel;
}; }
SessionPlayer.prototype.isMuted = function () { isMuted() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.PlayState || {}; state = state.PlayState || {};
return state.IsMuted; return state.IsMuted;
}; }
SessionPlayer.prototype.pause = function () { pause() {
sendPlayStateCommand(getCurrentApiClient(this), 'Pause'); sendPlayStateCommand(getCurrentApiClient(this), 'Pause');
}; }
SessionPlayer.prototype.unpause = function () { unpause() {
sendPlayStateCommand(getCurrentApiClient(this), 'Unpause'); sendPlayStateCommand(getCurrentApiClient(this), 'Unpause');
}; }
SessionPlayer.prototype.playPause = function () { playPause() {
sendPlayStateCommand(getCurrentApiClient(this), 'PlayPause'); sendPlayStateCommand(getCurrentApiClient(this), 'PlayPause');
}; }
SessionPlayer.prototype.setMute = function (isMuted) { setMute(isMuted) {
if (isMuted) { if (isMuted) {
sendCommandByName(this, 'Mute'); sendCommandByName(this, 'Mute');
} else { } else {
sendCommandByName(this, 'Unmute'); sendCommandByName(this, 'Unmute');
} }
}; }
SessionPlayer.prototype.toggleMute = function () { toggleMute() {
sendCommandByName(this, 'ToggleMute'); sendCommandByName(this, 'ToggleMute');
}; }
SessionPlayer.prototype.setVolume = function (vol) { setVolume(vol) {
sendCommandByName(this, 'SetVolume', { sendCommandByName(this, 'SetVolume', {
Volume: vol Volume: vol
}); });
}; }
SessionPlayer.prototype.volumeUp = function () { volumeUp() {
sendCommandByName(this, 'VolumeUp'); sendCommandByName(this, 'VolumeUp');
}; }
SessionPlayer.prototype.volumeDown = function () { volumeDown() {
sendCommandByName(this, 'VolumeDown'); sendCommandByName(this, 'VolumeDown');
}; }
SessionPlayer.prototype.toggleFullscreen = function () { toggleFullscreen() {
sendCommandByName(this, 'ToggleFullscreen'); sendCommandByName(this, 'ToggleFullscreen');
}; }
SessionPlayer.prototype.audioTracks = function () { audioTracks() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.NowPlayingItem || {}; state = state.NowPlayingItem || {};
var streams = state.MediaStreams || []; const streams = state.MediaStreams || [];
return streams.filter(function (s) { return streams.filter(function (s) {
return s.Type === 'Audio'; return s.Type === 'Audio';
}); });
}; }
SessionPlayer.prototype.getAudioStreamIndex = function () { getAudioStreamIndex() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.PlayState || {}; state = state.PlayState || {};
return state.AudioStreamIndex; return state.AudioStreamIndex;
}; }
SessionPlayer.prototype.playTrailers = function (item) { playTrailers(item) {
sendCommandByName(this, 'PlayTrailers', { sendCommandByName(this, 'PlayTrailers', {
ItemId: item.Id ItemId: item.Id
}); });
}; }
SessionPlayer.prototype.setAudioStreamIndex = function (index) { setAudioStreamIndex(index) {
sendCommandByName(this, 'SetAudioStreamIndex', { sendCommandByName(this, 'SetAudioStreamIndex', {
Index: index Index: index
}); });
}; }
SessionPlayer.prototype.subtitleTracks = function () { subtitleTracks() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.NowPlayingItem || {}; state = state.NowPlayingItem || {};
var streams = state.MediaStreams || []; const streams = state.MediaStreams || [];
return streams.filter(function (s) { return streams.filter(function (s) {
return s.Type === 'Subtitle'; return s.Type === 'Subtitle';
}); });
}; }
SessionPlayer.prototype.getSubtitleStreamIndex = function () { getSubtitleStreamIndex() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.PlayState || {}; state = state.PlayState || {};
return state.SubtitleStreamIndex; return state.SubtitleStreamIndex;
}; }
SessionPlayer.prototype.setSubtitleStreamIndex = function (index) { setSubtitleStreamIndex(index) {
sendCommandByName(this, 'SetSubtitleStreamIndex', { sendCommandByName(this, 'SetSubtitleStreamIndex', {
Index: index Index: index
}); });
}; }
SessionPlayer.prototype.getMaxStreamingBitrate = function () { setRepeatMode(mode) {
};
SessionPlayer.prototype.setMaxStreamingBitrate = function (options) {
};
SessionPlayer.prototype.isFullscreen = function () {
};
SessionPlayer.prototype.toggleFullscreen = function () {
};
SessionPlayer.prototype.getRepeatMode = function () {
};
SessionPlayer.prototype.setRepeatMode = function (mode) {
sendCommandByName(this, 'SetRepeatMode', { sendCommandByName(this, 'SetRepeatMode', {
RepeatMode: mode RepeatMode: mode
}); });
}; }
SessionPlayer.prototype.setQueueShuffleMode = function (mode) { getRepeatMode() {
}
setQueueShuffleMode(mode) {
sendCommandByName(this, 'SetShuffleQueue', { sendCommandByName(this, 'SetShuffleQueue', {
ShuffleMode: mode ShuffleMode: mode
}); });
}; }
SessionPlayer.prototype.getQueueShuffleMode = function () { getQueueShuffleMode() {
}
}; displayContent(options) {
SessionPlayer.prototype.displayContent = function (options) {
sendCommandByName(this, 'DisplayContent', options); sendCommandByName(this, 'DisplayContent', options);
}; }
SessionPlayer.prototype.isPlaying = function () { isPlaying() {
var state = this.lastPlayerData || {}; const state = this.lastPlayerData || {};
return state.NowPlayingItem != null; return state.NowPlayingItem != null;
}; }
SessionPlayer.prototype.isPlayingVideo = function () { isPlayingVideo() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.NowPlayingItem || {}; state = state.NowPlayingItem || {};
return state.MediaType === 'Video'; return state.MediaType === 'Video';
}; }
SessionPlayer.prototype.isPlayingAudio = function () { isPlayingAudio() {
var state = this.lastPlayerData || {}; let state = this.lastPlayerData || {};
state = state.NowPlayingItem || {}; state = state.NowPlayingItem || {};
return state.MediaType === 'Audio'; return state.MediaType === 'Audio';
}; }
SessionPlayer.prototype.getPlaylist = function () { getPlaylist() {
return Promise.resolve([]); return Promise.resolve([]);
}; }
SessionPlayer.prototype.getCurrentPlaylistItemId = function () { getCurrentPlaylistItemId() {
}; }
SessionPlayer.prototype.setCurrentPlaylistItem = function (playlistItemId) { setCurrentPlaylistItem(playlistItemId) {
return Promise.resolve(); return Promise.resolve();
}; }
SessionPlayer.prototype.removeFromPlaylist = function (playlistItemIds) { removeFromPlaylist(playlistItemIds) {
return Promise.resolve(); return Promise.resolve();
}; }
SessionPlayer.prototype.tryPair = function (target) { tryPair(target) {
return Promise.resolve(); return Promise.resolve();
}; }
}
return SessionPlayer; export default SessionPlayer;
});

View file

@ -5,8 +5,8 @@
} }
const script = document.createElement('script'); const script = document.createElement('script');
if (self.dashboardVersion) { if (window.dashboardVersion) {
src += `?v=${self.dashboardVersion}`; src += `?v=${window.dashboardVersion}`;
} }
script.src = src; script.src = src;
script.setAttribute('async', ''); script.setAttribute('async', '');
@ -35,10 +35,10 @@
// Promise() being missing on some legacy browser, and a funky one // Promise() being missing on some legacy browser, and a funky one
// is Promise() present but buggy on WebOS 2 // is Promise() present but buggy on WebOS 2
window.Promise = undefined; window.Promise = undefined;
self.Promise = undefined; window.Promise = undefined;
} }
if (!self.Promise) { if (!window.Promise) {
// Load Promise polyfill if they are not natively supported // Load Promise polyfill if they are not natively supported
injectScriptElement( injectScriptElement(
'./libraries/npo.js', './libraries/npo.js',

View file

@ -210,7 +210,7 @@ if (userAgent.toLowerCase().indexOf('xbox') !== -1) {
browser.tv = true; browser.tv = true;
} }
browser.animate = typeof document !== 'undefined' && document.documentElement.animate != null; browser.animate = typeof document !== 'undefined' && document.documentElement.animate != null;
browser.tizen = userAgent.toLowerCase().indexOf('tizen') !== -1 || self.tizen != null; browser.tizen = userAgent.toLowerCase().indexOf('tizen') !== -1 || window.tizen != null;
browser.web0s = userAgent.toLowerCase().indexOf('Web0S'.toLowerCase()) !== -1; browser.web0s = userAgent.toLowerCase().indexOf('Web0S'.toLowerCase()) !== -1;
browser.edgeUwp = browser.edge && (userAgent.toLowerCase().indexOf('msapphost') !== -1 || userAgent.toLowerCase().indexOf('webview') !== -1); browser.edgeUwp = browser.edge && (userAgent.toLowerCase().indexOf('msapphost') !== -1 || userAgent.toLowerCase().indexOf('webview') !== -1);

View file

@ -315,10 +315,12 @@ define(['browser'], function (browser) {
// Not sure how to test for this // Not sure how to test for this
var supportsMp2VideoAudio = browser.edgeUwp || browser.tizen || browser.web0s; var supportsMp2VideoAudio = browser.edgeUwp || browser.tizen || browser.web0s;
/* eslint-disable compat/compat */
var maxVideoWidth = browser.xboxOne ? var maxVideoWidth = browser.xboxOne ?
(self.screen ? self.screen.width : null) : (window.screen ? window.screen.width : null) :
null; null;
/* eslint-enable compat/compat */
if (options.maxVideoWidth) { if (options.maxVideoWidth) {
maxVideoWidth = options.maxVideoWidth; maxVideoWidth = options.maxVideoWidth;
} }

233
src/scripts/clientUtils.js Normal file
View file

@ -0,0 +1,233 @@
export function getCurrentUser() {
return window.ApiClient.getCurrentUser(false);
}
//TODO: investigate url prefix support for serverAddress function
export function serverAddress() {
if (AppInfo.isNativeApp) {
const apiClient = window.ApiClient;
if (apiClient) {
return apiClient.serverAddress();
}
return null;
}
const urlLower = window.location.href.toLowerCase();
const index = urlLower.lastIndexOf('/web');
if (index != -1) {
return urlLower.substring(0, index);
}
const loc = window.location;
let address = loc.protocol + '//' + loc.hostname;
if (loc.port) {
address += ':' + loc.port;
}
return address;
}
export function getCurrentUserId() {
const apiClient = window.ApiClient;
if (apiClient) {
return apiClient.getCurrentUserId();
}
return null;
}
export function onServerChanged(userId, accessToken, apiClient) {
apiClient = apiClient || window.ApiClient;
window.ApiClient = apiClient;
}
export function logout() {
ConnectionManager.logout().then(function () {
let loginPage;
if (AppInfo.isNativeApp) {
loginPage = 'selectserver.html';
window.ApiClient = null;
} else {
loginPage = 'login.html';
}
navigate(loginPage);
});
}
export function getConfigurationPageUrl(name) {
return 'configurationpage?name=' + encodeURIComponent(name);
}
export function getConfigurationResourceUrl(name) {
if (AppInfo.isNativeApp) {
return ApiClient.getUrl('web/ConfigurationPage', {
name: name
});
}
return getConfigurationPageUrl(name);
}
export function navigate(url, preserveQueryString) {
if (!url) {
throw new Error('url cannot be null or empty');
}
const queryString = getWindowLocationSearch();
if (preserveQueryString && queryString) {
url += queryString;
}
return new Promise(function (resolve, reject) {
import('appRouter').then(({default: appRouter}) => {
return appRouter.show(url).then(resolve, reject);
});
});
}
export function processPluginConfigurationUpdateResult() {
Promise.all([
import('loading'),
import('toast')
])
.then(([{default: loading}, {default: toast}]) => {
loading.hide();
toast(Globalize.translate('SettingsSaved'));
});
}
export function processServerConfigurationUpdateResult(result) {
Promise.all([
import('loading'),
import('toast')
])
.then(([{default: loading}, {default: toast}]) => {
loading.hide();
toast(Globalize.translate('SettingsSaved'));
});
}
export function processErrorResponse(response) {
import('loading').then(({default: loading}) => {
loading.hide();
});
let status = '' + response.status;
if (response.statusText) {
status = response.statusText;
}
alert({
title: status,
message: response.headers ? response.headers.get('X-Application-Error-Code') : null
});
}
export function alert(options) {
if (typeof options == 'string') {
return void import('toast').then(({default: toast}) => {
toast({
text: options
});
});
}
import('alert').then(({default: alert}) => {
alert({
title: options.title || Globalize.translate('HeaderAlert'),
text: options.message
}).then(options.callback || function () {});
});
}
export function capabilities(appHost) {
let capabilities = {
PlayableMediaTypes: ['Audio', 'Video'],
SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'SetShuffleQueue', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'],
SupportsPersistentIdentifier: window.appMode === 'cordova' || window.appMode === 'android',
SupportsMediaControl: true
};
return Object.assign(capabilities, appHost.getPushTokenInfo());
}
export function selectServer() {
if (window.NativeShell && typeof window.NativeShell.selectServer === 'function') {
window.NativeShell.selectServer();
} else {
navigate('selectserver.html');
}
}
export function hideLoadingMsg() {
import('loading').then(({default: loading}) => {
loading.hide();
});
}
export function showLoadingMsg() {
import('loading').then(({default: loading}) => {
loading.show();
});
}
export function confirm(message, title, callback) {
import('confirm').then(({default: confirm}) => {
confirm(message, title).then(function() {
callback(!0);
}).catch(function() {
callback(!1);
});
});
}
// This is used in plugins and templates, so keep it defined for now.
// TODO: Remove once plugins don't need it
window.Dashboard = {
alert,
capabilities,
confirm,
getConfigurationPageUrl,
getConfigurationResourceUrl,
getCurrentUser,
getCurrentUserId,
hideLoadingMsg,
logout,
navigate,
onServerChanged,
processErrorResponse,
processPluginConfigurationUpdateResult,
processServerConfigurationUpdateResult,
selectServer,
serverAddress,
showLoadingMsg
};
export default {
alert,
capabilities,
confirm,
getConfigurationPageUrl,
getConfigurationResourceUrl,
getCurrentUser,
getCurrentUserId,
hideLoadingMsg,
logout,
navigate,
onServerChanged,
processErrorResponse,
processPluginConfigurationUpdateResult,
processServerConfigurationUpdateResult,
selectServer,
serverAddress,
showLoadingMsg
};

View file

@ -302,7 +302,7 @@ import 'material-icons';
$(document).on('itemsaved', '.metadataEditorPage', function (e, item) { $(document).on('itemsaved', '.metadataEditorPage', function (e, item) {
updateEditorNode(this, item); updateEditorNode(this, item);
}).on('pagebeforeshow', '.metadataEditorPage', function () { }).on('pagebeforeshow', '.metadataEditorPage', function () {
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('css!assets/css/metadataeditor.css'); import('css!assets/css/metadataeditor.css');
}).on('pagebeforeshow', '.metadataEditorPage', function () { }).on('pagebeforeshow', '.metadataEditorPage', function () {
var page = this; var page = this;

View file

@ -19,386 +19,383 @@
// # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// # THE SOFTWARE. // # THE SOFTWARE.
require(['apphost'], function (appHost) {
'use strict';
appHost = appHost.default || appHost; import appHost from 'apphost';
var _GAMEPAD_A_BUTTON_INDEX = 0; var _GAMEPAD_A_BUTTON_INDEX = 0;
var _GAMEPAD_B_BUTTON_INDEX = 1; var _GAMEPAD_B_BUTTON_INDEX = 1;
var _GAMEPAD_DPAD_UP_BUTTON_INDEX = 12; var _GAMEPAD_DPAD_UP_BUTTON_INDEX = 12;
var _GAMEPAD_DPAD_DOWN_BUTTON_INDEX = 13; var _GAMEPAD_DPAD_DOWN_BUTTON_INDEX = 13;
var _GAMEPAD_DPAD_LEFT_BUTTON_INDEX = 14; var _GAMEPAD_DPAD_LEFT_BUTTON_INDEX = 14;
var _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX = 15; var _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX = 15;
var _GAMEPAD_A_KEY = 'GamepadA'; var _GAMEPAD_A_KEY = 'GamepadA';
var _GAMEPAD_B_KEY = 'GamepadB'; var _GAMEPAD_B_KEY = 'GamepadB';
var _GAMEPAD_DPAD_UP_KEY = 'GamepadDPadUp'; var _GAMEPAD_DPAD_UP_KEY = 'GamepadDPadUp';
var _GAMEPAD_DPAD_DOWN_KEY = 'GamepadDPadDown'; var _GAMEPAD_DPAD_DOWN_KEY = 'GamepadDPadDown';
var _GAMEPAD_DPAD_LEFT_KEY = 'GamepadDPadLeft'; var _GAMEPAD_DPAD_LEFT_KEY = 'GamepadDPadLeft';
var _GAMEPAD_DPAD_RIGHT_KEY = 'GamepadDPadRight'; var _GAMEPAD_DPAD_RIGHT_KEY = 'GamepadDPadRight';
var _GAMEPAD_LEFT_THUMBSTICK_UP_KEY = 'GamepadLeftThumbStickUp'; var _GAMEPAD_LEFT_THUMBSTICK_UP_KEY = 'GamepadLeftThumbStickUp';
var _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEY = 'GamepadLeftThumbStickDown'; var _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEY = 'GamepadLeftThumbStickDown';
var _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEY = 'GamepadLeftThumbStickLeft'; var _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEY = 'GamepadLeftThumbStickLeft';
var _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEY = 'GamepadLeftThumbStickRight'; var _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEY = 'GamepadLeftThumbStickRight';
var _GAMEPAD_A_KEYCODE = 0; var _GAMEPAD_A_KEYCODE = 0;
var _GAMEPAD_B_KEYCODE = 27; var _GAMEPAD_B_KEYCODE = 27;
var _GAMEPAD_DPAD_UP_KEYCODE = 38; var _GAMEPAD_DPAD_UP_KEYCODE = 38;
var _GAMEPAD_DPAD_DOWN_KEYCODE = 40; var _GAMEPAD_DPAD_DOWN_KEYCODE = 40;
var _GAMEPAD_DPAD_LEFT_KEYCODE = 37; var _GAMEPAD_DPAD_LEFT_KEYCODE = 37;
var _GAMEPAD_DPAD_RIGHT_KEYCODE = 39; var _GAMEPAD_DPAD_RIGHT_KEYCODE = 39;
var _GAMEPAD_LEFT_THUMBSTICK_UP_KEYCODE = 38; var _GAMEPAD_LEFT_THUMBSTICK_UP_KEYCODE = 38;
var _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEYCODE = 40; var _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEYCODE = 40;
var _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEYCODE = 37; var _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEYCODE = 37;
var _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEYCODE = 39; var _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEYCODE = 39;
var _THUMB_STICK_THRESHOLD = 0.75; var _THUMB_STICK_THRESHOLD = 0.75;
var _leftThumbstickUpPressed = false; var _leftThumbstickUpPressed = false;
var _leftThumbstickDownPressed = false; var _leftThumbstickDownPressed = false;
var _leftThumbstickLeftPressed = false; var _leftThumbstickLeftPressed = false;
var _leftThumbstickRightPressed = false; var _leftThumbstickRightPressed = false;
var _dPadUpPressed = false; var _dPadUpPressed = false;
var _dPadDownPressed = false; var _dPadDownPressed = false;
var _dPadLeftPressed = false; var _dPadLeftPressed = false;
var _dPadRightPressed = false; var _dPadRightPressed = false;
var _gamepadAPressed = false; var _gamepadAPressed = false;
var _gamepadBPressed = false; var _gamepadBPressed = false;
// The set of buttons on the gamepad we listen for. // The set of buttons on the gamepad we listen for.
var ProcessedButtons = [ var ProcessedButtons = [
_GAMEPAD_DPAD_UP_BUTTON_INDEX, _GAMEPAD_DPAD_UP_BUTTON_INDEX,
_GAMEPAD_DPAD_DOWN_BUTTON_INDEX, _GAMEPAD_DPAD_DOWN_BUTTON_INDEX,
_GAMEPAD_DPAD_LEFT_BUTTON_INDEX, _GAMEPAD_DPAD_LEFT_BUTTON_INDEX,
_GAMEPAD_DPAD_RIGHT_BUTTON_INDEX, _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX,
_GAMEPAD_A_BUTTON_INDEX, _GAMEPAD_A_BUTTON_INDEX,
_GAMEPAD_B_BUTTON_INDEX _GAMEPAD_B_BUTTON_INDEX
]; ];
var _ButtonPressedState = {}; var _ButtonPressedState = {};
_ButtonPressedState.getgamepadA = function () { _ButtonPressedState.getgamepadA = function () {
return _gamepadAPressed; return _gamepadAPressed;
}; };
_ButtonPressedState.setgamepadA = function (newPressedState) { _ButtonPressedState.setgamepadA = function (newPressedState) {
raiseKeyEvent(_gamepadAPressed, newPressedState, _GAMEPAD_A_KEY, _GAMEPAD_A_KEYCODE, false, true); raiseKeyEvent(_gamepadAPressed, newPressedState, _GAMEPAD_A_KEY, _GAMEPAD_A_KEYCODE, false, true);
_gamepadAPressed = newPressedState; _gamepadAPressed = newPressedState;
}; };
_ButtonPressedState.getgamepadB = function () { _ButtonPressedState.getgamepadB = function () {
return _gamepadBPressed; return _gamepadBPressed;
}; };
_ButtonPressedState.setgamepadB = function (newPressedState) { _ButtonPressedState.setgamepadB = function (newPressedState) {
raiseKeyEvent(_gamepadBPressed, newPressedState, _GAMEPAD_B_KEY, _GAMEPAD_B_KEYCODE); raiseKeyEvent(_gamepadBPressed, newPressedState, _GAMEPAD_B_KEY, _GAMEPAD_B_KEYCODE);
_gamepadBPressed = newPressedState; _gamepadBPressed = newPressedState;
}; };
_ButtonPressedState.getleftThumbstickUp = function () { _ButtonPressedState.getleftThumbstickUp = function () {
return _leftThumbstickUpPressed; return _leftThumbstickUpPressed;
}; };
_ButtonPressedState.setleftThumbstickUp = function (newPressedState) { _ButtonPressedState.setleftThumbstickUp = function (newPressedState) {
raiseKeyEvent(_leftThumbstickUpPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_UP_KEY, _GAMEPAD_LEFT_THUMBSTICK_UP_KEYCODE, true); raiseKeyEvent(_leftThumbstickUpPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_UP_KEY, _GAMEPAD_LEFT_THUMBSTICK_UP_KEYCODE, true);
_leftThumbstickUpPressed = newPressedState; _leftThumbstickUpPressed = newPressedState;
}; };
_ButtonPressedState.getleftThumbstickDown = function () { _ButtonPressedState.getleftThumbstickDown = function () {
return _leftThumbstickDownPressed; return _leftThumbstickDownPressed;
}; };
_ButtonPressedState.setleftThumbstickDown = function (newPressedState) { _ButtonPressedState.setleftThumbstickDown = function (newPressedState) {
raiseKeyEvent(_leftThumbstickDownPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEY, _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEYCODE, true); raiseKeyEvent(_leftThumbstickDownPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEY, _GAMEPAD_LEFT_THUMBSTICK_DOWN_KEYCODE, true);
_leftThumbstickDownPressed = newPressedState; _leftThumbstickDownPressed = newPressedState;
}; };
_ButtonPressedState.getleftThumbstickLeft = function () { _ButtonPressedState.getleftThumbstickLeft = function () {
return _leftThumbstickLeftPressed; return _leftThumbstickLeftPressed;
}; };
_ButtonPressedState.setleftThumbstickLeft = function (newPressedState) { _ButtonPressedState.setleftThumbstickLeft = function (newPressedState) {
raiseKeyEvent(_leftThumbstickLeftPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEY, _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEYCODE, true); raiseKeyEvent(_leftThumbstickLeftPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEY, _GAMEPAD_LEFT_THUMBSTICK_LEFT_KEYCODE, true);
_leftThumbstickLeftPressed = newPressedState; _leftThumbstickLeftPressed = newPressedState;
}; };
_ButtonPressedState.getleftThumbstickRight = function () { _ButtonPressedState.getleftThumbstickRight = function () {
return _leftThumbstickRightPressed; return _leftThumbstickRightPressed;
}; };
_ButtonPressedState.setleftThumbstickRight = function (newPressedState) { _ButtonPressedState.setleftThumbstickRight = function (newPressedState) {
raiseKeyEvent(_leftThumbstickRightPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEY, _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEYCODE, true); raiseKeyEvent(_leftThumbstickRightPressed, newPressedState, _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEY, _GAMEPAD_LEFT_THUMBSTICK_RIGHT_KEYCODE, true);
_leftThumbstickRightPressed = newPressedState; _leftThumbstickRightPressed = newPressedState;
}; };
_ButtonPressedState.getdPadUp = function () { _ButtonPressedState.getdPadUp = function () {
return _dPadUpPressed; return _dPadUpPressed;
}; };
_ButtonPressedState.setdPadUp = function (newPressedState) { _ButtonPressedState.setdPadUp = function (newPressedState) {
raiseKeyEvent(_dPadUpPressed, newPressedState, _GAMEPAD_DPAD_UP_KEY, _GAMEPAD_DPAD_UP_KEYCODE, true); raiseKeyEvent(_dPadUpPressed, newPressedState, _GAMEPAD_DPAD_UP_KEY, _GAMEPAD_DPAD_UP_KEYCODE, true);
_dPadUpPressed = newPressedState; _dPadUpPressed = newPressedState;
}; };
_ButtonPressedState.getdPadDown = function () { _ButtonPressedState.getdPadDown = function () {
return _dPadDownPressed; return _dPadDownPressed;
}; };
_ButtonPressedState.setdPadDown = function (newPressedState) { _ButtonPressedState.setdPadDown = function (newPressedState) {
raiseKeyEvent(_dPadDownPressed, newPressedState, _GAMEPAD_DPAD_DOWN_KEY, _GAMEPAD_DPAD_DOWN_KEYCODE, true); raiseKeyEvent(_dPadDownPressed, newPressedState, _GAMEPAD_DPAD_DOWN_KEY, _GAMEPAD_DPAD_DOWN_KEYCODE, true);
_dPadDownPressed = newPressedState; _dPadDownPressed = newPressedState;
}; };
_ButtonPressedState.getdPadLeft = function () { _ButtonPressedState.getdPadLeft = function () {
return _dPadLeftPressed; return _dPadLeftPressed;
}; };
_ButtonPressedState.setdPadLeft = function (newPressedState) { _ButtonPressedState.setdPadLeft = function (newPressedState) {
raiseKeyEvent(_dPadLeftPressed, newPressedState, _GAMEPAD_DPAD_LEFT_KEY, _GAMEPAD_DPAD_LEFT_KEYCODE, true); raiseKeyEvent(_dPadLeftPressed, newPressedState, _GAMEPAD_DPAD_LEFT_KEY, _GAMEPAD_DPAD_LEFT_KEYCODE, true);
_dPadLeftPressed = newPressedState; _dPadLeftPressed = newPressedState;
}; };
_ButtonPressedState.getdPadRight = function () { _ButtonPressedState.getdPadRight = function () {
return _dPadRightPressed; return _dPadRightPressed;
}; };
_ButtonPressedState.setdPadRight = function (newPressedState) { _ButtonPressedState.setdPadRight = function (newPressedState) {
raiseKeyEvent(_dPadRightPressed, newPressedState, _GAMEPAD_DPAD_RIGHT_KEY, _GAMEPAD_DPAD_RIGHT_KEYCODE, true); raiseKeyEvent(_dPadRightPressed, newPressedState, _GAMEPAD_DPAD_RIGHT_KEY, _GAMEPAD_DPAD_RIGHT_KEYCODE, true);
_dPadRightPressed = newPressedState; _dPadRightPressed = newPressedState;
}; };
var times = {}; var times = {};
function throttle(key) { function throttle(key) {
var time = times[key] || 0; var time = times[key] || 0;
var now = new Date().getTime(); var now = new Date().getTime();
if ((now - time) >= 200) {
//times[key] = now;
return true;
}
return false;
}
function resetThrottle(key) {
times[key] = new Date().getTime();
}
var isElectron = navigator.userAgent.toLowerCase().indexOf('electron') !== -1;
function allowInput() {
// This would be nice but always seems to return true with electron
if (!isElectron && document.hidden) { /* eslint-disable-line compat/compat */
return false;
}
if (appHost.getWindowState() === 'Minimized') {
return false;
}
if ((now - time) >= 200) {
//times[key] = now;
return true; return true;
} }
function raiseEvent(name, key, keyCode) { return false;
if (!allowInput()) { }
return;
}
var event = document.createEvent('Event'); function resetThrottle(key) {
event.initEvent(name, true, true); times[key] = new Date().getTime();
event.key = key; }
event.keyCode = keyCode;
(document.activeElement || document.body).dispatchEvent(event); var isElectron = navigator.userAgent.toLowerCase().indexOf('electron') !== -1;
function allowInput() {
// This would be nice but always seems to return true with electron
if (!isElectron && document.hidden) { /* eslint-disable-line compat/compat */
return false;
} }
function clickElement(elem) { if (appHost.getWindowState() === 'Minimized') {
if (!allowInput()) { return false;
return;
}
elem.click();
} }
function raiseKeyEvent(oldPressedState, newPressedState, key, keyCode, enableRepeatKeyDown, clickonKeyUp) { return true;
// No-op if oldPressedState === newPressedState }
if (newPressedState === true) {
// button down
var fire = false;
// always fire if this is the initial down press function raiseEvent(name, key, keyCode) {
if (oldPressedState === false) { if (!allowInput()) {
fire = true; return;
resetThrottle(key); }
} else if (enableRepeatKeyDown) {
fire = throttle(key);
}
if (fire && keyCode) { var event = document.createEvent('Event');
raiseEvent('keydown', key, keyCode); event.initEvent(name, true, true);
} event.key = key;
} else if (newPressedState === false && oldPressedState === true) { event.keyCode = keyCode;
(document.activeElement || document.body).dispatchEvent(event);
}
function clickElement(elem) {
if (!allowInput()) {
return;
}
elem.click();
}
function raiseKeyEvent(oldPressedState, newPressedState, key, keyCode, enableRepeatKeyDown, clickonKeyUp) {
// No-op if oldPressedState === newPressedState
if (newPressedState === true) {
// button down
var fire = false;
// always fire if this is the initial down press
if (oldPressedState === false) {
fire = true;
resetThrottle(key); resetThrottle(key);
} else if (enableRepeatKeyDown) {
fire = throttle(key);
}
// button up if (fire && keyCode) {
if (keyCode) { raiseEvent('keydown', key, keyCode);
raiseEvent('keyup', key, keyCode); }
} } else if (newPressedState === false && oldPressedState === true) {
if (clickonKeyUp) { resetThrottle(key);
clickElement(document.activeElement || window);
} // button up
if (keyCode) {
raiseEvent('keyup', key, keyCode);
}
if (clickonKeyUp) {
clickElement(document.activeElement || window);
} }
} }
}
var inputLoopTimer; var inputLoopTimer;
function runInputLoop() { function runInputLoop() {
// Get the latest gamepad state. // Get the latest gamepad state.
var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */ var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */
for (var i = 0, len = gamepads.length; i < len; i++) { for (var i = 0, len = gamepads.length; i < len; i++) {
var gamepad = gamepads[i]; var gamepad = gamepads[i];
if (!gamepad) { if (!gamepad) {
continue; continue;
} }
// Iterate through the axes // Iterate through the axes
var axes = gamepad.axes; var axes = gamepad.axes;
var leftStickX = axes[0]; var leftStickX = axes[0];
var leftStickY = axes[1]; var leftStickY = axes[1];
if (leftStickX > _THUMB_STICK_THRESHOLD) { // Right if (leftStickX > _THUMB_STICK_THRESHOLD) { // Right
_ButtonPressedState.setleftThumbstickRight(true); _ButtonPressedState.setleftThumbstickRight(true);
} else if (leftStickX < -_THUMB_STICK_THRESHOLD) { // Left } else if (leftStickX < -_THUMB_STICK_THRESHOLD) { // Left
_ButtonPressedState.setleftThumbstickLeft(true); _ButtonPressedState.setleftThumbstickLeft(true);
} else if (leftStickY < -_THUMB_STICK_THRESHOLD) { // Up } else if (leftStickY < -_THUMB_STICK_THRESHOLD) { // Up
_ButtonPressedState.setleftThumbstickUp(true); _ButtonPressedState.setleftThumbstickUp(true);
} else if (leftStickY > _THUMB_STICK_THRESHOLD) { // Down } else if (leftStickY > _THUMB_STICK_THRESHOLD) { // Down
_ButtonPressedState.setleftThumbstickDown(true); _ButtonPressedState.setleftThumbstickDown(true);
} else { } else {
_ButtonPressedState.setleftThumbstickLeft(false); _ButtonPressedState.setleftThumbstickLeft(false);
_ButtonPressedState.setleftThumbstickRight(false); _ButtonPressedState.setleftThumbstickRight(false);
_ButtonPressedState.setleftThumbstickUp(false); _ButtonPressedState.setleftThumbstickUp(false);
_ButtonPressedState.setleftThumbstickDown(false); _ButtonPressedState.setleftThumbstickDown(false);
} }
// Iterate through the buttons to see if Left thumbstick, DPad, A and B are pressed. // Iterate through the buttons to see if Left thumbstick, DPad, A and B are pressed.
var buttons = gamepad.buttons; var buttons = gamepad.buttons;
for (var j = 0, len = buttons.length; j < len; j++) { for (var j = 0, len = buttons.length; j < len; j++) {
if (ProcessedButtons.indexOf(j) !== -1) { if (ProcessedButtons.indexOf(j) !== -1) {
if (buttons[j].pressed) { if (buttons[j].pressed) {
switch (j) { switch (j) {
case _GAMEPAD_DPAD_UP_BUTTON_INDEX: case _GAMEPAD_DPAD_UP_BUTTON_INDEX:
_ButtonPressedState.setdPadUp(true); _ButtonPressedState.setdPadUp(true);
break; break;
case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX: case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX:
_ButtonPressedState.setdPadDown(true); _ButtonPressedState.setdPadDown(true);
break; break;
case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX: case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX:
_ButtonPressedState.setdPadLeft(true); _ButtonPressedState.setdPadLeft(true);
break; break;
case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX: case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX:
_ButtonPressedState.setdPadRight(true); _ButtonPressedState.setdPadRight(true);
break; break;
case _GAMEPAD_A_BUTTON_INDEX: case _GAMEPAD_A_BUTTON_INDEX:
_ButtonPressedState.setgamepadA(true); _ButtonPressedState.setgamepadA(true);
break; break;
case _GAMEPAD_B_BUTTON_INDEX: case _GAMEPAD_B_BUTTON_INDEX:
_ButtonPressedState.setgamepadB(true); _ButtonPressedState.setgamepadB(true);
break; break;
default: default:
// No-op // No-op
break; break;
} }
} else { } else {
switch (j) { switch (j) {
case _GAMEPAD_DPAD_UP_BUTTON_INDEX: case _GAMEPAD_DPAD_UP_BUTTON_INDEX:
if (_ButtonPressedState.getdPadUp()) { if (_ButtonPressedState.getdPadUp()) {
_ButtonPressedState.setdPadUp(false); _ButtonPressedState.setdPadUp(false);
} }
break; break;
case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX: case _GAMEPAD_DPAD_DOWN_BUTTON_INDEX:
if (_ButtonPressedState.getdPadDown()) { if (_ButtonPressedState.getdPadDown()) {
_ButtonPressedState.setdPadDown(false); _ButtonPressedState.setdPadDown(false);
} }
break; break;
case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX: case _GAMEPAD_DPAD_LEFT_BUTTON_INDEX:
if (_ButtonPressedState.getdPadLeft()) { if (_ButtonPressedState.getdPadLeft()) {
_ButtonPressedState.setdPadLeft(false); _ButtonPressedState.setdPadLeft(false);
} }
break; break;
case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX: case _GAMEPAD_DPAD_RIGHT_BUTTON_INDEX:
if (_ButtonPressedState.getdPadRight()) { if (_ButtonPressedState.getdPadRight()) {
_ButtonPressedState.setdPadRight(false); _ButtonPressedState.setdPadRight(false);
} }
break; break;
case _GAMEPAD_A_BUTTON_INDEX: case _GAMEPAD_A_BUTTON_INDEX:
if (_ButtonPressedState.getgamepadA()) { if (_ButtonPressedState.getgamepadA()) {
_ButtonPressedState.setgamepadA(false); _ButtonPressedState.setgamepadA(false);
} }
break; break;
case _GAMEPAD_B_BUTTON_INDEX: case _GAMEPAD_B_BUTTON_INDEX:
if (_ButtonPressedState.getgamepadB()) { if (_ButtonPressedState.getgamepadB()) {
_ButtonPressedState.setgamepadB(false); _ButtonPressedState.setgamepadB(false);
} }
break; break;
default: default:
// No-op // No-op
break; break;
}
} }
} }
} }
} }
// Schedule the next one
inputLoopTimer = requestAnimationFrame(runInputLoop);
} }
// Schedule the next one
inputLoopTimer = requestAnimationFrame(runInputLoop);
}
function startInputLoop() { function startInputLoop() {
if (!inputLoopTimer) { if (!inputLoopTimer) {
runInputLoop(); runInputLoop();
}
}
function stopInputLoop() {
cancelAnimationFrame(inputLoopTimer);
inputLoopTimer = undefined;
}
function isGamepadConnected() {
var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */
for (var i = 0, len = gamepads.length; i < len; i++) {
var gamepad = gamepads[i];
if (gamepad && gamepad.connected) {
return true;
} }
} }
return false;
}
function stopInputLoop() { function onFocusOrGamepadAttach(e) {
cancelAnimationFrame(inputLoopTimer); /* eslint-disable-next-line compat/compat */
inputLoopTimer = undefined; if (isGamepadConnected() && document.hasFocus()) {
console.log('Gamepad connected! Starting input loop');
startInputLoop();
} }
}
function isGamepadConnected() { function onFocusOrGamepadDetach(e) {
var gamepads = navigator.getGamepads(); /* eslint-disable-line compat/compat */ /* eslint-disable-next-line compat/compat */
for (var i = 0, len = gamepads.length; i < len; i++) { if (!isGamepadConnected() || !document.hasFocus()) {
var gamepad = gamepads[i]; console.log('Gamepad disconnected! No other gamepads are connected, stopping input loop');
if (gamepad && gamepad.connected) { stopInputLoop();
return true; } else {
} console.log('Gamepad disconnected! There are gamepads still connected.');
}
return false;
} }
}
function onFocusOrGamepadAttach(e) { // Event listeners for any change in gamepads' state.
/* eslint-disable-next-line compat/compat */ window.addEventListener('gamepaddisconnected', onFocusOrGamepadDetach);
if (isGamepadConnected() && document.hasFocus()) { window.addEventListener('gamepadconnected', onFocusOrGamepadAttach);
console.log('Gamepad connected! Starting input loop'); window.addEventListener('blur', onFocusOrGamepadDetach);
startInputLoop(); window.addEventListener('focus', onFocusOrGamepadAttach);
}
}
function onFocusOrGamepadDetach(e) { onFocusOrGamepadAttach();
/* eslint-disable-next-line compat/compat */
if (!isGamepadConnected() || !document.hasFocus()) {
console.log('Gamepad disconnected! No other gamepads are connected, stopping input loop');
stopInputLoop();
} else {
console.log('Gamepad disconnected! There are gamepads still connected.');
}
}
// Event listeners for any change in gamepads' state. // The gamepadInputEmulation is a string property that exists in JavaScript UWAs and in WebViews in UWAs.
window.addEventListener('gamepaddisconnected', onFocusOrGamepadDetach); // It won't exist in Win8.1 style apps or browsers.
window.addEventListener('gamepadconnected', onFocusOrGamepadAttach); if (window.navigator && typeof window.navigator.gamepadInputEmulation === 'string') {
window.addEventListener('blur', onFocusOrGamepadDetach); // We want the gamepad to provide gamepad VK keyboard events rather than moving a
window.addEventListener('focus', onFocusOrGamepadAttach); // mouse like cursor. Set to "keyboard", the gamepad will provide such keyboard events
// and provide input to the DOM navigator.getGamepads API.
onFocusOrGamepadAttach(); window.navigator.gamepadInputEmulation = 'gamepad';
}
// The gamepadInputEmulation is a string property that exists in JavaScript UWAs and in WebViews in UWAs.
// It won't exist in Win8.1 style apps or browsers.
if (window.navigator && typeof window.navigator.gamepadInputEmulation === 'string') {
// We want the gamepad to provide gamepad VK keyboard events rather than moving a
// mouse like cursor. Set to "keyboard", the gamepad will provide such keyboard events
// and provide input to the DOM navigator.getGamepads API.
window.navigator.gamepadInputEmulation = 'gamepad';
}
});

View file

@ -185,6 +185,12 @@ import appHost from 'apphost';
'changezoom': () => { 'changezoom': () => {
playbackManager.toggleAspectRatio(); playbackManager.toggleAspectRatio();
}, },
'increaseplaybackrate': () => {
playbackManager.increasePlaybackRate();
},
'decreaseplaybackrate': () => {
playbackManager.decreasePlaybackRate();
},
'changeaudiotrack': () => { 'changeaudiotrack': () => {
playbackManager.changeAudioStream(); playbackManager.changeAudioStream();
}, },

View file

@ -39,14 +39,14 @@ function renderItems(page, item) {
if (item.EpisodeCount) { if (item.EpisodeCount) {
sections.push({ sections.push({
name: globalize.translate('TabEpisodes'), name: globalize.translate('Episodes'),
type: 'Episode' type: 'Episode'
}); });
} }
if (item.TrailerCount) { if (item.TrailerCount) {
sections.push({ sections.push({
name: globalize.translate('TabTrailers'), name: globalize.translate('Trailers'),
type: 'Trailer' type: 'Trailer'
}); });
} }
@ -60,7 +60,7 @@ function renderItems(page, item) {
if (item.MusicVideoCount) { if (item.MusicVideoCount) {
sections.push({ sections.push({
name: globalize.translate('TabMusicVideos'), name: globalize.translate('HeaderMusicVideos'),
type: 'MusicVideo' type: 'MusicVideo'
}); });
} }

View file

@ -155,7 +155,7 @@ export function enable() {
function attachGamepadScript(e) { function attachGamepadScript(e) {
console.log('Gamepad connected! Attaching gamepadtokey.js script'); console.log('Gamepad connected! Attaching gamepadtokey.js script');
window.removeEventListener('gamepadconnected', attachGamepadScript); window.removeEventListener('gamepadconnected', attachGamepadScript);
/* eslint-disable-next-line no-unused-expressions */ /* eslint-disable-next-line @babel/no-unused-expressions */
import('scripts/gamepadtokey'); import('scripts/gamepadtokey');
} }

View file

@ -109,7 +109,7 @@ export function getQueryPagingHtml (options) {
} }
if (options.filterButton) { if (options.filterButton) {
html += '<button is="paper-icon-button-light" class="btnFilter autoSize" title="' + globalize.translate('ButtonFilter') + '"><span class="material-icons filter_list"></span></button>'; html += '<button is="paper-icon-button-light" class="btnFilter autoSize" title="' + globalize.translate('Filter') + '"><span class="material-icons filter_list"></span></button>';
} }
html += '</div>'; html += '</div>';

View file

@ -8,7 +8,7 @@ import appRouter from 'appRouter';
import appHost from 'apphost'; import appHost from 'apphost';
import playbackManager from 'playbackManager'; import playbackManager from 'playbackManager';
import syncPlayManager from 'syncPlayManager'; import syncPlayManager from 'syncPlayManager';
import groupSelectionMenu from 'groupSelectionMenu'; import * as groupSelectionMenu from 'groupSelectionMenu';
import browser from 'browser'; import browser from 'browser';
import globalize from 'globalize'; import globalize from 'globalize';
import imageHelper from 'scripts/imagehelper'; import imageHelper from 'scripts/imagehelper';
@ -270,7 +270,7 @@ import 'flexStyles';
function refreshLibraryInfoInDrawer(user, drawer) { function refreshLibraryInfoInDrawer(user, drawer) {
let html = ''; let html = '';
html += '<div style="height:.5em;"></div>'; html += '<div style="height:.5em;"></div>';
html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder" href="home.html"><span class="material-icons navMenuOptionIcon home"></span><span class="navMenuOptionText">' + globalize.translate('ButtonHome') + '</span></a>'; html += '<a is="emby-linkbutton" class="navMenuOption lnkMediaFolder" href="home.html"><span class="material-icons navMenuOptionIcon home"></span><span class="navMenuOptionText">' + globalize.translate('Home') + '</span></a>';
// libraries are added here // libraries are added here
html += '<div class="libraryMenuOptions">'; html += '<div class="libraryMenuOptions">';
@ -799,7 +799,7 @@ import 'flexStyles';
} }
function getNavDrawerOptions() { function getNavDrawerOptions() {
let drawerWidth = screen.availWidth - 50; let drawerWidth = window.screen.availWidth - 50;
drawerWidth = Math.max(drawerWidth, 240); drawerWidth = Math.max(drawerWidth, 240);
drawerWidth = Math.min(drawerWidth, 320); drawerWidth = Math.min(drawerWidth, 320);
return { return {

View file

@ -31,7 +31,7 @@ function sameDomain(url) {
var a = document.createElement('a'); var a = document.createElement('a');
a.href = url; a.href = url;
return location.hostname === a.hostname && location.protocol === a.protocol; return window.location.hostname === a.hostname && window.location.protocol === a.protocol;
} }
function download(url) { function download(url) {
@ -62,4 +62,3 @@ export default function (urls) {
download(url); download(url);
}); });
} }

View file

@ -1,4 +1,4 @@
function getWindowLocationSearch(win) { window.getWindowLocationSearch = function(win) {
'use strict'; 'use strict';
var search = (win || window).location.search; var search = (win || window).location.search;
@ -12,9 +12,9 @@ function getWindowLocationSearch(win) {
} }
return search || ''; return search || '';
} };
window.getParameterByName = function (name, url) { window.getParameterByName = function(name, url) {
'use strict'; 'use strict';
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]'); name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
@ -29,7 +29,7 @@ window.getParameterByName = function (name, url) {
return decodeURIComponent(results[1].replace(/\+/g, ' ')); return decodeURIComponent(results[1].replace(/\+/g, ' '));
}; };
function pageClassOn(eventName, className, fn) { window.pageClassOn = function(eventName, className, fn) {
'use strict'; 'use strict';
document.addEventListener(eventName, function (event) { document.addEventListener(eventName, function (event) {
@ -39,7 +39,7 @@ function pageClassOn(eventName, className, fn) {
fn.call(target, event); fn.call(target, event);
} }
}); });
} };
window.pageIdOn = function(eventName, id, fn) { window.pageIdOn = function(eventName, id, fn) {
'use strict'; 'use strict';
@ -53,187 +53,6 @@ window.pageIdOn = function(eventName, id, fn) {
}); });
}; };
var Dashboard = {
getCurrentUser: function () {
return window.ApiClient.getCurrentUser(false);
},
//TODO: investigate url prefix support for serverAddress function
serverAddress: function () {
if (AppInfo.isNativeApp) {
var apiClient = window.ApiClient;
if (apiClient) {
return apiClient.serverAddress();
}
return null;
}
var urlLower = window.location.href.toLowerCase();
var index = urlLower.lastIndexOf('/web');
if (index != -1) {
return urlLower.substring(0, index);
}
var loc = window.location;
var address = loc.protocol + '//' + loc.hostname;
if (loc.port) {
address += ':' + loc.port;
}
return address;
},
getCurrentUserId: function () {
var apiClient = window.ApiClient;
if (apiClient) {
return apiClient.getCurrentUserId();
}
return null;
},
onServerChanged: function (userId, accessToken, apiClient) {
apiClient = apiClient || window.ApiClient;
window.ApiClient = apiClient;
},
logout: function () {
ConnectionManager.logout().then(function () {
var loginPage;
if (AppInfo.isNativeApp) {
loginPage = 'selectserver.html';
window.ApiClient = null;
} else {
loginPage = 'login.html';
}
Dashboard.navigate(loginPage);
});
},
getConfigurationPageUrl: function (name) {
return 'configurationpage?name=' + encodeURIComponent(name);
},
getConfigurationResourceUrl: function (name) {
if (AppInfo.isNativeApp) {
return ApiClient.getUrl('web/ConfigurationPage', {
name: name
});
}
return Dashboard.getConfigurationPageUrl(name);
},
navigate: function (url, preserveQueryString) {
if (!url) {
throw new Error('url cannot be null or empty');
}
var queryString = getWindowLocationSearch();
if (preserveQueryString && queryString) {
url += queryString;
}
return new Promise(function (resolve, reject) {
require(['appRouter'], function (appRouter) {
return appRouter.show(url).then(resolve, reject);
});
});
},
navigate_direct: function (path) {
return new Promise(function (resolve, reject) {
require(['appRouter'], function (appRouter) {
return appRouter.showDirect(path).then(resolve, reject);
});
});
},
processPluginConfigurationUpdateResult: function () {
require(['loading', 'toast'], function (loading, toast) {
loading.hide();
toast.default(Globalize.translate('MessageSettingsSaved'));
});
},
processServerConfigurationUpdateResult: function (result) {
require(['loading', 'toast'], function (loading, toast) {
loading.hide();
toast.default(Globalize.translate('MessageSettingsSaved'));
});
},
processErrorResponse: function (response) {
require(['loading'], function (loading) {
loading.hide();
});
var status = '' + response.status;
if (response.statusText) {
status = response.statusText;
}
Dashboard.alert({
title: status,
message: response.headers ? response.headers.get('X-Application-Error-Code') : null
});
},
alert: function (options) {
if (typeof options == 'string') {
return void require(['toast'], function (toast) {
toast.default({
text: options
});
});
}
require(['alert'], function (alert) {
alert.default({
title: options.title || Globalize.translate('HeaderAlert'),
text: options.message
}).then(options.callback || function () {});
});
},
capabilities: function (appHost) {
var capabilities = {
PlayableMediaTypes: ['Audio', 'Video'],
SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'SetShuffleQueue', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'],
SupportsPersistentIdentifier: self.appMode === 'cordova' || self.appMode === 'android',
SupportsMediaControl: true
};
appHost.getPushTokenInfo();
return capabilities = Object.assign(capabilities, appHost.getPushTokenInfo());
},
selectServer: function () {
if (window.NativeShell && typeof window.NativeShell.selectServer === 'function') {
window.NativeShell.selectServer();
} else {
Dashboard.navigate('selectserver.html');
}
},
hideLoadingMsg: function() {
'use strict';
require(['loading'], function(loading) {
loading.hide();
});
},
showLoadingMsg: function() {
'use strict';
require(['loading'], function(loading) {
loading.show();
});
},
confirm: function(message, title, callback) {
'use strict';
require(['confirm'], function(confirm) {
confirm(message, title).then(function() {
callback(!0);
}).catch(function() {
callback(!1);
});
});
}
};
var AppInfo = {}; var AppInfo = {};
function initClient() { function initClient() {
@ -288,7 +107,7 @@ function initClient() {
if (!AppInfo.isNativeApp) { if (!AppInfo.isNativeApp) {
console.debug('loading ApiClient singleton'); console.debug('loading ApiClient singleton');
return require(['apiclient'], function (apiClientFactory) { return require(['apiclient', 'clientUtils'], function (apiClientFactory, clientUtils) {
console.debug('creating ApiClient singleton'); console.debug('creating ApiClient singleton');
var apiClient = new apiClientFactory(Dashboard.serverAddress(), appHost.appName(), appHost.appVersion(), appHost.deviceName(), appHost.deviceId()); var apiClient = new apiClientFactory(Dashboard.serverAddress(), appHost.appName(), appHost.appVersion(), appHost.deviceName(), appHost.deviceId());
@ -340,7 +159,7 @@ function initClient() {
function getPlaybackManager(playbackManager) { function getPlaybackManager(playbackManager) {
window.addEventListener('beforeunload', function () { window.addEventListener('beforeunload', function () {
try { try {
playbackManager.onAppClose(); playbackManager.default.onAppClose();
} catch (err) { } catch (err) {
console.error('error in onAppClose: ' + err); console.error('error in onAppClose: ' + err);
} }
@ -368,45 +187,21 @@ function initClient() {
} }
function defineResizeObserver() { function defineResizeObserver() {
if (self.ResizeObserver) { if (window.ResizeObserver) {
define('ResizeObserver', [], function () { define('ResizeObserver', [], function () {
return self.ResizeObserver; return window.ResizeObserver;
}); });
} else { } else {
define('ResizeObserver', ['resize-observer-polyfill'], returnFirstDependency); define('ResizeObserver', ['resize-observer-polyfill'], returnFirstDependency);
} }
} }
function initRequireWithBrowser() {
var componentsPath = getComponentsPath();
var scriptsPath = getScriptsPath();
define('filesystem', [scriptsPath + '/filesystem'], returnFirstDependency);
define('lazyLoader', [componentsPath + '/lazyLoader/lazyLoaderIntersectionObserver'], returnFirstDependency);
define('shell', [scriptsPath + '/shell'], returnFirstDependency);
define('alert', [componentsPath + '/alert'], returnFirstDependency);
defineResizeObserver();
define('dialog', [componentsPath + '/dialog/dialog'], returnFirstDependency);
define('confirm', [componentsPath + '/confirm/confirm'], returnFirstDependency);
define('prompt', [componentsPath + '/prompt/prompt'], returnFirstDependency);
define('loading', [componentsPath + '/loading/loading'], returnFirstDependency);
define('multi-download', [scriptsPath + '/multiDownload'], returnFirstDependency);
define('fileDownloader', [scriptsPath + '/fileDownloader'], returnFirstDependency);
define('castSenderApiLoader', [componentsPath + '/castSenderApi'], returnFirstDependency);
}
function init() { function init() {
define('livetvcss', ['css!assets/css/livetv.css'], returnFirstDependency); define('livetvcss', ['css!assets/css/livetv.css'], returnFirstDependency);
define('detailtablecss', ['css!assets/css/detailtable.css'], returnFirstDependency); define('detailtablecss', ['css!assets/css/detailtable.css'], returnFirstDependency);
require(['clientUtils']);
var promises = []; var promises = [];
if (!window.fetch) { if (!window.fetch) {
promises.push(require(['fetch'])); promises.push(require(['fetch']));
@ -453,8 +248,8 @@ function initClient() {
} }
function onGlobalizeInit(browser, globalize) { function onGlobalizeInit(browser, globalize) {
if (self.appMode === 'android') { if (window.appMode === 'android') {
if (self.location.href.toString().toLowerCase().indexOf('start=backgroundsync') !== -1) { if (window.location.href.toString().toLowerCase().indexOf('start=backgroundsync') !== -1) {
return onAppReady(browser); return onAppReady(browser);
} }
} }
@ -479,7 +274,7 @@ function initClient() {
} }
function loadPlugins(appHost, browser, shell) { function loadPlugins(appHost, browser, shell) {
console.debug('loading installed plugins'); console.groupCollapsed('loading installed plugins');
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['webSettings'], function (webSettings) { require(['webSettings'], function (webSettings) {
webSettings.getPlugins().then(function (list) { webSettings.getPlugins().then(function (list) {
@ -497,11 +292,18 @@ function initClient() {
list = list.concat(window.NativeShell.getPlugins()); list = list.concat(window.NativeShell.getPlugins());
} }
Promise.all(list.map(loadPlugin)).then(function () { Promise.all(list.map(loadPlugin))
require(['packageManager'], function (packageManager) { .then(function () {
packageManager.init().then(resolve, reject); console.debug('finished loading plugins');
}); })
}, reject); .catch(() => reject)
.finally(() => {
console.groupEnd('loading installed plugins');
require(['packageManager'], function (packageManager) {
packageManager.default.init().then(resolve, reject);
});
})
;
}); });
}); });
}); });
@ -510,7 +312,7 @@ function initClient() {
function loadPlugin(url) { function loadPlugin(url) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
require(['pluginManager'], function (pluginManager) { require(['pluginManager'], function (pluginManager) {
pluginManager.loadPlugin(url).then(resolve, reject); pluginManager.default.loadPlugin(url).then(resolve, reject);
}); });
}); });
} }
@ -520,6 +322,7 @@ function initClient() {
// ensure that appHost is loaded in this point // ensure that appHost is loaded in this point
require(['apphost', 'appRouter'], function (appHost, appRouter) { require(['apphost', 'appRouter'], function (appHost, appRouter) {
appRouter = appRouter.default || appRouter;
appHost = appHost.default || appHost; appHost = appHost.default || appHost;
window.Emby = {}; window.Emby = {};
@ -581,11 +384,15 @@ function initClient() {
return response.text(); return response.text();
}) })
.then(function(css) { .then(function(css) {
// Inject the branding css as a dom element in body so it will take let style = document.querySelector('#cssBranding');
// precedence over other stylesheets if (!style) {
var style = document.createElement('style'); // Inject the branding css as a dom element in body so it will take
style.appendChild(document.createTextNode(css)); // precedence over other stylesheets
document.body.appendChild(style); style = document.createElement('style');
style.id = 'cssBranding';
document.body.appendChild(style);
}
style.textContent = css;
}) })
.catch(function(err) { .catch(function(err) {
console.warn('Error applying custom css', err); console.warn('Error applying custom css', err);
@ -597,7 +404,7 @@ function initClient() {
function registerServiceWorker() { function registerServiceWorker() {
/* eslint-disable compat/compat */ /* eslint-disable compat/compat */
if (navigator.serviceWorker && self.appMode !== 'cordova' && self.appMode !== 'android') { if (navigator.serviceWorker && window.appMode !== 'cordova' && window.appMode !== 'android') {
try { try {
navigator.serviceWorker.register('serviceworker.js'); navigator.serviceWorker.register('serviceworker.js');
} catch (err) { } catch (err) {
@ -610,19 +417,41 @@ function initClient() {
} }
function onWebComponentsReady() { function onWebComponentsReady() {
initRequireWithBrowser(); var componentsPath = getComponentsPath();
var scriptsPath = getScriptsPath();
if (self.appMode === 'cordova' || self.appMode === 'android' || self.appMode === 'standalone') { define('filesystem', [scriptsPath + '/filesystem'], returnFirstDependency);
define('lazyLoader', [componentsPath + '/lazyLoader/lazyLoaderIntersectionObserver'], returnFirstDependency);
define('shell', [scriptsPath + '/shell'], returnFirstDependency);
define('alert', [componentsPath + '/alert'], returnFirstDependency);
defineResizeObserver();
define('dialog', [componentsPath + '/dialog/dialog'], returnFirstDependency);
define('confirm', [componentsPath + '/confirm/confirm'], returnFirstDependency);
define('prompt', [componentsPath + '/prompt/prompt'], returnFirstDependency);
define('loading', [componentsPath + '/loading/loading'], returnFirstDependency);
define('multi-download', [scriptsPath + '/multiDownload'], returnFirstDependency);
define('fileDownloader', [scriptsPath + '/fileDownloader'], returnFirstDependency);
define('castSenderApiLoader', [componentsPath + '/castSenderApi'], returnFirstDependency);
if (window.appMode === 'cordova' || window.appMode === 'android' || window.appMode === 'standalone') {
AppInfo.isNativeApp = true; AppInfo.isNativeApp = true;
} }
init(); init();
} }
var promise;
var localApiClient; var localApiClient;
let promise;
(function () { function initRequireJs() {
var urlArgs = 'v=' + (window.dashboardVersion || new Date().getDate()); var urlArgs = 'v=' + (window.dashboardVersion || new Date().getDate());
var bowerPath = getBowerPath(); var bowerPath = getBowerPath();
@ -653,7 +482,9 @@ function initClient() {
nowPlayingHelper: componentsPath + '/playback/nowplayinghelper', nowPlayingHelper: componentsPath + '/playback/nowplayinghelper',
pluginManager: componentsPath + '/pluginManager', pluginManager: componentsPath + '/pluginManager',
packageManager: componentsPath + '/packageManager', packageManager: componentsPath + '/packageManager',
screensaverManager: componentsPath + '/screensavermanager' screensaverManager: componentsPath + '/screensavermanager',
clientUtils: scriptsPath + '/clientUtils',
appRouter: 'components/appRouter'
}; };
requirejs.onError = onRequireJsError; requirejs.onError = onRequireJsError;
@ -852,267 +683,9 @@ function initClient() {
return window.ApiClient; return window.ApiClient;
}; };
}); });
define('appRouter', [componentsPath + '/appRouter', 'itemHelper'], function (appRouter, itemHelper) { }
function showItem(item, serverId, options) {
if (typeof item == 'string') {
require(['connectionManager'], function (connectionManager) {
var apiClient = connectionManager.currentApiClient();
apiClient.getItem(apiClient.getCurrentUserId(), item).then(function (item) {
appRouter.showItem(item, options);
});
});
} else {
if (arguments.length == 2) {
options = arguments[1];
}
appRouter.show('/' + appRouter.getRouteUrl(item, options), {
item: item
});
}
}
appRouter.showLocalLogin = function (serverId, manualLogin) {
Dashboard.navigate('login.html?serverid=' + serverId);
};
appRouter.showVideoOsd = function () {
return Dashboard.navigate('video');
};
appRouter.showSelectServer = function () {
Dashboard.navigate(AppInfo.isNativeApp ? 'selectserver.html' : 'login.html');
};
appRouter.showWelcome = function () {
Dashboard.navigate(AppInfo.isNativeApp ? 'selectserver.html' : 'login.html');
};
appRouter.showSettings = function () {
Dashboard.navigate('mypreferencesmenu.html');
};
appRouter.showGuide = function () {
Dashboard.navigate('livetv.html?tab=1');
};
appRouter.goHome = function () {
Dashboard.navigate('home.html');
};
appRouter.showSearch = function () {
Dashboard.navigate('search.html');
};
appRouter.showLiveTV = function () {
Dashboard.navigate('livetv.html');
};
appRouter.showRecordedTV = function () {
Dashboard.navigate('livetv.html?tab=3');
};
appRouter.showFavorites = function () {
Dashboard.navigate('home.html?tab=1');
};
appRouter.showSettings = function () {
Dashboard.navigate('mypreferencesmenu.html');
};
appRouter.setTitle = function (title) {
LibraryMenu.setTitle(title);
};
appRouter.getRouteUrl = function (item, options) {
if (!item) {
throw new Error('item cannot be null');
}
if (item.url) {
return item.url;
}
var context = options ? options.context : null;
var id = item.Id || item.ItemId;
if (!options) {
options = {};
}
var url;
var itemType = item.Type || (options ? options.itemType : null);
var serverId = item.ServerId || options.serverId;
if (item === 'settings') {
return 'mypreferencesmenu.html';
}
if (item === 'wizard') {
return 'wizardstart.html';
}
if (item === 'manageserver') {
return 'dashboard.html';
}
if (item === 'recordedtv') {
return 'livetv.html?tab=3&serverId=' + options.serverId;
}
if (item === 'nextup') {
return 'list.html?type=nextup&serverId=' + options.serverId;
}
if (item === 'list') {
var url = 'list.html?serverId=' + options.serverId + '&type=' + options.itemTypes;
if (options.isFavorite) {
url += '&IsFavorite=true';
}
return url;
}
if (item === 'livetv') {
if (options.section === 'programs') {
return 'livetv.html?tab=0&serverId=' + options.serverId;
}
if (options.section === 'guide') {
return 'livetv.html?tab=1&serverId=' + options.serverId;
}
if (options.section === 'movies') {
return 'list.html?type=Programs&IsMovie=true&serverId=' + options.serverId;
}
if (options.section === 'shows') {
return 'list.html?type=Programs&IsSeries=true&IsMovie=false&IsNews=false&serverId=' + options.serverId;
}
if (options.section === 'sports') {
return 'list.html?type=Programs&IsSports=true&serverId=' + options.serverId;
}
if (options.section === 'kids') {
return 'list.html?type=Programs&IsKids=true&serverId=' + options.serverId;
}
if (options.section === 'news') {
return 'list.html?type=Programs&IsNews=true&serverId=' + options.serverId;
}
if (options.section === 'onnow') {
return 'list.html?type=Programs&IsAiring=true&serverId=' + options.serverId;
}
if (options.section === 'dvrschedule') {
return 'livetv.html?tab=4&serverId=' + options.serverId;
}
if (options.section === 'seriesrecording') {
return 'livetv.html?tab=5&serverId=' + options.serverId;
}
return 'livetv.html?serverId=' + options.serverId;
}
if (itemType == 'SeriesTimer') {
return 'details?seriesTimerId=' + id + '&serverId=' + serverId;
}
if (item.CollectionType == 'livetv') {
return 'livetv.html';
}
if (item.Type === 'Genre') {
url = 'list.html?genreId=' + item.Id + '&serverId=' + serverId;
if (context === 'livetv') {
url += '&type=Programs';
}
if (options.parentId) {
url += '&parentId=' + options.parentId;
}
return url;
}
if (item.Type === 'MusicGenre') {
url = 'list.html?musicGenreId=' + item.Id + '&serverId=' + serverId;
if (options.parentId) {
url += '&parentId=' + options.parentId;
}
return url;
}
if (item.Type === 'Studio') {
url = 'list.html?studioId=' + item.Id + '&serverId=' + serverId;
if (options.parentId) {
url += '&parentId=' + options.parentId;
}
return url;
}
if (context !== 'folders' && !itemHelper.isLocalItem(item)) {
if (item.CollectionType == 'movies') {
url = 'movies.html?topParentId=' + item.Id;
if (options && options.section === 'latest') {
url += '&tab=1';
}
return url;
}
if (item.CollectionType == 'tvshows') {
url = 'tv.html?topParentId=' + item.Id;
if (options && options.section === 'latest') {
url += '&tab=2';
}
return url;
}
if (item.CollectionType == 'music') {
return 'music.html?topParentId=' + item.Id;
}
}
var itemTypes = ['Playlist', 'TvChannel', 'Program', 'BoxSet', 'MusicAlbum', 'MusicGenre', 'Person', 'Recording', 'MusicArtist'];
if (itemTypes.indexOf(itemType) >= 0) {
return 'details?id=' + id + '&serverId=' + serverId;
}
var contextSuffix = context ? '&context=' + context : '';
if (itemType == 'Series' || itemType == 'Season' || itemType == 'Episode') {
return 'details?id=' + id + contextSuffix + '&serverId=' + serverId;
}
if (item.IsFolder) {
if (id) {
return 'list.html?parentId=' + id + '&serverId=' + serverId;
}
return '#';
}
return 'details?id=' + id + '&serverId=' + serverId;
};
appRouter.showItem = showItem;
return appRouter;
});
})();
initRequireJs();
promise.then(onWebComponentsReady); promise.then(onWebComponentsReady);
} }

View file

@ -1,13 +1,12 @@
import * as webSettings from 'webSettings'; import * as webSettings from 'webSettings';
var themeStyleElement; var themeStyleElement = document.querySelector('#cssTheme');
var currentThemeId; var currentThemeId;
function unloadTheme() { function unloadTheme() {
var elem = themeStyleElement; var elem = themeStyleElement;
if (elem) { if (elem) {
elem.parentNode.removeChild(elem); elem.removeAttribute('href');
themeStyleElement = null;
currentThemeId = null; currentThemeId = null;
} }
} }
@ -45,15 +44,26 @@ function setTheme(id) {
var linkUrl = info.stylesheetPath; var linkUrl = info.stylesheetPath;
unloadTheme(); unloadTheme();
var link = document.createElement('link'); let link = themeStyleElement;
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css'); if (!link) {
link.onload = function () { // Inject the theme css as a dom element in body so it will take
// precedence over other stylesheets
link = document.createElement('link');
link.id = 'cssTheme';
link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css');
document.body.appendChild(link);
}
const onLoad = function (e) {
e.target.removeEventListener('load', onLoad);
resolve(); resolve();
}; };
link.addEventListener('load', onLoad);
link.setAttribute('href', linkUrl); link.setAttribute('href', linkUrl);
document.head.appendChild(link);
themeStyleElement = link; themeStyleElement = link;
currentThemeId = info.themeId; currentThemeId = info.themeId;
}); });

View file

@ -41,8 +41,6 @@
"Absolute": "Absoluut", "Absolute": "Absoluut",
"AlbumArtist": "Album Kunstenaar", "AlbumArtist": "Album Kunstenaar",
"TabLatest": "Nuutste", "TabLatest": "Nuutste",
"TabInfo": "Inligting",
"TabEpisodes": "Episodes",
"TabDirectPlay": "Speel Direk", "TabDirectPlay": "Speel Direk",
"TabDashboard": "Paneelbord", "TabDashboard": "Paneelbord",
"TabContainers": "Houers", "TabContainers": "Houers",
@ -123,12 +121,10 @@
"ThemeSongs": "Tema Liedjies", "ThemeSongs": "Tema Liedjies",
"TellUsAboutYourself": "Vertel ons van jouself", "TellUsAboutYourself": "Vertel ons van jouself",
"TabUpcoming": "Komende", "TabUpcoming": "Komende",
"TabTrailers": "Voorprente",
"TabStreaming": "Stroom", "TabStreaming": "Stroom",
"TabSettings": "Instellings", "TabSettings": "Instellings",
"TabServer": "Bediener", "TabServer": "Bediener",
"TabScheduledTasks": "Geskeduleerde Take", "TabScheduledTasks": "Geskeduleerde Take",
"TabResumeSettings": "Hervat",
"TabResponses": "Reaksies", "TabResponses": "Reaksies",
"TabProfiles": "Profiele", "TabProfiles": "Profiele",
"TabProfile": "Profiel", "TabProfile": "Profiel",
@ -138,7 +134,6 @@
"TabNfoSettings": "NFO Instellings", "TabNfoSettings": "NFO Instellings",
"TabNetworking": "Netwerking", "TabNetworking": "Netwerking",
"TabNetworks": "Netwerke", "TabNetworks": "Netwerke",
"TabMusicVideos": "Musiek Videos",
"TabMusic": "Musiek", "TabMusic": "Musiek",
"TabLogs": "Logs" "TabLogs": "Logs"
} }

View file

@ -21,30 +21,23 @@
"ButtonBack": "خلف", "ButtonBack": "خلف",
"ButtonCancel": "الغاء", "ButtonCancel": "الغاء",
"ButtonChangeServer": "غير الخادم", "ButtonChangeServer": "غير الخادم",
"ButtonEdit": "تعديل",
"ButtonEditImages": "تعديل الصور",
"ButtonEditOtherUserPreferences": "اضبط إعدادات حساب المستخدم هذا، وصورته وتفضيلاته الشخصية.", "ButtonEditOtherUserPreferences": "اضبط إعدادات حساب المستخدم هذا، وصورته وتفضيلاته الشخصية.",
"ButtonFilter": "مرشِّح",
"ButtonForgotPassword": "نسيت كلمة السر", "ButtonForgotPassword": "نسيت كلمة السر",
"ButtonFullscreen": "ملء الشاشة", "ButtonFullscreen": "ملء الشاشة",
"ButtonGuide": "الدليل", "ButtonGuide": "الدليل",
"ButtonHome": "الرئيسية",
"ButtonInfo": "معلومات", "ButtonInfo": "معلومات",
"ButtonLibraryAccess": "صلاحيات المكتبة", "ButtonLibraryAccess": "صلاحيات المكتبة",
"ButtonManualLogin": "الدخول اليدوي", "ButtonManualLogin": "الدخول اليدوي",
"ButtonMore": "المزيد", "ButtonMore": "المزيد",
"ButtonNetwork": "الشبكة", "ButtonNetwork": "الشبكة",
"ButtonNextTrack": "المقطوعة التالية", "ButtonNextTrack": "المقطوعة التالية",
"ButtonOff": "إيقاف التشغيل",
"ButtonOk": "موافق", "ButtonOk": "موافق",
"ButtonOpen": "إفتح", "ButtonOpen": "إفتح",
"ButtonParentalControl": "التحكم الأبوي", "ButtonParentalControl": "التحكم الأبوي",
"ButtonPause": "توقف مؤقت", "ButtonPause": "توقف مؤقت",
"ButtonPlay": "تشغيل",
"ButtonPreviousTrack": "المقطوعة السابقة", "ButtonPreviousTrack": "المقطوعة السابقة",
"ButtonProfile": "حساب", "ButtonProfile": "حساب",
"ButtonQuickStartGuide": "دليل بدء الاستخدام السريع", "ButtonQuickStartGuide": "دليل بدء الاستخدام السريع",
"ButtonRefresh": "إعادة تنشيط",
"ButtonRefreshGuideData": "إعادة تنشيط بيانات الدليل", "ButtonRefreshGuideData": "إعادة تنشيط بيانات الدليل",
"ButtonRemove": "إزالة", "ButtonRemove": "إزالة",
"ButtonRename": "إعادة التسمية", "ButtonRename": "إعادة التسمية",
@ -64,7 +57,6 @@
"ButtonStart": "إبدأ", "ButtonStart": "إبدأ",
"ButtonStop": "إيقاف", "ButtonStop": "إيقاف",
"ButtonSubmit": "تسليم", "ButtonSubmit": "تسليم",
"ButtonSubtitles": "ترجمات",
"ButtonTrailer": "العرض الإعلاني", "ButtonTrailer": "العرض الإعلاني",
"ButtonUninstall": "إزالة التثبيت", "ButtonUninstall": "إزالة التثبيت",
"ButtonWebsite": "موقع إلكتروني", "ButtonWebsite": "موقع إلكتروني",
@ -119,9 +111,7 @@
"HeaderActiveDevices": "الأجهزة المفعّلة", "HeaderActiveDevices": "الأجهزة المفعّلة",
"HeaderActiveRecordings": "التسجيلات المفعلة", "HeaderActiveRecordings": "التسجيلات المفعلة",
"HeaderActivity": "الأنشطة", "HeaderActivity": "الأنشطة",
"HeaderAddScheduledTaskTrigger": "إضافة زناد",
"HeaderAddUpdateImage": "إضافة/تحديث صورة", "HeaderAddUpdateImage": "إضافة/تحديث صورة",
"HeaderAddUser": "إضافة مستخدم",
"HeaderAdditionalParts": "أدوار إضافية", "HeaderAdditionalParts": "أدوار إضافية",
"HeaderAdmin": "المدير", "HeaderAdmin": "المدير",
"HeaderAlert": "تنبيه", "HeaderAlert": "تنبيه",
@ -131,10 +121,8 @@
"HeaderApiKeysHelp": "التطبيقات الخارجية تحتاج أن تمتلك مفتاح api لكي تتصل بالخادم. هذه المفاتيح تُصدر عن طريق تسجيل الدخول بمستخدم عادي، أو عن طريق منح التطبيق مفتاحاً أصدر يدوياً.", "HeaderApiKeysHelp": "التطبيقات الخارجية تحتاج أن تمتلك مفتاح api لكي تتصل بالخادم. هذه المفاتيح تُصدر عن طريق تسجيل الدخول بمستخدم عادي، أو عن طريق منح التطبيق مفتاحاً أصدر يدوياً.",
"HeaderApp": "التطبيق", "HeaderApp": "التطبيق",
"HeaderAudioSettings": "إعدادات الصوت", "HeaderAudioSettings": "إعدادات الصوت",
"HeaderBooks": "الكتب",
"HeaderBranding": "وسومات البرنامج", "HeaderBranding": "وسومات البرنامج",
"HeaderCastAndCrew": "الممثلين وطاقم العمل", "HeaderCastAndCrew": "الممثلين وطاقم العمل",
"HeaderCastCrew": "الممثلين والطاقم",
"HeaderChannelAccess": "صلاحيات القنوات", "HeaderChannelAccess": "صلاحيات القنوات",
"HeaderCodecProfile": "عريضة الكودك", "HeaderCodecProfile": "عريضة الكودك",
"HeaderCodecProfileHelp": "عرائض الكودك تشير إلى محدودية جهاز ما عند تشغيل وسيطة مشفر بكودك معيّن. إن كان هناك أي محدودية مذكورة فستحال الوسيطة إلى التشغير البيني، حتى لو كانت الصيغة مضبوطة للعمل بتلقائية.", "HeaderCodecProfileHelp": "عرائض الكودك تشير إلى محدودية جهاز ما عند تشغيل وسيطة مشفر بكودك معيّن. إن كان هناك أي محدودية مذكورة فستحال الوسيطة إلى التشغير البيني، حتى لو كانت الصيغة مضبوطة للعمل بتلقائية.",
@ -159,12 +147,10 @@
"HeaderDirectPlayProfile": "عريضة التشغيل المباشر", "HeaderDirectPlayProfile": "عريضة التشغيل المباشر",
"HeaderDirectPlayProfileHelp": "أضف مباشرةً عريضة تشغيل للإشارة لأي صيغة يتمكن الجهاز من التعامل معه بتلقائية.", "HeaderDirectPlayProfileHelp": "أضف مباشرةً عريضة تشغيل للإشارة لأي صيغة يتمكن الجهاز من التعامل معه بتلقائية.",
"HeaderEasyPinCode": "الرمز الشخصي الميسر", "HeaderEasyPinCode": "الرمز الشخصي الميسر",
"HeaderEpisodes": "الحلقات",
"HeaderError": "حدث خطأ", "HeaderError": "حدث خطأ",
"HeaderFeatureAccess": "صلاحية الخاصية", "HeaderFeatureAccess": "صلاحية الخاصية",
"HeaderFetchImages": "إطهار الصور:", "HeaderFetchImages": "إطهار الصور:",
"HeaderForKids": "للأطفال", "HeaderForKids": "للأطفال",
"HeaderForgotPassword": "نسيت كلمة السر",
"HeaderFrequentlyPlayed": "تم تشغيله مراراً", "HeaderFrequentlyPlayed": "تم تشغيله مراراً",
"HeaderGuideProviders": "مزودو الأدلة", "HeaderGuideProviders": "مزودو الأدلة",
"HeaderHttpHeaders": "رؤوس HTTP", "HeaderHttpHeaders": "رؤوس HTTP",
@ -186,7 +172,6 @@
"HeaderLoginFailure": "فشل في تسجيل الدخول", "HeaderLoginFailure": "فشل في تسجيل الدخول",
"HeaderMedia": "الوسائط", "HeaderMedia": "الوسائط",
"HeaderMediaFolders": "مجلدات الوسائط", "HeaderMediaFolders": "مجلدات الوسائط",
"HeaderMediaInfo": "معلومات الوسيطة",
"HeaderMoreLikeThis": "المزيد من الروابط لهذا", "HeaderMoreLikeThis": "المزيد من الروابط لهذا",
"HeaderMusicVideos": "الفيديوهات الموسيقية", "HeaderMusicVideos": "الفيديوهات الموسيقية",
"HeaderMyMedia": "وسائطي", "HeaderMyMedia": "وسائطي",
@ -297,7 +282,6 @@
"LabelCustomCertificatePathHelp": "مسار ملف PKCS # 12 يحتوي على شهادة ومفتاح خاص لتمكين دعم TLS على مجال مخصص.", "LabelCustomCertificatePathHelp": "مسار ملف PKCS # 12 يحتوي على شهادة ومفتاح خاص لتمكين دعم TLS على مجال مخصص.",
"LabelCustomCss": "تنيسق CSS مخصص:", "LabelCustomCss": "تنيسق CSS مخصص:",
"LabelCustomCssHelp": "طبق تنسيقك css المخصص لواجهة الويب.", "LabelCustomCssHelp": "طبق تنسيقك css المخصص لواجهة الويب.",
"LabelCustomDeviceDisplayName": "اسم العرض:",
"LabelCustomDeviceDisplayNameHelp": "أذكر اسم عرض مخصوص أو أتركه فارغاً لاستخدام الاسم المبلغ من الجهاز.", "LabelCustomDeviceDisplayNameHelp": "أذكر اسم عرض مخصوص أو أتركه فارغاً لاستخدام الاسم المبلغ من الجهاز.",
"LabelDateAddedBehavior": "كيف يتصرف المحتوى الجديد نحو \"تاريخ الإضافة\" الخاص به:", "LabelDateAddedBehavior": "كيف يتصرف المحتوى الجديد نحو \"تاريخ الإضافة\" الخاص به:",
"LabelDateAddedBehaviorHelp": "إذا اخذت واصفات البيانات قيمة، فإنها سوف تستخدم قبل أن تستخدم أي من هذه الخيارات.", "LabelDateAddedBehaviorHelp": "إذا اخذت واصفات البيانات قيمة، فإنها سوف تستخدم قبل أن تستخدم أي من هذه الخيارات.",
@ -307,7 +291,6 @@
"LabelDefaultUserHelp": "لتحديد مكتبة المستخدم التي تظهر على الأجهزة المتصلة. بإمكان الامتطاء على هذه القيمة لكل جهاز عن طريق عرائض الأجهزة.", "LabelDefaultUserHelp": "لتحديد مكتبة المستخدم التي تظهر على الأجهزة المتصلة. بإمكان الامتطاء على هذه القيمة لكل جهاز عن طريق عرائض الأجهزة.",
"LabelDeviceDescription": "وصف الجهاز", "LabelDeviceDescription": "وصف الجهاز",
"LabelDidlMode": "طور DIDL:", "LabelDidlMode": "طور DIDL:",
"LabelDisplayMissingEpisodesWithinSeasons": "أظهر الحلقات المفقودة في مجلدات المواسم",
"LabelDisplayName": "الاسم المعروض:", "LabelDisplayName": "الاسم المعروض:",
"LabelDisplaySpecialsWithinSeasons": "أظهر الحلقات الخاصة في المواسم التي بثت فيها", "LabelDisplaySpecialsWithinSeasons": "أظهر الحلقات الخاصة في المواسم التي بثت فيها",
"LabelDownMixAudioScale": "تعزيز الصوت عند تقليل توزيع قنوات الصوت:", "LabelDownMixAudioScale": "تعزيز الصوت عند تقليل توزيع قنوات الصوت:",
@ -436,7 +419,6 @@
"LabelPostProcessorArguments": "معطيات سطر الأوامر لتطبيق ما بعد المعالجة", "LabelPostProcessorArguments": "معطيات سطر الأوامر لتطبيق ما بعد المعالجة",
"LabelPostProcessorArgumentsHelp": "استخدم المسار: {path} كمسار لملف التسجيل.", "LabelPostProcessorArgumentsHelp": "استخدم المسار: {path} كمسار لملف التسجيل.",
"LabelPreferredDisplayLanguage": "لغة الواجهة المفضلة:", "LabelPreferredDisplayLanguage": "لغة الواجهة المفضلة:",
"LabelPreferredDisplayLanguageHelp": "إن ترجمة أمبي هو مشروع جاري التنفيذ.",
"LabelProfileAudioCodecs": "كودك تشفير الصوت", "LabelProfileAudioCodecs": "كودك تشفير الصوت",
"LabelProfileCodecs": "الكودكات:", "LabelProfileCodecs": "الكودكات:",
"LabelProfileCodecsHelp": "يجب فصل العناصر بفواصل (,). يمكن أن تترك هذه فارغة إذا أريد تطبيقها على كل الكودكات.", "LabelProfileCodecsHelp": "يجب فصل العناصر بفواصل (,). يمكن أن تترك هذه فارغة إذا أريد تطبيقها على كل الكودكات.",
@ -484,12 +466,9 @@
"LabelTag": "البطاقة:", "LabelTag": "البطاقة:",
"LabelTime": "الوقت:", "LabelTime": "الوقت:",
"LabelTimeLimitHours": "الوقت المحدد (بالساعة):", "LabelTimeLimitHours": "الوقت المحدد (بالساعة):",
"LabelTranscodingAudioCodec": "كودك تشفير الصوت:",
"LabelTranscodingContainer": "الحاوية:",
"LabelTranscodingTempPathHelp": "هذا المجلد يحتوي على ملفات قيد الاستعمال من قبل المشفر البيني. حدد مساراً مخصوصاً او اتركه فارغاً لاستعمال القيمة الافتراضية في مجلد بيانات الخادم.", "LabelTranscodingTempPathHelp": "هذا المجلد يحتوي على ملفات قيد الاستعمال من قبل المشفر البيني. حدد مساراً مخصوصاً او اتركه فارغاً لاستعمال القيمة الافتراضية في مجلد بيانات الخادم.",
"LabelTranscodingThreadCount": "عدد مسارات التشفير البيني", "LabelTranscodingThreadCount": "عدد مسارات التشفير البيني",
"LabelTranscodingThreadCountHelp": "إختر الحد الأقصى المسموح به من مسارات التشفير البيني. إن تقليل عدد المسارات سيقلل من نسبة استخدام المعالج لكنه قد لا يحوّل الوسيطة بالسرعة المطلوبة لتشغيل سلس.", "LabelTranscodingThreadCountHelp": "إختر الحد الأقصى المسموح به من مسارات التشفير البيني. إن تقليل عدد المسارات سيقلل من نسبة استخدام المعالج لكنه قد لا يحوّل الوسيطة بالسرعة المطلوبة لتشغيل سلس.",
"LabelTranscodingVideoCodec": "كودك تشفير الفيديو:",
"LabelTriggerType": "نوع الزناد:", "LabelTriggerType": "نوع الزناد:",
"LabelTunerIpAddress": "عنوان آي بي المولف:", "LabelTunerIpAddress": "عنوان آي بي المولف:",
"LabelTunerType": "نوع المولف:", "LabelTunerType": "نوع المولف:",
@ -573,7 +552,6 @@
"MessagePluginConfigurationRequiresLocalAccess": "لضبط", "MessagePluginConfigurationRequiresLocalAccess": "لضبط",
"MessagePluginInstallDisclaimer": "إن الملحقات التي بناها أعضاء مجتمع أمبي لهي طريقة رائعة لتحسين متعة استخدام أمبي وذلك بإضافة المزايا والخدمات الجديدة. قبل تثبيت الملحقات، نرجو أخذ العلم بالآثار التي قد تلحقها بخادم أمبي الخاص بك، مثل أوقات أطولة لتمشيط مكتبتك، والعمليات الخلفية الإضافية وتقليل استقرار نظامك.", "MessagePluginInstallDisclaimer": "إن الملحقات التي بناها أعضاء مجتمع أمبي لهي طريقة رائعة لتحسين متعة استخدام أمبي وذلك بإضافة المزايا والخدمات الجديدة. قبل تثبيت الملحقات، نرجو أخذ العلم بالآثار التي قد تلحقها بخادم أمبي الخاص بك، مثل أوقات أطولة لتمشيط مكتبتك، والعمليات الخلفية الإضافية وتقليل استقرار نظامك.",
"MessageReenableUser": "أنظر أدناه لإعادة التفعيل", "MessageReenableUser": "أنظر أدناه لإعادة التفعيل",
"MessageSettingsSaved": "تم حفظ الإعدادات.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "مكان الوسائط التالي سيزال من مكتبة أمبي الخاصة بك:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "مكان الوسائط التالي سيزال من مكتبة أمبي الخاصة بك:",
"MessageUnableToConnectToServer": "لم نستطع الاتصال إلى الخادم المختار في الوقت الحالي. الرجاء التأكد من أنه يعمل ثم المحاولة مرة أخرى.", "MessageUnableToConnectToServer": "لم نستطع الاتصال إلى الخادم المختار في الوقت الحالي. الرجاء التأكد من أنه يعمل ثم المحاولة مرة أخرى.",
"MessageUnsetContentHelp": "المحتوى سيعرض كمجدات اعتيادية. لأفضل النتائج استخدم مدير واصفات البيانات لإعداد نوع محتوى المجلدات الفرعية.", "MessageUnsetContentHelp": "المحتوى سيعرض كمجدات اعتيادية. لأفضل النتائج استخدم مدير واصفات البيانات لإعداد نوع محتوى المجلدات الفرعية.",
@ -611,7 +589,6 @@
"OptionArtist": "الفنان", "OptionArtist": "الفنان",
"OptionAscending": "تصاعدي", "OptionAscending": "تصاعدي",
"OptionAuto": "آلي", "OptionAuto": "آلي",
"OptionAutomatic": "الآلي",
"OptionAutomaticallyGroupSeries": "إدمج الحلقات الموزعة بين عدة مجلدات إلى مجلد واحد تلقائياً.", "OptionAutomaticallyGroupSeries": "إدمج الحلقات الموزعة بين عدة مجلدات إلى مجلد واحد تلقائياً.",
"OptionAutomaticallyGroupSeriesHelp": "في حال التفعيل فإن الحلقات الموزعة بين عدة مجلدات ستدمج تلقائياً في مجلد مسلسل واحد.", "OptionAutomaticallyGroupSeriesHelp": "في حال التفعيل فإن الحلقات الموزعة بين عدة مجلدات ستدمج تلقائياً في مجلد مسلسل واحد.",
"OptionBlockBooks": "الكتب", "OptionBlockBooks": "الكتب",
@ -749,18 +726,14 @@
"SystemDlnaProfilesHelp": "عرائض النظام تكون مقفلة للقراءة-فقط. وأي تغيير على عريضة من عرائض النظام ستحفظ إلى عريضة مخصوصة جديدة.", "SystemDlnaProfilesHelp": "عرائض النظام تكون مقفلة للقراءة-فقط. وأي تغيير على عريضة من عرائض النظام ستحفظ إلى عريضة مخصوصة جديدة.",
"TabAccess": "الدخول", "TabAccess": "الدخول",
"TabAdvanced": "متقدم", "TabAdvanced": "متقدم",
"TabAlbumArtists": "فنانو الألبومات",
"TabCatalog": "الكتالوج", "TabCatalog": "الكتالوج",
"TabCodecs": "الكودكات", "TabCodecs": "الكودكات",
"TabContainers": "الحاويات", "TabContainers": "الحاويات",
"TabDashboard": "لوحة العدادات", "TabDashboard": "لوحة العدادات",
"TabDirectPlay": "تشغيل مباشر", "TabDirectPlay": "تشغيل مباشر",
"TabEpisodes": "الحلقات",
"TabInfo": "معلومات",
"TabLatest": "الاخير", "TabLatest": "الاخير",
"TabLogs": "الكشوفات", "TabLogs": "الكشوفات",
"TabMusic": "الموسيقى", "TabMusic": "الموسيقى",
"TabMusicVideos": "الفيديوهات الموسيقية",
"TabMyPlugins": "ملحقاتي", "TabMyPlugins": "ملحقاتي",
"TabNetworks": "الشبكات", "TabNetworks": "الشبكات",
"TabNfoSettings": "أعدادات Nfo", "TabNfoSettings": "أعدادات Nfo",
@ -771,12 +744,10 @@
"TabProfile": "عريضة", "TabProfile": "عريضة",
"TabProfiles": "الحسابات", "TabProfiles": "الحسابات",
"TabResponses": "الردود", "TabResponses": "الردود",
"TabResumeSettings": "استئناف الإعدادات",
"TabScheduledTasks": "المهام المجدولة", "TabScheduledTasks": "المهام المجدولة",
"TabServer": "الخادم", "TabServer": "الخادم",
"TabSettings": "الإعدادات", "TabSettings": "الإعدادات",
"TabStreaming": "التشغيل التدفقي", "TabStreaming": "التشغيل التدفقي",
"TabTrailers": "العروض الإعلانية",
"TabUpcoming": "القادم", "TabUpcoming": "القادم",
"TellUsAboutYourself": "اخبرنا عن نفسك", "TellUsAboutYourself": "اخبرنا عن نفسك",
"ThisWizardWillGuideYou": "مرشد الاعدادات سيساعدك خلال خطوات عملية الاعدادات. للبدء، الرجاء اختيار لغتك المفضلة.", "ThisWizardWillGuideYou": "مرشد الاعدادات سيساعدك خلال خطوات عملية الاعدادات. للبدء، الرجاء اختيار لغتك المفضلة.",
@ -1001,7 +972,6 @@
"HeaderKeepRecording": "استمر في التسجيل", "HeaderKeepRecording": "استمر في التسجيل",
"HeaderIdentifyItemHelp": "أدخل معيار بحث واحد أو أكثر. إزالة المعايير لزيادة نتائج البحث.", "HeaderIdentifyItemHelp": "أدخل معيار بحث واحد أو أكثر. إزالة المعايير لزيادة نتائج البحث.",
"HeaderHttpsSettings": "إعدادات HTTPS", "HeaderHttpsSettings": "إعدادات HTTPS",
"HeaderHome": "الصفحة الرئيسية",
"HeaderFetcherSettings": "إعدادات الجلب", "HeaderFetcherSettings": "إعدادات الجلب",
"HeaderFavoritePlaylists": "قوائم التشغيل المفضلة", "HeaderFavoritePlaylists": "قوائم التشغيل المفضلة",
"HeaderFavoriteVideos": "مقاطع الفيديو المفضلة", "HeaderFavoriteVideos": "مقاطع الفيديو المفضلة",
@ -1044,9 +1014,7 @@
"ErrorDeletingItem": "حدث خطأ في حذف العنصر من سيرفر Jellyfin. يرجى التحقق من أن سيرفر Jellyfin لديه حق الوصول للكتابة إلى مجلد الوسائط وحاول مرة أخرى.", "ErrorDeletingItem": "حدث خطأ في حذف العنصر من سيرفر Jellyfin. يرجى التحقق من أن سيرفر Jellyfin لديه حق الوصول للكتابة إلى مجلد الوسائط وحاول مرة أخرى.",
"Episode": "حلقة", "Episode": "حلقة",
"EnableThemeVideosHelp": "قم بتشغيل الفيديوهات الرئيسية في الخلفية أثناء تصفح المكتبة.", "EnableThemeVideosHelp": "قم بتشغيل الفيديوهات الرئيسية في الخلفية أثناء تصفح المكتبة.",
"EnableThemeVideos": "الفيديوهات الرئيسية",
"EnableThemeSongsHelp": "قم بتشغيل اللحن الرئيسي في الخلفية أثناء تصفح المكتبة.", "EnableThemeSongsHelp": "قم بتشغيل اللحن الرئيسي في الخلفية أثناء تصفح المكتبة.",
"EnableThemeSongs": "اللحن الرئيسي",
"EnableStreamLoopingHelp": "قم بتمكين هذا إذا كانت عمليات البث المباشر تحتوي فقط على بضع ثوان من البيانات وتحتاج إلى إعادة طلب مستمر. قد يؤدي تمكين هذا عندما لا تكون هناك حاجة إلى مشاكل.", "EnableStreamLoopingHelp": "قم بتمكين هذا إذا كانت عمليات البث المباشر تحتوي فقط على بضع ثوان من البيانات وتحتاج إلى إعادة طلب مستمر. قد يؤدي تمكين هذا عندما لا تكون هناك حاجة إلى مشاكل.",
"EnableStreamLooping": "تكرار البث المباشر", "EnableStreamLooping": "تكرار البث المباشر",
"EnableHardwareEncoding": "تمكين تشفير الأجهزة", "EnableHardwareEncoding": "تمكين تشفير الأجهزة",
@ -1099,7 +1067,6 @@
"LabelAudioChannels": "قنوات الصوت:", "LabelAudioChannels": "قنوات الصوت:",
"LabelAudioBitrate": "معدل بث الصوت:", "LabelAudioBitrate": "معدل بث الصوت:",
"LabelAudioBitDepth": "عمق بث الصوت:", "LabelAudioBitDepth": "عمق بث الصوت:",
"LabelAudio": "الصوت",
"LabelAllowedRemoteAddressesMode": "وضع مرشح عنوان المضيف IP البعيد:", "LabelAllowedRemoteAddressesMode": "وضع مرشح عنوان المضيف IP البعيد:",
"LabelAllowedRemoteAddresses": "مرشح عنوان المضيف IP البعيد:", "LabelAllowedRemoteAddresses": "مرشح عنوان المضيف IP البعيد:",
"LabelAirsBeforeSeason": "عروض بث قبل الموسم:", "LabelAirsBeforeSeason": "عروض بث قبل الموسم:",

View file

@ -3,7 +3,6 @@
"ButtonOk": "ОК", "ButtonOk": "ОК",
"ButtonQuickStartGuide": "Кіраўніцтва па запуску", "ButtonQuickStartGuide": "Кіраўніцтва па запуску",
"ButtonSignOut": "Sign out", "ButtonSignOut": "Sign out",
"HeaderAddUser": "Даданне карыстальніка",
"HeaderEasyPinCode": "Просты PIN-код", "HeaderEasyPinCode": "Просты PIN-код",
"HeaderPaths": "Шляхі", "HeaderPaths": "Шляхі",
"HeaderTaskTriggers": "Трыгеры задачы", "HeaderTaskTriggers": "Трыгеры задачы",

View file

@ -28,28 +28,21 @@
"ButtonAudioTracks": "Звукови пътеки", "ButtonAudioTracks": "Звукови пътеки",
"ButtonBack": "Назад", "ButtonBack": "Назад",
"ButtonCancel": "Отмяна", "ButtonCancel": "Отмяна",
"ButtonEdit": "Редактиране",
"ButtonEditImages": "Редактиране на изображенията",
"ButtonFilter": "Филтър",
"ButtonForgotPassword": "Забравена парола", "ButtonForgotPassword": "Забравена парола",
"ButtonGotIt": "Добре", "ButtonGotIt": "Добре",
"ButtonGuide": "Справочник", "ButtonGuide": "Справочник",
"ButtonHome": "Начало",
"ButtonInfo": "Сведения", "ButtonInfo": "Сведения",
"ButtonLibraryAccess": "Достъп до библиотеката", "ButtonLibraryAccess": "Достъп до библиотеката",
"ButtonManualLogin": "Вход с име и парола", "ButtonManualLogin": "Вход с име и парола",
"ButtonMore": "Още", "ButtonMore": "Още",
"ButtonNextTrack": "Следваща пътека", "ButtonNextTrack": "Следваща пътека",
"ButtonOff": "Изключено",
"ButtonOk": "Добре", "ButtonOk": "Добре",
"ButtonOpen": "Отваряне", "ButtonOpen": "Отваряне",
"ButtonParentalControl": "Родителски контрол", "ButtonParentalControl": "Родителски контрол",
"ButtonPause": "Пауза", "ButtonPause": "Пауза",
"ButtonPlay": "Пускане",
"ButtonPreviousTrack": "Предишна пътека", "ButtonPreviousTrack": "Предишна пътека",
"ButtonProfile": "Профил", "ButtonProfile": "Профил",
"ButtonQuickStartGuide": "Първи стъпки", "ButtonQuickStartGuide": "Първи стъпки",
"ButtonRefresh": "Опресняване",
"ButtonRefreshGuideData": "Обновяване на данните в справочника", "ButtonRefreshGuideData": "Обновяване на данните в справочника",
"ButtonRemove": "Премахване", "ButtonRemove": "Премахване",
"ButtonRename": "Преименуване", "ButtonRename": "Преименуване",
@ -65,7 +58,6 @@
"ButtonSignOut": "Отписване", "ButtonSignOut": "Отписване",
"ButtonStop": "Спиране", "ButtonStop": "Спиране",
"ButtonSubmit": "Подаване", "ButtonSubmit": "Подаване",
"ButtonSubtitles": "Субтитри",
"ButtonUninstall": "Деинсталиране", "ButtonUninstall": "Деинсталиране",
"ButtonWebsite": "Сайт", "ButtonWebsite": "Сайт",
"ChannelAccessHelp": "Изберете каналите, които да споделите с потребителя. Администраторите ще могат да редактират всички канали, използвайки управлението на метаданни.", "ChannelAccessHelp": "Изберете каналите, които да споделите с потребителя. Администраторите ще могат да редактират всички канали, използвайки управлението на метаданни.",
@ -98,7 +90,6 @@
"EditMetadata": "Редактиране на метаданните", "EditMetadata": "Редактиране на метаданните",
"EditSubtitles": "Редактиране на субтитрите", "EditSubtitles": "Редактиране на субтитрите",
"EnableCinemaMode": "Режим \"Киносалон\"", "EnableCinemaMode": "Режим \"Киносалон\"",
"EnableThemeSongs": "Тематични песни",
"Ended": "Приключило", "Ended": "Приключило",
"EndsAtValue": "Свършва на {0}", "EndsAtValue": "Свършва на {0}",
"Episodes": "Епизоди", "Episodes": "Епизоди",
@ -130,11 +121,9 @@
"HeaderActiveDevices": "Активни устройства", "HeaderActiveDevices": "Активни устройства",
"HeaderActiveRecordings": "Активни записи", "HeaderActiveRecordings": "Активни записи",
"HeaderActivity": "Дейност", "HeaderActivity": "Дейност",
"HeaderAddScheduledTaskTrigger": "Добавяне на спусък",
"HeaderAddToCollection": "Добавяне към колекция", "HeaderAddToCollection": "Добавяне към колекция",
"HeaderAddToPlaylist": "Добавяне към списък", "HeaderAddToPlaylist": "Добавяне към списък",
"HeaderAddUpdateImage": "Добавяне/редактиране на изображение", "HeaderAddUpdateImage": "Добавяне/редактиране на изображение",
"HeaderAddUser": "+ Потребител",
"HeaderAdditionalParts": "Допълнителни части", "HeaderAdditionalParts": "Допълнителни части",
"HeaderAdmin": "Администриране", "HeaderAdmin": "Администриране",
"HeaderAlbumArtists": "Изпълнители на албуми", "HeaderAlbumArtists": "Изпълнители на албуми",
@ -142,9 +131,7 @@
"HeaderApiKeys": "ППИ ключове", "HeaderApiKeys": "ППИ ключове",
"HeaderApp": "Програма", "HeaderApp": "Програма",
"HeaderAudioSettings": "Настройки на звука", "HeaderAudioSettings": "Настройки на звука",
"HeaderBooks": "Книги",
"HeaderCastAndCrew": "Артисти и изпълнители", "HeaderCastAndCrew": "Артисти и изпълнители",
"HeaderCastCrew": "Артисти и изпълнители",
"HeaderCodecProfile": "Профил на кодека", "HeaderCodecProfile": "Профил на кодека",
"HeaderContainerProfile": "Профил на контейнера", "HeaderContainerProfile": "Профил на контейнера",
"HeaderContinueListening": "Продължаване на слушането", "HeaderContinueListening": "Продължаване на слушането",
@ -163,7 +150,6 @@
"HeaderFeatureAccess": "Достъп до функции", "HeaderFeatureAccess": "Достъп до функции",
"HeaderFetchImages": "Свали изображения:", "HeaderFetchImages": "Свали изображения:",
"HeaderForKids": "Детски", "HeaderForKids": "Детски",
"HeaderForgotPassword": "Забравена парола",
"HeaderFrequentlyPlayed": "Често пускани", "HeaderFrequentlyPlayed": "Често пускани",
"HeaderGuideProviders": "Доставчици на справочници", "HeaderGuideProviders": "Доставчици на справочници",
"HeaderIdentification": "Идентификация", "HeaderIdentification": "Идентификация",
@ -182,7 +168,6 @@
"HeaderLibrarySettings": "Настройки на библиотеката", "HeaderLibrarySettings": "Настройки на библиотеката",
"HeaderMedia": "Медия", "HeaderMedia": "Медия",
"HeaderMediaFolders": "Медийни папки", "HeaderMediaFolders": "Медийни папки",
"HeaderMediaInfo": "Сведения",
"HeaderMetadataSettings": "Настройки на метаданните", "HeaderMetadataSettings": "Настройки на метаданните",
"HeaderMoreLikeThis": "Подобни", "HeaderMoreLikeThis": "Подобни",
"HeaderMusicQuality": "Качество на музиката", "HeaderMusicQuality": "Качество на музиката",
@ -271,7 +256,6 @@
"LabelCustomCertificatePathHelp": "Път до файл с шифровъчен стандарт №12 (PKCS #12), съдържащ сертификат и частен ключ за поддръжка на протокол TLS на собствен домейн.", "LabelCustomCertificatePathHelp": "Път до файл с шифровъчен стандарт №12 (PKCS #12), съдържащ сертификат и частен ключ за поддръжка на протокол TLS на собствен домейн.",
"LabelCustomCss": "CSS по избор:", "LabelCustomCss": "CSS по избор:",
"LabelCustomCssHelp": "Добавете собствен стил към уеб-интерфейса.", "LabelCustomCssHelp": "Добавете собствен стил към уеб-интерфейса.",
"LabelCustomDeviceDisplayName": "Показвано име:",
"LabelCustomRating": "Оценка по избор:", "LabelCustomRating": "Оценка по избор:",
"LabelDateAdded": "Дата на добавяне:", "LabelDateAdded": "Дата на добавяне:",
"LabelDateTimeLocale": "Местоположение за дата и час:", "LabelDateTimeLocale": "Местоположение за дата и час:",
@ -279,7 +263,6 @@
"LabelDeviceDescription": "Описание на устройството", "LabelDeviceDescription": "Описание на устройството",
"LabelDisplayLanguage": "Език на показване:", "LabelDisplayLanguage": "Език на показване:",
"LabelDisplayLanguageHelp": "Превеждането на Емби е текущ проект.", "LabelDisplayLanguageHelp": "Превеждането на Емби е текущ проект.",
"LabelDisplayMissingEpisodesWithinSeasons": "Показване на липсващите епизоди в сезоните",
"LabelDisplayMode": "Режим на показване:", "LabelDisplayMode": "Режим на показване:",
"LabelDisplayName": "Показвано име:", "LabelDisplayName": "Показвано име:",
"LabelDisplayOrder": "Ред на показване:", "LabelDisplayOrder": "Ред на показване:",
@ -361,7 +344,6 @@
"LabelPlayDefaultAudioTrack": "Да се пуска първоначалната звукова пътечка независимо от езика", "LabelPlayDefaultAudioTrack": "Да се пуска първоначалната звукова пътечка независимо от езика",
"LabelPlaylist": "Списък:", "LabelPlaylist": "Списък:",
"LabelPreferredDisplayLanguage": "Предпочитан език на показване:", "LabelPreferredDisplayLanguage": "Предпочитан език на показване:",
"LabelPreferredDisplayLanguageHelp": "Превеждането на Емби е текущ проект.",
"LabelPreferredSubtitleLanguage": "Предпочитан език на субтитрите:", "LabelPreferredSubtitleLanguage": "Предпочитан език на субтитрите:",
"LabelProfileAudioCodecs": "Звукови кодеци:", "LabelProfileAudioCodecs": "Звукови кодеци:",
"LabelProfileCodecs": "Кодеци:", "LabelProfileCodecs": "Кодеци:",
@ -394,7 +376,6 @@
"LabelStatus": "Състояние:", "LabelStatus": "Състояние:",
"LabelStopWhenPossible": "Спирай, когато е възможно:", "LabelStopWhenPossible": "Спирай, когато е възможно:",
"LabelSubtitlePlaybackMode": "Режим на субтитрите:", "LabelSubtitlePlaybackMode": "Режим на субтитрите:",
"LabelSubtitles": "Субтитри",
"LabelSupportedMediaTypes": "Поддържани типове медия:", "LabelSupportedMediaTypes": "Поддържани типове медия:",
"LabelTag": "Етикет:", "LabelTag": "Етикет:",
"LabelTextColor": "Цвят на текста:", "LabelTextColor": "Цвят на текста:",
@ -403,9 +384,7 @@
"LabelTime": "Време:", "LabelTime": "Време:",
"LabelTimeLimitHours": "Времево ограничение (часове):", "LabelTimeLimitHours": "Времево ограничение (часове):",
"LabelTitle": "Заглавие:", "LabelTitle": "Заглавие:",
"LabelTranscodingAudioCodec": "Звуков кодек:",
"LabelTranscodingTempPathHelp": "Посочете персонализиран път за файлове,които е необходимо да бъдат транскодирани и доставени на клиентите. Оставете празно ,за да се използва мястото по подразбиране.", "LabelTranscodingTempPathHelp": "Посочете персонализиран път за файлове,които е необходимо да бъдат транскодирани и доставени на клиентите. Оставете празно ,за да се използва мястото по подразбиране.",
"LabelTranscodingVideoCodec": "Видеокодек:",
"LabelTriggerType": "Тип на спусъка:", "LabelTriggerType": "Тип на спусъка:",
"LabelType": "Вид:", "LabelType": "Вид:",
"LabelTypeText": "Текст", "LabelTypeText": "Текст",
@ -448,7 +427,6 @@
"MessageNoPluginsInstalled": "Нямате инсталирани приставки.", "MessageNoPluginsInstalled": "Нямате инсталирани приставки.",
"MessageNothingHere": "Тук няма нищо.", "MessageNothingHere": "Тук няма нищо.",
"MessagePleaseEnsureInternetMetadata": "Моля, уверете се че свалянето на метаданни от интернет е разрешено.", "MessagePleaseEnsureInternetMetadata": "Моля, уверете се че свалянето на метаданни от интернет е разрешено.",
"MessageSettingsSaved": "Настройките са запазени.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Следните местоположения ще бъдат премахнати от библиотеката ви:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Следните местоположения ще бъдат премахнати от библиотеката ви:",
"MessageYouHaveVersionInstalled": "В момента имате инсталирана версия {0}.", "MessageYouHaveVersionInstalled": "В момента имате инсталирана версия {0}.",
"MetadataManager": "Управление на метаданните", "MetadataManager": "Управление на метаданните",
@ -490,7 +468,6 @@
"OptionArtist": "Изпълнител", "OptionArtist": "Изпълнител",
"OptionAscending": "Възходящо", "OptionAscending": "Възходящо",
"OptionAuto": "Автоматично", "OptionAuto": "Автоматично",
"OptionAutomatic": "Автоматично",
"OptionBlockBooks": "Книги", "OptionBlockBooks": "Книги",
"OptionBlockMovies": "Филми", "OptionBlockMovies": "Филми",
"OptionBlockTvShows": "Телевизионни сериали", "OptionBlockTvShows": "Телевизионни сериали",
@ -634,18 +611,14 @@
"TV": "Телевизор", "TV": "Телевизор",
"TabAccess": "Достъп", "TabAccess": "Достъп",
"TabAdvanced": "Допълнителни", "TabAdvanced": "Допълнителни",
"TabAlbumArtists": "Изпълнители на албуми",
"TabCatalog": "Каталог", "TabCatalog": "Каталог",
"TabCodecs": "Кодеци", "TabCodecs": "Кодеци",
"TabContainers": "Контейнери", "TabContainers": "Контейнери",
"TabDashboard": "Табло", "TabDashboard": "Табло",
"TabDirectPlay": "Директно пускане", "TabDirectPlay": "Директно пускане",
"TabEpisodes": "Епизоди",
"TabInfo": "Информация",
"TabLatest": "Последни", "TabLatest": "Последни",
"TabLogs": "Журнали", "TabLogs": "Журнали",
"TabMusic": "Музика", "TabMusic": "Музика",
"TabMusicVideos": "Музикални клипове",
"TabMyPlugins": "Моите приставки", "TabMyPlugins": "Моите приставки",
"TabNetworks": "Мрежи", "TabNetworks": "Мрежи",
"TabNfoSettings": "Формат за метаданни NFO", "TabNfoSettings": "Формат за метаданни NFO",
@ -656,12 +629,10 @@
"TabProfile": "Профил", "TabProfile": "Профил",
"TabProfiles": "Профили", "TabProfiles": "Профили",
"TabResponses": "Отговори", "TabResponses": "Отговори",
"TabResumeSettings": "Възобнови",
"TabScheduledTasks": "Планирани задачи", "TabScheduledTasks": "Планирани задачи",
"TabServer": "Сървър", "TabServer": "Сървър",
"TabSettings": "Настройки", "TabSettings": "Настройки",
"TabStreaming": "Излъчване", "TabStreaming": "Излъчване",
"TabTrailers": "Трейлъри",
"TabUpcoming": "Предстоящи", "TabUpcoming": "Предстоящи",
"Tags": "Етикети", "Tags": "Етикети",
"TagsValue": "Етикети: {0}", "TagsValue": "Етикети: {0}",
@ -833,7 +804,6 @@
"EnableDetailsBannerHelp": "Покажи картинка с банер в горната част на страницата с детайли.", "EnableDetailsBannerHelp": "Покажи картинка с банер в горната част на страницата с детайли.",
"EnableDetailsBanner": "Банер с подробности", "EnableDetailsBanner": "Банер с подробности",
"EnableThemeVideosHelp": "Пускай тематични видеа на заден план ,докато се разглежда библиотеката.", "EnableThemeVideosHelp": "Пускай тематични видеа на заден план ,докато се разглежда библиотеката.",
"EnableThemeVideos": "Тематични видеа",
"EnableThemeSongsHelp": "Пускай тематична музика ,докато се разглежда библиотеката.", "EnableThemeSongsHelp": "Пускай тематична музика ,докато се разглежда библиотеката.",
"EnableStreamLoopingHelp": "Включи това ,ако поточното видео се предава на кратки интервали и е необходимо да се изпращат заявки постоянно.Включването на тази опция без нужда може да породи проблеми.", "EnableStreamLoopingHelp": "Включи това ,ако поточното видео се предава на кратки интервали и е необходимо да се изпращат заявки постоянно.Включването на тази опция без нужда може да породи проблеми.",
"EnableStreamLooping": "Автоматично повторение на поточни видеа", "EnableStreamLooping": "Автоматично повторение на поточни видеа",
@ -871,7 +841,6 @@
"HeaderFavoriteMovies": "Любими филми", "HeaderFavoriteMovies": "Любими филми",
"HeaderFavoriteBooks": "Любими книги", "HeaderFavoriteBooks": "Любими книги",
"HeaderExternalIds": "Външни идентификатори:", "HeaderExternalIds": "Външни идентификатори:",
"HeaderEpisodes": "Епизоди",
"HeaderEnabledFieldsHelp": "Махни отметката ,за да го заключиш и да предотвратиш неговата промяна.", "HeaderEnabledFieldsHelp": "Махни отметката ,за да го заключиш и да предотвратиш неговата промяна.",
"HeaderDVR": "DVR (Цифрово записващо устройство)", "HeaderDVR": "DVR (Цифрово записващо устройство)",
"HeaderDirectPlayProfileHelp": "Добави профили за директно възпроизвеждане ,за да се укаже кои формати може да възпроизвежда устройството.", "HeaderDirectPlayProfileHelp": "Добави профили за директно възпроизвеждане ,за да се укаже кои формати може да възпроизвежда устройството.",
@ -970,7 +939,6 @@
"HeaderIdentificationCriteriaHelp": "Въведете пони един критерии.", "HeaderIdentificationCriteriaHelp": "Въведете пони един критерии.",
"HeaderHttpsSettings": "HTTPS настройки", "HeaderHttpsSettings": "HTTPS настройки",
"HeaderHttpHeaders": "HTTP Хедъри", "HeaderHttpHeaders": "HTTP Хедъри",
"HeaderHome": "Главна",
"HeaderFetcherSettings": "Настройки на програмата за изтегляне", "HeaderFetcherSettings": "Настройки на програмата за изтегляне",
"HeaderFavoritePlaylists": "Любими списъци", "HeaderFavoritePlaylists": "Любими списъци",
"LabelDeathDate": "Дата на смърт:", "LabelDeathDate": "Дата на смърт:",
@ -996,7 +964,6 @@
"LabelAudioChannels": "Аудио канали:", "LabelAudioChannels": "Аудио канали:",
"LabelAudioBitrate": "Скорост на предаване на аудиото:", "LabelAudioBitrate": "Скорост на предаване на аудиото:",
"LabelAudioBitDepth": "Битова дълбочина на аудиото:", "LabelAudioBitDepth": "Битова дълбочина на аудиото:",
"LabelAudio": "Аудио",
"LabelAppNameExample": "Примерно: Sickbeard, Sonarr", "LabelAppNameExample": "Примерно: Sickbeard, Sonarr",
"LabelAllowedRemoteAddressesMode": "Режим на филтъра за външни ИП адреси:", "LabelAllowedRemoteAddressesMode": "Режим на филтъра за външни ИП адреси:",
"LabelAllowedRemoteAddresses": "Филтър за външни ИП адреси:", "LabelAllowedRemoteAddresses": "Филтър за външни ИП адреси:",
@ -1176,7 +1143,6 @@
"LabelTranscodingFramerate": "Честота на кадрите при транскодиране:", "LabelTranscodingFramerate": "Честота на кадрите при транскодиране:",
"LabelTranscodes": "Транскодирания:", "LabelTranscodes": "Транскодирания:",
"LabelTranscodePath": "Път за транскодиране:", "LabelTranscodePath": "Път за транскодиране:",
"LabelTranscodingContainer": "Контейнер:",
"LabelTrackNumber": "Номер на песен:", "LabelTrackNumber": "Номер на песен:",
"LabelTextBackgroundColor": "Цвят на фона на текста:", "LabelTextBackgroundColor": "Цвят на фона на текста:",
"LabelTagline": "Ключова фраза:", "LabelTagline": "Ключова фраза:",

View file

@ -17,26 +17,20 @@
"AddToPlaylist": "প্লেলিস্টে অ্যাড করুন", "AddToPlaylist": "প্লেলিস্টে অ্যাড করুন",
"AddToPlayQueue": "প্লে কিউ তে অ্যাড করুন", "AddToPlayQueue": "প্লে কিউ তে অ্যাড করুন",
"AddToCollection": "কালেকশন এ অ্যাড করুন", "AddToCollection": "কালেকশন এ অ্যাড করুন",
"ButtonPlay": "চালান",
"ButtonPause": "বিরতি", "ButtonPause": "বিরতি",
"ButtonParentalControl": "অভিভাবকীয় নিয়ন্ত্রণ", "ButtonParentalControl": "অভিভাবকীয় নিয়ন্ত্রণ",
"ButtonOpen": "খুলুন", "ButtonOpen": "খুলুন",
"ButtonOk": "আচ্ছা", "ButtonOk": "আচ্ছা",
"ButtonOff": "বন্ধ",
"ButtonNextTrack": "পরবর্তী ট্র্যাক", "ButtonNextTrack": "পরবর্তী ট্র্যাক",
"ButtonNetwork": "নেটওয়ার্ক", "ButtonNetwork": "নেটওয়ার্ক",
"ButtonMore": "আরও", "ButtonMore": "আরও",
"ButtonLibraryAccess": "লাইব্রেরি অ্যাক্সেস", "ButtonLibraryAccess": "লাইব্রেরি অ্যাক্সেস",
"ButtonInfo": "তথ্য", "ButtonInfo": "তথ্য",
"ButtonHome": "হোম",
"ButtonGuide": "গাইড", "ButtonGuide": "গাইড",
"ButtonGotIt": "বুঝেছি", "ButtonGotIt": "বুঝেছি",
"ButtonFullscreen": "ফুলস্ক্রিন", "ButtonFullscreen": "ফুলস্ক্রিন",
"ButtonForgotPassword": "পাসওয়ার্ড ভুলে গেছি", "ButtonForgotPassword": "পাসওয়ার্ড ভুলে গেছি",
"ButtonFilter": "ফিলটার",
"ButtonEditOtherUserPreferences": "এই ব্যবহারকারীর প্রোফাইল, ছবি এবং ব্যক্তিগত পছন্দগুলি এডিট করুন।", "ButtonEditOtherUserPreferences": "এই ব্যবহারকারীর প্রোফাইল, ছবি এবং ব্যক্তিগত পছন্দগুলি এডিট করুন।",
"ButtonEditImages": "ছবিগুলি এডিট করুন",
"ButtonEdit": "এডিট করুন",
"ButtonChangeServer": "সার্ভার পরিবর্তন করুন", "ButtonChangeServer": "সার্ভার পরিবর্তন করুন",
"ButtonCancel": "বাতিল", "ButtonCancel": "বাতিল",
"ButtonBack": "অনগ্রসর", "ButtonBack": "অনগ্রসর",
@ -91,7 +85,6 @@
"ButtonRename": "নামান্তর", "ButtonRename": "নামান্তর",
"ButtonRemove": "সরান", "ButtonRemove": "সরান",
"ButtonRefreshGuideData": "গাইড ডেটা রিফ্রেশ করুন", "ButtonRefreshGuideData": "গাইড ডেটা রিফ্রেশ করুন",
"ButtonRefresh": "রিফ্রেশ",
"ButtonQuickStartGuide": "দ্রুত শুরু করার নির্দেশাবলী", "ButtonQuickStartGuide": "দ্রুত শুরু করার নির্দেশাবলী",
"CopyStreamURL": "স্ট্রিম ইউআরএল কপি", "CopyStreamURL": "স্ট্রিম ইউআরএল কপি",
"ContinueWatching": "দেখা অব্যাহত রাখুন", "ContinueWatching": "দেখা অব্যাহত রাখুন",

View file

@ -23,14 +23,10 @@
"ButtonBack": "Darrera", "ButtonBack": "Darrera",
"ButtonCancel": "Cancel·la", "ButtonCancel": "Cancel·la",
"ButtonChangeServer": "Canvia Servidor", "ButtonChangeServer": "Canvia Servidor",
"ButtonEdit": "Edita",
"ButtonEditImages": "Edita les imatges",
"ButtonEditOtherUserPreferences": "Edita el perfil, la imatge i les preferències d'aquest usuari.", "ButtonEditOtherUserPreferences": "Edita el perfil, la imatge i les preferències d'aquest usuari.",
"ButtonFilter": "Filtra",
"ButtonForgotPassword": "He oblidat la contrasenya", "ButtonForgotPassword": "He oblidat la contrasenya",
"ButtonGotIt": "Entesos", "ButtonGotIt": "Entesos",
"ButtonGuide": "Guia", "ButtonGuide": "Guia",
"ButtonHome": "Inici",
"ButtonLibraryAccess": "Accés a la biblioteca", "ButtonLibraryAccess": "Accés a la biblioteca",
"ButtonManualLogin": "Inici de sessió manual", "ButtonManualLogin": "Inici de sessió manual",
"ButtonMore": "Més", "ButtonMore": "Més",
@ -39,11 +35,9 @@
"ButtonOpen": "Obre", "ButtonOpen": "Obre",
"ButtonParentalControl": "Control parental", "ButtonParentalControl": "Control parental",
"ButtonPause": "Pausa", "ButtonPause": "Pausa",
"ButtonPlay": "Reprodueix",
"ButtonPreviousTrack": "Pista anterior", "ButtonPreviousTrack": "Pista anterior",
"ButtonProfile": "Perfil", "ButtonProfile": "Perfil",
"ButtonQuickStartGuide": "Guia d'inici ràpid", "ButtonQuickStartGuide": "Guia d'inici ràpid",
"ButtonRefresh": "Refresca",
"ButtonRefreshGuideData": "Refresca les Dades de la Guia", "ButtonRefreshGuideData": "Refresca les Dades de la Guia",
"ButtonRemove": "Elimina", "ButtonRemove": "Elimina",
"ButtonResetEasyPassword": "Reinicia el codi pin senzill", "ButtonResetEasyPassword": "Reinicia el codi pin senzill",
@ -59,7 +53,6 @@
"ButtonSignOut": "Tanca sessió", "ButtonSignOut": "Tanca sessió",
"ButtonStop": "Atura", "ButtonStop": "Atura",
"ButtonSubmit": "Envia", "ButtonSubmit": "Envia",
"ButtonSubtitles": "Subtítols",
"ButtonTrailer": "Tràiler", "ButtonTrailer": "Tràiler",
"CancelRecording": "Cancel·la enregistrament", "CancelRecording": "Cancel·la enregistrament",
"CancelSeries": "Cancel·la sèrie", "CancelSeries": "Cancel·la sèrie",
@ -113,22 +106,18 @@
"HeaderActiveDevices": "Dispositius Actius", "HeaderActiveDevices": "Dispositius Actius",
"HeaderActiveRecordings": "Enregistraments Actius", "HeaderActiveRecordings": "Enregistraments Actius",
"HeaderActivity": "Activitat", "HeaderActivity": "Activitat",
"HeaderAddScheduledTaskTrigger": "Afegir Disparador",
"HeaderAddToCollection": "Afegir a Col·lecció", "HeaderAddToCollection": "Afegir a Col·lecció",
"HeaderAddToPlaylist": "Afegir a la llista de reproducció", "HeaderAddToPlaylist": "Afegir a la llista de reproducció",
"HeaderAddUpdateImage": "Afegir/Actualitzar Imatge", "HeaderAddUpdateImage": "Afegir/Actualitzar Imatge",
"HeaderAddUser": "Afegir Usuari",
"HeaderAdditionalParts": "Parts addicionals", "HeaderAdditionalParts": "Parts addicionals",
"HeaderApiKey": "Clau Api", "HeaderApiKey": "Clau Api",
"HeaderApiKeys": "Claus Api", "HeaderApiKeys": "Claus Api",
"HeaderApiKeysHelp": "Les aplicacions externes requereixen una Api key pere tal de poder-se comunicar amb el Servidor d'Jellyfin. Les claus són emeses iniciant sessió amb un compte d'Jellyfin, o concedint manualment una clau a l'aplicació.", "HeaderApiKeysHelp": "Les aplicacions externes requereixen una Api key pere tal de poder-se comunicar amb el Servidor d'Jellyfin. Les claus són emeses iniciant sessió amb un compte d'Jellyfin, o concedint manualment una clau a l'aplicació.",
"HeaderAudioSettings": "Preferències d'Àudio", "HeaderAudioSettings": "Preferències d'Àudio",
"HeaderBooks": "Llibres",
"HeaderBranding": "Aparença", "HeaderBranding": "Aparença",
"HeaderCancelRecording": "Cancel·lar Enregistrament", "HeaderCancelRecording": "Cancel·lar Enregistrament",
"HeaderCancelSeries": "Cancel·lar Sèries", "HeaderCancelSeries": "Cancel·lar Sèries",
"HeaderCastAndCrew": "Repartiment i Equip", "HeaderCastAndCrew": "Repartiment i Equip",
"HeaderCastCrew": "Repartiment i Equip",
"HeaderCodecProfile": "Perfil de Còdec", "HeaderCodecProfile": "Perfil de Còdec",
"HeaderConfirmProfileDeletion": "Confirmar Supressió de Perfil", "HeaderConfirmProfileDeletion": "Confirmar Supressió de Perfil",
"HeaderConnectToServer": "Connectar al Servidor", "HeaderConnectToServer": "Connectar al Servidor",
@ -151,7 +140,6 @@
"HeaderExternalIds": "Identificadors externs:", "HeaderExternalIds": "Identificadors externs:",
"HeaderFeatureAccess": "Accés a Funcions", "HeaderFeatureAccess": "Accés a Funcions",
"HeaderFetchImages": "Obtingues Imatges:", "HeaderFetchImages": "Obtingues Imatges:",
"HeaderForgotPassword": "He oblidat la contrasenya",
"HeaderFrequentlyPlayed": "Reproduït Freqüentment", "HeaderFrequentlyPlayed": "Reproduït Freqüentment",
"HeaderHttpHeaders": "Capçaleres Http", "HeaderHttpHeaders": "Capçaleres Http",
"HeaderIdentification": "Identificació", "HeaderIdentification": "Identificació",
@ -173,7 +161,6 @@
"HeaderLibraryOrder": "Ordre de la llibreria", "HeaderLibraryOrder": "Ordre de la llibreria",
"HeaderLibrarySettings": "Preferències de la Biblioteca", "HeaderLibrarySettings": "Preferències de la Biblioteca",
"HeaderMediaFolders": "Directoris Multimèdia", "HeaderMediaFolders": "Directoris Multimèdia",
"HeaderMediaInfo": "Info Multimèdia",
"HeaderMetadataSettings": "Preferències de Metadades", "HeaderMetadataSettings": "Preferències de Metadades",
"HeaderMusicVideos": "Vídeos Musicals", "HeaderMusicVideos": "Vídeos Musicals",
"HeaderMyDevice": "El meu dispositiu", "HeaderMyDevice": "El meu dispositiu",
@ -260,7 +247,6 @@
"LabelCurrentPassword": "Contrasenya actual:", "LabelCurrentPassword": "Contrasenya actual:",
"LabelCustomCss": "CSS propi:", "LabelCustomCss": "CSS propi:",
"LabelCustomCssHelp": "Aplica el teu propi css a la interfície web.", "LabelCustomCssHelp": "Aplica el teu propi css a la interfície web.",
"LabelCustomDeviceDisplayName": "Nom a mostrar:",
"LabelDateAdded": "Data afegit:", "LabelDateAdded": "Data afegit:",
"LabelDay": "Dia:", "LabelDay": "Dia:",
"LabelDeathDate": "Data de defunció:", "LabelDeathDate": "Data de defunció:",
@ -269,7 +255,6 @@
"LabelDeviceDescription": "Descripció del dispositiu", "LabelDeviceDescription": "Descripció del dispositiu",
"LabelDiscNumber": "Disc:", "LabelDiscNumber": "Disc:",
"LabelDisplayLanguage": "Idioma de visualització:", "LabelDisplayLanguage": "Idioma de visualització:",
"LabelDisplayMissingEpisodesWithinSeasons": "Mostra els episodis que manquen dins les temporades",
"LabelDisplayName": "Nom a mostrar:", "LabelDisplayName": "Nom a mostrar:",
"LabelDisplayOrder": "Ordre de visualització:", "LabelDisplayOrder": "Ordre de visualització:",
"LabelDisplaySpecialsWithinSeasons": "Mostra els especials dins les temporades en que van ser emesos", "LabelDisplaySpecialsWithinSeasons": "Mostra els especials dins les temporades en que van ser emesos",
@ -354,7 +339,6 @@
"LabelPlayDefaultAudioTrack": "Reprodueix la pista d'àudio per defecte independentment de l'idioma", "LabelPlayDefaultAudioTrack": "Reprodueix la pista d'àudio per defecte independentment de l'idioma",
"LabelPlaylist": "Llista de rep.:", "LabelPlaylist": "Llista de rep.:",
"LabelPreferredDisplayLanguage": "Idioma de visualització preferit:", "LabelPreferredDisplayLanguage": "Idioma de visualització preferit:",
"LabelPreferredDisplayLanguageHelp": "La traducció d'Jellyfin és un projecte en curs.",
"LabelPreferredSubtitleLanguage": "Idioma preferit de subtítols:", "LabelPreferredSubtitleLanguage": "Idioma preferit de subtítols:",
"LabelProfileAudioCodecs": "Còdecs d'àudio:", "LabelProfileAudioCodecs": "Còdecs d'àudio:",
"LabelProfileCodecs": "Còdecs:", "LabelProfileCodecs": "Còdecs:",
@ -390,10 +374,7 @@
"LabelTimeLimitHours": "Temps límit (en hores):", "LabelTimeLimitHours": "Temps límit (en hores):",
"LabelTitle": "Títol:", "LabelTitle": "Títol:",
"LabelTrackNumber": "Pista:", "LabelTrackNumber": "Pista:",
"LabelTranscodingAudioCodec": "Còdec d'àudio",
"LabelTranscodingContainer": "Contenidor:",
"LabelTranscodingTempPathHelp": "Aquest directori conté fitxers emprats pel transcodificador. Especifica un directori personalitzat o deixa-ho en blanc per emprar el per defecte dins el directori de dades del servidor.", "LabelTranscodingTempPathHelp": "Aquest directori conté fitxers emprats pel transcodificador. Especifica un directori personalitzat o deixa-ho en blanc per emprar el per defecte dins el directori de dades del servidor.",
"LabelTranscodingVideoCodec": "Còdec de vídeo:",
"LabelTriggerType": "Tipus de Disparador:", "LabelTriggerType": "Tipus de Disparador:",
"LabelType": "Tipus:", "LabelType": "Tipus:",
"LabelUseNotificationServices": "Empra els següents serveis:", "LabelUseNotificationServices": "Empra els següents serveis:",
@ -433,7 +414,6 @@
"MessageNoTrailersFound": "No s'han trobat tràilers. Instal·la el canal Trailer per millorar la teva experiència amb les pel·lícules afegint una llibreria de tràilers d'internet.", "MessageNoTrailersFound": "No s'han trobat tràilers. Instal·la el canal Trailer per millorar la teva experiència amb les pel·lícules afegint una llibreria de tràilers d'internet.",
"MessageNothingHere": "Res aquí.", "MessageNothingHere": "Res aquí.",
"MessagePleaseEnsureInternetMetadata": "Si et plau, assegura't que la descàrrega de metadades d'internet està habilitada.", "MessagePleaseEnsureInternetMetadata": "Si et plau, assegura't que la descàrrega de metadades d'internet està habilitada.",
"MessageSettingsSaved": "Preferències desades.",
"MessageYouHaveVersionInstalled": "Actualment tens la versió {0} instal·lada.", "MessageYouHaveVersionInstalled": "Actualment tens la versió {0} instal·lada.",
"MetadataManager": "Gestor de Metadades", "MetadataManager": "Gestor de Metadades",
"MinutesAfter": "minuts després", "MinutesAfter": "minuts després",
@ -607,11 +587,8 @@
"TabContainers": "Contenidors", "TabContainers": "Contenidors",
"TabDashboard": "Tauler de Control", "TabDashboard": "Tauler de Control",
"TabDirectPlay": "Reproducció Directa", "TabDirectPlay": "Reproducció Directa",
"TabEpisodes": "Episodis",
"TabInfo": "Informació",
"TabLatest": "Novetats", "TabLatest": "Novetats",
"TabMusic": "Música", "TabMusic": "Música",
"TabMusicVideos": "Vídeos musicals",
"TabMyPlugins": "Els meus complements", "TabMyPlugins": "Els meus complements",
"TabNetworks": "Cadenes", "TabNetworks": "Cadenes",
"TabNfoSettings": "Preferències d'Nfo", "TabNfoSettings": "Preferències d'Nfo",
@ -625,7 +602,6 @@
"TabScheduledTasks": "Tasques Programades", "TabScheduledTasks": "Tasques Programades",
"TabServer": "Servidor", "TabServer": "Servidor",
"TabSettings": "Preferències", "TabSettings": "Preferències",
"TabTrailers": "Tràilers",
"TabUpcoming": "Properament", "TabUpcoming": "Properament",
"Tags": "Etiquetes", "Tags": "Etiquetes",
"TellUsAboutYourself": "Explica'ns sobre tu", "TellUsAboutYourself": "Explica'ns sobre tu",
@ -721,7 +697,6 @@
"ChannelNameOnly": "Número de canal", "ChannelNameOnly": "Número de canal",
"ChangingMetadataImageSettingsNewContent": "Els canvis als paràmetres de descàrrega de metadades o d'obra d'art només s'apliquen al contingut nou afegit a la biblioteca. Per aplicar els canvis als títols existents, haureu de refrescar les metadades manualment.", "ChangingMetadataImageSettingsNewContent": "Els canvis als paràmetres de descàrrega de metadades o d'obra d'art només s'apliquen al contingut nou afegit a la biblioteca. Per aplicar els canvis als títols existents, haureu de refrescar les metadades manualment.",
"ButtonTogglePlaylist": "Llista de reproducció", "ButtonTogglePlaylist": "Llista de reproducció",
"ButtonOff": "Apagar",
"BurnSubtitlesHelp": "Determina si el servidor hauria de gravar els subtítols en transcodificar vídeos. Evitar això millorarà molt el rendiment. Seleccioneu Automàtica per gravar formats basats en imatges (VOBSUB, PGS, SUB, IDX) i certs subtítols ASS o SSA.", "BurnSubtitlesHelp": "Determina si el servidor hauria de gravar els subtítols en transcodificar vídeos. Evitar això millorarà molt el rendiment. Seleccioneu Automàtica per gravar formats basats en imatges (VOBSUB, PGS, SUB, IDX) i certs subtítols ASS o SSA.",
"Browse": "Navega", "Browse": "Navega",
"BoxRear": "Caixa (posterior)", "BoxRear": "Caixa (posterior)",

View file

@ -43,29 +43,22 @@
"ButtonBack": "Zpět", "ButtonBack": "Zpět",
"ButtonCancel": "Zrušit", "ButtonCancel": "Zrušit",
"ButtonChangeServer": "Změna serveru", "ButtonChangeServer": "Změna serveru",
"ButtonEdit": "Upravit",
"ButtonEditImages": "Editovat obrázky",
"ButtonEditOtherUserPreferences": "Editace uživatelského profilu, avataru a osobních preferencí.", "ButtonEditOtherUserPreferences": "Editace uživatelského profilu, avataru a osobních preferencí.",
"ButtonFilter": "Filtr",
"ButtonForgotPassword": "Zapomenuté heslo", "ButtonForgotPassword": "Zapomenuté heslo",
"ButtonFullscreen": "Celá obrazovka", "ButtonFullscreen": "Celá obrazovka",
"ButtonGotIt": "Mám to", "ButtonGotIt": "Mám to",
"ButtonGuide": "Programový průvodce", "ButtonGuide": "Programový průvodce",
"ButtonHome": "Domů",
"ButtonLibraryAccess": "Přístup ke knihovně", "ButtonLibraryAccess": "Přístup ke knihovně",
"ButtonManualLogin": "Manuální přihlášení", "ButtonManualLogin": "Manuální přihlášení",
"ButtonMore": "Více", "ButtonMore": "Více",
"ButtonNetwork": "Síť", "ButtonNetwork": "Síť",
"ButtonNextTrack": "Následující stopa", "ButtonNextTrack": "Následující stopa",
"ButtonOff": "Vypnout",
"ButtonOpen": "Otevřít", "ButtonOpen": "Otevřít",
"ButtonParentalControl": "Rodičovská kontrola", "ButtonParentalControl": "Rodičovská kontrola",
"ButtonPause": "Pozastavit", "ButtonPause": "Pozastavit",
"ButtonPlay": "Přehrát",
"ButtonPreviousTrack": "Předchozí stopa", "ButtonPreviousTrack": "Předchozí stopa",
"ButtonProfile": "Profil", "ButtonProfile": "Profil",
"ButtonQuickStartGuide": "Rychlý průvodce", "ButtonQuickStartGuide": "Rychlý průvodce",
"ButtonRefresh": "Obnovit",
"ButtonRefreshGuideData": "Obnovit data programového průvodce", "ButtonRefreshGuideData": "Obnovit data programového průvodce",
"ButtonRemove": "Odstranit", "ButtonRemove": "Odstranit",
"ButtonRename": "Přejmenovat", "ButtonRename": "Přejmenovat",
@ -83,7 +76,6 @@
"ButtonSignOut": "Odhlásit se", "ButtonSignOut": "Odhlásit se",
"ButtonStop": "Zastavit", "ButtonStop": "Zastavit",
"ButtonSubmit": "Potvrdit", "ButtonSubmit": "Potvrdit",
"ButtonSubtitles": "Titulky",
"ButtonTrailer": "Upoutávka", "ButtonTrailer": "Upoutávka",
"ButtonUninstall": "Odinstalovat", "ButtonUninstall": "Odinstalovat",
"ButtonWebsite": "Webové stránky", "ButtonWebsite": "Webové stránky",
@ -151,9 +143,7 @@
"EnableNextVideoInfoOverlay": "Zobrazit informaci o následujícím videu během přehrávání", "EnableNextVideoInfoOverlay": "Zobrazit informaci o následujícím videu během přehrávání",
"EnablePhotos": "Zobrazit fotky", "EnablePhotos": "Zobrazit fotky",
"EnablePhotosHelp": "Obrázky budou detekovány a zobrazeny spolu s dalšími multimediálními soubory.", "EnablePhotosHelp": "Obrázky budou detekovány a zobrazeny spolu s dalšími multimediálními soubory.",
"EnableThemeSongs": "Tématická hudba na pozadí",
"EnableThemeSongsHelp": "Přehrát tématickou hudbu na pozadí při procházení knihovny.", "EnableThemeSongsHelp": "Přehrát tématickou hudbu na pozadí při procházení knihovny.",
"EnableThemeVideos": "Tématická videa",
"EnableThemeVideosHelp": "Přehrát tématické video na pozadí při procházení knihovny.", "EnableThemeVideosHelp": "Přehrát tématické video na pozadí při procházení knihovny.",
"Ended": "Ukončeno", "Ended": "Ukončeno",
"EndsAtValue": "Končí v {0}", "EndsAtValue": "Končí v {0}",
@ -202,11 +192,9 @@
"HeaderActiveDevices": "Aktivní zařízení", "HeaderActiveDevices": "Aktivní zařízení",
"HeaderActiveRecordings": "Aktivní nahrávání", "HeaderActiveRecordings": "Aktivní nahrávání",
"HeaderActivity": "Aktivita", "HeaderActivity": "Aktivita",
"HeaderAddScheduledTaskTrigger": "Přidat Spouštěč",
"HeaderAddToCollection": "Přidat do Kolekce", "HeaderAddToCollection": "Přidat do Kolekce",
"HeaderAddToPlaylist": "Přidat do playlistu", "HeaderAddToPlaylist": "Přidat do playlistu",
"HeaderAddUpdateImage": "Přidat/aktualizovat obrázek", "HeaderAddUpdateImage": "Přidat/aktualizovat obrázek",
"HeaderAddUser": "Přidat uživatele",
"HeaderAdditionalParts": "Další součásti", "HeaderAdditionalParts": "Další součásti",
"HeaderAdmin": "Administrátor", "HeaderAdmin": "Administrátor",
"HeaderAlbumArtists": "Umělci alba", "HeaderAlbumArtists": "Umělci alba",
@ -217,12 +205,10 @@
"HeaderApp": "Aplikace", "HeaderApp": "Aplikace",
"HeaderAudioBooks": "Audio knihy", "HeaderAudioBooks": "Audio knihy",
"HeaderAudioSettings": "Nastavení zvuku", "HeaderAudioSettings": "Nastavení zvuku",
"HeaderBooks": "Knihy",
"HeaderBranding": "Branding", "HeaderBranding": "Branding",
"HeaderCancelRecording": "Zrušit nahrávání", "HeaderCancelRecording": "Zrušit nahrávání",
"HeaderCancelSeries": "Ukončit Seriál", "HeaderCancelSeries": "Ukončit Seriál",
"HeaderCastAndCrew": "Herci a obsazení", "HeaderCastAndCrew": "Herci a obsazení",
"HeaderCastCrew": "Herci a obsazení",
"HeaderChannelAccess": "Přístup ke kanálu", "HeaderChannelAccess": "Přístup ke kanálu",
"HeaderCodecProfile": "Profil kodeků", "HeaderCodecProfile": "Profil kodeků",
"HeaderCodecProfileHelp": "Kodek profily označují omezení daného zařízení pro přehrávání pomocí specifických kodeků. Jestliže je omezení aplikováno, média budou překódovany i v případě, že kodek je nakonfigurován pro přímé přehrávání.", "HeaderCodecProfileHelp": "Kodek profily označují omezení daného zařízení pro přehrávání pomocí specifických kodeků. Jestliže je omezení aplikováno, média budou překódovany i v případě, že kodek je nakonfigurován pro přímé přehrávání.",
@ -252,12 +238,10 @@
"HeaderEditImages": "Editovat obrázky", "HeaderEditImages": "Editovat obrázky",
"HeaderEnabledFields": "Povolené pole", "HeaderEnabledFields": "Povolené pole",
"HeaderEnabledFieldsHelp": "Zrušte zaškrtnutí, abyste zabránily změnám dat.", "HeaderEnabledFieldsHelp": "Zrušte zaškrtnutí, abyste zabránily změnám dat.",
"HeaderEpisodes": "Epizody",
"HeaderError": "Chyba", "HeaderError": "Chyba",
"HeaderFeatureAccess": "Přístup k funkcím", "HeaderFeatureAccess": "Přístup k funkcím",
"HeaderFetchImages": "Načíst obrázky:", "HeaderFetchImages": "Načíst obrázky:",
"HeaderForKids": "Pro děti", "HeaderForKids": "Pro děti",
"HeaderForgotPassword": "Zapomenuté heslo",
"HeaderFrequentlyPlayed": "Nejčastěji přehráváno", "HeaderFrequentlyPlayed": "Nejčastěji přehráváno",
"HeaderGuideProviders": "Poskytovatelé programových průvodců", "HeaderGuideProviders": "Poskytovatelé programových průvodců",
"HeaderHttpHeaders": "Http hlavičky", "HeaderHttpHeaders": "Http hlavičky",
@ -283,7 +267,6 @@
"HeaderLoginFailure": "Přihlášení selhalo", "HeaderLoginFailure": "Přihlášení selhalo",
"HeaderMedia": "Média", "HeaderMedia": "Média",
"HeaderMediaFolders": "Složky médií", "HeaderMediaFolders": "Složky médií",
"HeaderMediaInfo": "Informace o médiu",
"HeaderMetadataSettings": "Nastavení metadat", "HeaderMetadataSettings": "Nastavení metadat",
"HeaderMoreLikeThis": "Podobné položky", "HeaderMoreLikeThis": "Podobné položky",
"HeaderMusicQuality": "Kvalita hudby", "HeaderMusicQuality": "Kvalita hudby",
@ -402,7 +385,6 @@
"LabelAppNameExample": "Příklad: Sickbeard, Sonarr", "LabelAppNameExample": "Příklad: Sickbeard, Sonarr",
"LabelArtists": "Umělci:", "LabelArtists": "Umělci:",
"LabelArtistsHelp": "Více interpretů se odděluje pomocí středníku.", "LabelArtistsHelp": "Více interpretů se odděluje pomocí středníku.",
"LabelAudio": "Zvuk",
"LabelAudioLanguagePreference": "Preferovaný jazyk zvuku:", "LabelAudioLanguagePreference": "Preferovaný jazyk zvuku:",
"LabelBindToLocalNetworkAddress": "Vázat na místní síťovou adresu:", "LabelBindToLocalNetworkAddress": "Vázat na místní síťovou adresu:",
"LabelBindToLocalNetworkAddressHelp": "Změní místní IP adresu serveru HTTP. Pokud je ponecháno prázdné, server bude svázán se všemi dostupnými adresami. Změna této hodnoty vyžaduje restartování.", "LabelBindToLocalNetworkAddressHelp": "Změní místní IP adresu serveru HTTP. Pokud je ponecháno prázdné, server bude svázán se všemi dostupnými adresami. Změna této hodnoty vyžaduje restartování.",
@ -422,7 +404,6 @@
"LabelCurrentPassword": "Aktuální heslo:", "LabelCurrentPassword": "Aktuální heslo:",
"LabelCustomCss": "Vlastní CSS:", "LabelCustomCss": "Vlastní CSS:",
"LabelCustomCssHelp": "Aplikovat vaše vlastní styly webového rozhraní.", "LabelCustomCssHelp": "Aplikovat vaše vlastní styly webového rozhraní.",
"LabelCustomDeviceDisplayName": "Jméno pro zobrazení:",
"LabelCustomDeviceDisplayNameHelp": "Nahradit vlastním názvem zobrazení nebo ponechte prázdné, aby název byl určen zařízením.", "LabelCustomDeviceDisplayNameHelp": "Nahradit vlastním názvem zobrazení nebo ponechte prázdné, aby název byl určen zařízením.",
"LabelCustomRating": "Vlastní hodnocení:", "LabelCustomRating": "Vlastní hodnocení:",
"LabelDateAdded": "Datum přidání:", "LabelDateAdded": "Datum přidání:",
@ -437,7 +418,6 @@
"LabelDiscNumber": "Číslo disku:", "LabelDiscNumber": "Číslo disku:",
"LabelDisplayLanguage": "Jazyk rozhraní:", "LabelDisplayLanguage": "Jazyk rozhraní:",
"LabelDisplayLanguageHelp": "Překlad projektu Jellyfin se neustále vyvíjí.", "LabelDisplayLanguageHelp": "Překlad projektu Jellyfin se neustále vyvíjí.",
"LabelDisplayMissingEpisodesWithinSeasons": "Zobrazit chybějící epizody",
"LabelDisplayMode": "Režim zobrazení:", "LabelDisplayMode": "Režim zobrazení:",
"LabelDisplayName": "Zobrazované jméno:", "LabelDisplayName": "Zobrazované jméno:",
"LabelDisplayOrder": "Pořadí zobrazení:", "LabelDisplayOrder": "Pořadí zobrazení:",
@ -580,7 +560,6 @@
"LabelPostProcessorArguments": "Argumenty příkazové řádky pro následné zpracování:", "LabelPostProcessorArguments": "Argumenty příkazové řádky pro následné zpracování:",
"LabelPostProcessorArgumentsHelp": "Použij {path} jako cestu k nahrávanému souboru.", "LabelPostProcessorArgumentsHelp": "Použij {path} jako cestu k nahrávanému souboru.",
"LabelPreferredDisplayLanguage": "Preferovaný jazyk zobrazení:", "LabelPreferredDisplayLanguage": "Preferovaný jazyk zobrazení:",
"LabelPreferredDisplayLanguageHelp": "Překlad projektu Jellyfin se neustále vyvíjí.",
"LabelPreferredSubtitleLanguage": "Preferovaný jazyk titulků:", "LabelPreferredSubtitleLanguage": "Preferovaný jazyk titulků:",
"LabelProfileAudioCodecs": "Audio kodeky:", "LabelProfileAudioCodecs": "Audio kodeky:",
"LabelProfileCodecs": "Kodeky:", "LabelProfileCodecs": "Kodeky:",
@ -632,7 +611,6 @@
"LabelStopping": "Zastavování", "LabelStopping": "Zastavování",
"LabelSubtitleFormatHelp": "Příklad: srt", "LabelSubtitleFormatHelp": "Příklad: srt",
"LabelSubtitlePlaybackMode": "Mód titulků:", "LabelSubtitlePlaybackMode": "Mód titulků:",
"LabelSubtitles": "Titulky",
"LabelSupportedMediaTypes": "Podporované typy médií:", "LabelSupportedMediaTypes": "Podporované typy médií:",
"LabelTagline": "Slogan:", "LabelTagline": "Slogan:",
"LabelTextBackgroundColor": "Barva pozadí textu:", "LabelTextBackgroundColor": "Barva pozadí textu:",
@ -643,12 +621,9 @@
"LabelTimeLimitHours": "Časový limit (v hodinách):", "LabelTimeLimitHours": "Časový limit (v hodinách):",
"LabelTitle": "Název:", "LabelTitle": "Název:",
"LabelTrackNumber": "Číslo stopy:", "LabelTrackNumber": "Číslo stopy:",
"LabelTranscodingAudioCodec": "Audio kodek:",
"LabelTranscodingContainer": "Obal:",
"LabelTranscodingTempPathHelp": "Určete vlastní cestu pro překódované soubory odesílané klientům. Chcete-li použít výchozí nastavení serveru, ponechte pole prázdné.", "LabelTranscodingTempPathHelp": "Určete vlastní cestu pro překódované soubory odesílané klientům. Chcete-li použít výchozí nastavení serveru, ponechte pole prázdné.",
"LabelTranscodingThreadCount": "Počet vláken pro překódování:", "LabelTranscodingThreadCount": "Počet vláken pro překódování:",
"LabelTranscodingThreadCountHelp": "Zadejte maximální počet vláken pro překódování. Snížením počtu vláken se sníží využití procesoru, ale převod nemusí být dostatečně rychlý pro plynulé přehrávání.", "LabelTranscodingThreadCountHelp": "Zadejte maximální počet vláken pro překódování. Snížením počtu vláken se sníží využití procesoru, ale převod nemusí být dostatečně rychlý pro plynulé přehrávání.",
"LabelTranscodingVideoCodec": "Video kodek:",
"LabelTriggerType": "Typ úkolu:", "LabelTriggerType": "Typ úkolu:",
"LabelTunerIpAddress": "IP adresa tuneru:", "LabelTunerIpAddress": "IP adresa tuneru:",
"LabelTunerType": "Typ tuneru:", "LabelTunerType": "Typ tuneru:",
@ -745,7 +720,6 @@
"MessagePluginConfigurationRequiresLocalAccess": "Pro konfiguraci zásuvného modulu se přihlaste přímo na lokální server.", "MessagePluginConfigurationRequiresLocalAccess": "Pro konfiguraci zásuvného modulu se přihlaste přímo na lokální server.",
"MessagePluginInstallDisclaimer": "Zásuvné moduly vytvořené členy komunity jsou skvělým způsobem, jak si zlepšit prožitek pomocí dalších funkcí. Před instalací se prosím seznamte se všemi dopady, které mohou doplňky na server mít, např.: pomalejší skenování knihovny, delší zpracování na pozadí nebo snížená stabilita systému.", "MessagePluginInstallDisclaimer": "Zásuvné moduly vytvořené členy komunity jsou skvělým způsobem, jak si zlepšit prožitek pomocí dalších funkcí. Před instalací se prosím seznamte se všemi dopady, které mohou doplňky na server mít, např.: pomalejší skenování knihovny, delší zpracování na pozadí nebo snížená stabilita systému.",
"MessageReenableUser": "Viz níže pro znovuzapnutí", "MessageReenableUser": "Viz níže pro znovuzapnutí",
"MessageSettingsSaved": "Nastavení uloženo.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Z vaší knihovny budou odstraněny následující zdroje médií:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Z vaší knihovny budou odstraněny následující zdroje médií:",
"MessageUnableToConnectToServer": "Nejsme schopni se připojit k vybranému serveru právě teď. Prosím, ujistěte se, že je spuštěn a zkuste to znovu.", "MessageUnableToConnectToServer": "Nejsme schopni se připojit k vybranému serveru právě teď. Prosím, ujistěte se, že je spuštěn a zkuste to znovu.",
"MessageUnsetContentHelp": "Obsah je zobrazen pomocí prostých složek. Pro dosažení nejlepších výsledků pomocí správce metadat nastavte typy obsahu pod-složek.", "MessageUnsetContentHelp": "Obsah je zobrazen pomocí prostých složek. Pro dosažení nejlepších výsledků pomocí správce metadat nastavte typy obsahu pod-složek.",
@ -802,7 +776,6 @@
"OptionArtist": "Umělec", "OptionArtist": "Umělec",
"OptionAscending": "Vzestupně", "OptionAscending": "Vzestupně",
"OptionAuto": "Automaticky", "OptionAuto": "Automaticky",
"OptionAutomatic": "Automaticky",
"OptionAutomaticallyGroupSeries": "Automatické sloučení k seriálu, které jsou ve více složkách", "OptionAutomaticallyGroupSeries": "Automatické sloučení k seriálu, které jsou ve více složkách",
"OptionAutomaticallyGroupSeriesHelp": "Seriály uložené ve více složkách v této knihovně budou automaticky sloučeny do jednoho seriálu.", "OptionAutomaticallyGroupSeriesHelp": "Seriály uložené ve více složkách v této knihovně budou automaticky sloučeny do jednoho seriálu.",
"OptionBlockBooks": "Knihy", "OptionBlockBooks": "Knihy",
@ -1014,16 +987,13 @@
"SystemDlnaProfilesHelp": "Systémové profily jsou jen pro čtení. Chcete-li přepsat profil systému, vytvořit vlastní profil zaměřený na stejné zařízení.", "SystemDlnaProfilesHelp": "Systémové profily jsou jen pro čtení. Chcete-li přepsat profil systému, vytvořit vlastní profil zaměřený na stejné zařízení.",
"TabAccess": "Přístup", "TabAccess": "Přístup",
"TabAdvanced": "Pokročilé", "TabAdvanced": "Pokročilé",
"TabAlbumArtists": "Umělci alba",
"TabCatalog": "Katalog", "TabCatalog": "Katalog",
"TabCodecs": "Kodeky", "TabCodecs": "Kodeky",
"TabContainers": "Obaly", "TabContainers": "Obaly",
"TabDashboard": "Nástěnka", "TabDashboard": "Nástěnka",
"TabEpisodes": "Epizody",
"TabLatest": "Nejnovější", "TabLatest": "Nejnovější",
"TabLogs": "Záznamy", "TabLogs": "Záznamy",
"TabMusic": "Hudba", "TabMusic": "Hudba",
"TabMusicVideos": "Hudební videa",
"TabMyPlugins": "Moje zásuvné moduly", "TabMyPlugins": "Moje zásuvné moduly",
"TabNetworks": "Stanice", "TabNetworks": "Stanice",
"TabNfoSettings": "NFO nastavení", "TabNfoSettings": "NFO nastavení",
@ -1034,11 +1004,9 @@
"TabProfile": "Profil", "TabProfile": "Profil",
"TabProfiles": "Profily", "TabProfiles": "Profily",
"TabResponses": "Odpovědi", "TabResponses": "Odpovědi",
"TabResumeSettings": "Obnovit",
"TabScheduledTasks": "Naplánované úlohy", "TabScheduledTasks": "Naplánované úlohy",
"TabSettings": "Nastavení", "TabSettings": "Nastavení",
"TabStreaming": "Streamování", "TabStreaming": "Streamování",
"TabTrailers": "Upoutávky",
"TabUpcoming": "Nadcházející", "TabUpcoming": "Nadcházející",
"Tags": "Tagy", "Tags": "Tagy",
"TellUsAboutYourself": "Řekněte nám něco o sobě", "TellUsAboutYourself": "Řekněte nám něco o sobě",
@ -1296,7 +1264,6 @@
"SubtitleDownloadersHelp": "Povolte a zařaďte preferované stahovače titulků v pořadí podle priority.", "SubtitleDownloadersHelp": "Povolte a zařaďte preferované stahovače titulků v pořadí podle priority.",
"TV": "TV", "TV": "TV",
"TabDirectPlay": "Přímé přehrávání", "TabDirectPlay": "Přímé přehrávání",
"TabInfo": "Info",
"TabServer": "Server", "TabServer": "Server",
"TagsValue": "Tagy: {0}", "TagsValue": "Tagy: {0}",
"ThemeSongs": "Tematická hudba", "ThemeSongs": "Tematická hudba",
@ -1312,7 +1279,6 @@
"Vertical": "Svisle", "Vertical": "Svisle",
"ViewPlaybackInfo": "Zobrazení informací o přehrávání", "ViewPlaybackInfo": "Zobrazení informací o přehrávání",
"Whitelist": "Povolit vše kromě výjimek", "Whitelist": "Povolit vše kromě výjimek",
"HeaderHome": "Domů",
"DashboardOperatingSystem": "Operační systém: {0}", "DashboardOperatingSystem": "Operační systém: {0}",
"DashboardArchitecture": "Architektura: {0}", "DashboardArchitecture": "Architektura: {0}",
"MessageNoServersAvailable": "Pomocí automatického zjišťování nebyly nalezeny žádné servery.", "MessageNoServersAvailable": "Pomocí automatického zjišťování nebyly nalezeny žádné servery.",
@ -1475,5 +1441,6 @@
"SubtitleVerticalPositionHelp": "Číslo řádku, na kterém se zobrazí text. Kladná čísla znamenají směr shora dolů. Záporná čísla zdola nahoru.", "SubtitleVerticalPositionHelp": "Číslo řádku, na kterém se zobrazí text. Kladná čísla znamenají směr shora dolů. Záporná čísla zdola nahoru.",
"LabelSubtitleVerticalPosition": "Svislé umístění:", "LabelSubtitleVerticalPosition": "Svislé umístění:",
"MessageGetInstalledPluginsError": "Při načítání seznamu nainstalovaných zásuvných modulů došlo k chybě.", "MessageGetInstalledPluginsError": "Při načítání seznamu nainstalovaných zásuvných modulů došlo k chybě.",
"MessagePluginInstallError": "Při instalaci zásuvného modulu došlo k chybě." "MessagePluginInstallError": "Při instalaci zásuvného modulu došlo k chybě.",
"PlaybackRate": "Rychlost přehrávání"
} }

View file

@ -40,26 +40,20 @@
"ButtonBack": "Tilbage", "ButtonBack": "Tilbage",
"ButtonCancel": "Annuller", "ButtonCancel": "Annuller",
"ButtonChangeServer": "Skift server", "ButtonChangeServer": "Skift server",
"ButtonEdit": "Rediger",
"ButtonEditImages": "Rediger billeder",
"ButtonEditOtherUserPreferences": "Rediger denne brugers profil, billede og personlige indstillinger.", "ButtonEditOtherUserPreferences": "Rediger denne brugers profil, billede og personlige indstillinger.",
"ButtonForgotPassword": "Glemt Adgangskode", "ButtonForgotPassword": "Glemt Adgangskode",
"ButtonFullscreen": "Fuld skærm", "ButtonFullscreen": "Fuld skærm",
"ButtonGotIt": "Forstået", "ButtonGotIt": "Forstået",
"ButtonHome": "Hjem",
"ButtonLibraryAccess": "Biblioteksadgang", "ButtonLibraryAccess": "Biblioteksadgang",
"ButtonManualLogin": "Manuel Login", "ButtonManualLogin": "Manuel Login",
"ButtonMore": "Mere", "ButtonMore": "Mere",
"ButtonNetwork": "Netværk", "ButtonNetwork": "Netværk",
"ButtonNextTrack": "Næste spor", "ButtonNextTrack": "Næste spor",
"ButtonOff": "Fra",
"ButtonOpen": "Åben", "ButtonOpen": "Åben",
"ButtonParentalControl": "Forældrekontrol", "ButtonParentalControl": "Forældrekontrol",
"ButtonPlay": "Afspil",
"ButtonPreviousTrack": "Forrige spor", "ButtonPreviousTrack": "Forrige spor",
"ButtonProfile": "Profil", "ButtonProfile": "Profil",
"ButtonQuickStartGuide": "Hurtig-start guide", "ButtonQuickStartGuide": "Hurtig-start guide",
"ButtonRefresh": "Opdater",
"ButtonRefreshGuideData": "Opdater Guide data", "ButtonRefreshGuideData": "Opdater Guide data",
"ButtonRemove": "Fjern", "ButtonRemove": "Fjern",
"ButtonRename": "Omdøb", "ButtonRename": "Omdøb",
@ -77,7 +71,6 @@
"ButtonSignIn": "Log Ind", "ButtonSignIn": "Log Ind",
"ButtonSignOut": "Log ud", "ButtonSignOut": "Log ud",
"ButtonSubmit": "Indsend", "ButtonSubmit": "Indsend",
"ButtonSubtitles": "Undertekster",
"ButtonUninstall": "Afinstaller", "ButtonUninstall": "Afinstaller",
"ButtonWebsite": "Hjemmeside", "ButtonWebsite": "Hjemmeside",
"CancelRecording": "Annuller optagelse", "CancelRecording": "Annuller optagelse",
@ -169,11 +162,9 @@
"HeaderActiveDevices": "Aktive enheder", "HeaderActiveDevices": "Aktive enheder",
"HeaderActiveRecordings": "Aktive optagelser", "HeaderActiveRecordings": "Aktive optagelser",
"HeaderActivity": "Aktivitet", "HeaderActivity": "Aktivitet",
"HeaderAddScheduledTaskTrigger": "Tilføj udløser",
"HeaderAddToCollection": "Tilføj til samling", "HeaderAddToCollection": "Tilføj til samling",
"HeaderAddToPlaylist": "Tilføj til afspilningsliste", "HeaderAddToPlaylist": "Tilføj til afspilningsliste",
"HeaderAddUpdateImage": "Tilføj/opdater billede", "HeaderAddUpdateImage": "Tilføj/opdater billede",
"HeaderAddUser": "Tilføj bruger",
"HeaderAdditionalParts": "Andre stier", "HeaderAdditionalParts": "Andre stier",
"HeaderAlert": "Advarsel", "HeaderAlert": "Advarsel",
"HeaderAllowMediaDeletionFrom": "Tillad Media Sletning Fra", "HeaderAllowMediaDeletionFrom": "Tillad Media Sletning Fra",
@ -182,11 +173,9 @@
"HeaderApiKeysHelp": "Eksterne applikationer skal have en API-nøgle for at kunne kommunikere med Jellyfin. Nøgler udstedes ved at logge ind med en Jellyfin konto, eller ved manuelt at tildele applikationen en nøgle.", "HeaderApiKeysHelp": "Eksterne applikationer skal have en API-nøgle for at kunne kommunikere med Jellyfin. Nøgler udstedes ved at logge ind med en Jellyfin konto, eller ved manuelt at tildele applikationen en nøgle.",
"HeaderAudioSettings": "Lydindstillinger", "HeaderAudioSettings": "Lydindstillinger",
"HeaderBlockItemsWithNoRating": "Klokér titler uden eller med ukendt bedømmelses information:", "HeaderBlockItemsWithNoRating": "Klokér titler uden eller med ukendt bedømmelses information:",
"HeaderBooks": "Bøger",
"HeaderCancelRecording": "Annuller Optagelse", "HeaderCancelRecording": "Annuller Optagelse",
"HeaderCancelSeries": "Annuller Serie", "HeaderCancelSeries": "Annuller Serie",
"HeaderCastAndCrew": "Medvirkende", "HeaderCastAndCrew": "Medvirkende",
"HeaderCastCrew": "Medvirkende",
"HeaderChannelAccess": "Adgang til kanaler", "HeaderChannelAccess": "Adgang til kanaler",
"HeaderChapterImages": "Kapitel Billeder", "HeaderChapterImages": "Kapitel Billeder",
"HeaderCodecProfile": "Codec profil", "HeaderCodecProfile": "Codec profil",
@ -218,14 +207,12 @@
"HeaderEditImages": "Rediger billeder", "HeaderEditImages": "Rediger billeder",
"HeaderEnabledFields": "Aktivér Felter", "HeaderEnabledFields": "Aktivér Felter",
"HeaderEnabledFieldsHelp": "Fjern fluebenet fra et felt for at låse det og forhindre dets data fra at blive ændret.", "HeaderEnabledFieldsHelp": "Fjern fluebenet fra et felt for at låse det og forhindre dets data fra at blive ændret.",
"HeaderEpisodes": "Episoder",
"HeaderError": "Fejl", "HeaderError": "Fejl",
"HeaderExternalIds": "Eksterne ID'er:", "HeaderExternalIds": "Eksterne ID'er:",
"HeaderFeatureAccess": "Adgang til funktioner", "HeaderFeatureAccess": "Adgang til funktioner",
"HeaderFetchImages": "Hent billeder:", "HeaderFetchImages": "Hent billeder:",
"HeaderFetcherSettings": "Henter indstillinger", "HeaderFetcherSettings": "Henter indstillinger",
"HeaderForKids": "For Børn", "HeaderForKids": "For Børn",
"HeaderForgotPassword": "Glemt adgangskode",
"HeaderFrequentlyPlayed": "Ofte afspillet", "HeaderFrequentlyPlayed": "Ofte afspillet",
"HeaderGuideProviders": "Guide Udbydere", "HeaderGuideProviders": "Guide Udbydere",
"HeaderHttpHeaders": "HTTP Headers", "HeaderHttpHeaders": "HTTP Headers",
@ -253,7 +240,6 @@
"HeaderLoginFailure": "Login fejl", "HeaderLoginFailure": "Login fejl",
"HeaderMedia": "Medier", "HeaderMedia": "Medier",
"HeaderMediaFolders": "Mediemapper", "HeaderMediaFolders": "Mediemapper",
"HeaderMediaInfo": "Medieinformation",
"HeaderMetadataSettings": "Indstillinger for metadata", "HeaderMetadataSettings": "Indstillinger for metadata",
"HeaderMoreLikeThis": "Mere Som Denne", "HeaderMoreLikeThis": "Mere Som Denne",
"HeaderMusicVideos": "Musikvideoer", "HeaderMusicVideos": "Musikvideoer",
@ -388,7 +374,6 @@
"LabelCustomCertificatePathHelp": "Sti til PKCS #12 fil indeholdende et certifikat og privat nøgle for at aktivere TLS understøttelse på et brugerdefineret domæne.", "LabelCustomCertificatePathHelp": "Sti til PKCS #12 fil indeholdende et certifikat og privat nøgle for at aktivere TLS understøttelse på et brugerdefineret domæne.",
"LabelCustomCss": "Brugerdefineret CSS:", "LabelCustomCss": "Brugerdefineret CSS:",
"LabelCustomCssHelp": "Anvend din egen stil til webinterfacet.", "LabelCustomCssHelp": "Anvend din egen stil til webinterfacet.",
"LabelCustomDeviceDisplayName": "Visningsnavn:",
"LabelCustomDeviceDisplayNameHelp": "Angiv en brugerdefineret navn. hvis der ikke angives et navn, bruges det navn enheden sender.", "LabelCustomDeviceDisplayNameHelp": "Angiv en brugerdefineret navn. hvis der ikke angives et navn, bruges det navn enheden sender.",
"LabelCustomRating": "Brugerdefineret bedømmelse:", "LabelCustomRating": "Brugerdefineret bedømmelse:",
"LabelDateAdded": "Dato for tilføjelse:", "LabelDateAdded": "Dato for tilføjelse:",
@ -401,7 +386,6 @@
"LabelDeviceDescription": "Beskrivelse af enhed", "LabelDeviceDescription": "Beskrivelse af enhed",
"LabelDidlMode": "DIDL tilstand:", "LabelDidlMode": "DIDL tilstand:",
"LabelDiscNumber": "Disk-nummer:", "LabelDiscNumber": "Disk-nummer:",
"LabelDisplayMissingEpisodesWithinSeasons": "Vis manglende episoder i sæsoner",
"LabelDisplayName": "Visningsnavn:", "LabelDisplayName": "Visningsnavn:",
"LabelDisplayOrder": "Visningsorden:", "LabelDisplayOrder": "Visningsorden:",
"LabelDisplaySpecialsWithinSeasons": "Vis specialepisoder sammen med den sæson de blev sent i", "LabelDisplaySpecialsWithinSeasons": "Vis specialepisoder sammen med den sæson de blev sent i",
@ -543,7 +527,6 @@
"LabelPostProcessorArguments": "Kommandolinjeargumenter til efterbehandler:", "LabelPostProcessorArguments": "Kommandolinjeargumenter til efterbehandler:",
"LabelPostProcessorArgumentsHelp": "Benyt {path} som stien til optagelsesfilen.", "LabelPostProcessorArgumentsHelp": "Benyt {path} som stien til optagelsesfilen.",
"LabelPreferredDisplayLanguage": "Foretrukket sprog til visning:", "LabelPreferredDisplayLanguage": "Foretrukket sprog til visning:",
"LabelPreferredDisplayLanguageHelp": "Oversættelse af Jellyfin er et løbende projekt.",
"LabelProfileAudioCodecs": "Lyd codecs:", "LabelProfileAudioCodecs": "Lyd codecs:",
"LabelProfileCodecsHelp": "Adskil med komma. Kan efterlades tom for at gælde for alle codecs.", "LabelProfileCodecsHelp": "Adskil med komma. Kan efterlades tom for at gælde for alle codecs.",
"LabelProfileContainersHelp": "Adskil med komma. Kan efterlades tom for at gælde for alle containere.", "LabelProfileContainersHelp": "Adskil med komma. Kan efterlades tom for at gælde for alle containere.",
@ -595,7 +578,6 @@
"LabelTimeLimitHours": "Tidsgrænse (timer):", "LabelTimeLimitHours": "Tidsgrænse (timer):",
"LabelTitle": "Titel:", "LabelTitle": "Titel:",
"LabelTrackNumber": "Spor nummer:", "LabelTrackNumber": "Spor nummer:",
"LabelTranscodingAudioCodec": "Lyd codec:",
"LabelTranscodingTempPathHelp": "Definér en bugerdefineret sti til transkodede filer til klienter. Lad den stå tom for at bruge standardmappen i serverens datamappe.", "LabelTranscodingTempPathHelp": "Definér en bugerdefineret sti til transkodede filer til klienter. Lad den stå tom for at bruge standardmappen i serverens datamappe.",
"LabelTranscodingThreadCount": "Antal af omkodningstråde:", "LabelTranscodingThreadCount": "Antal af omkodningstråde:",
"LabelTranscodingThreadCountHelp": "Vælg det maksimale antal af tråde der bruges under transcoding. Reduktion af antallet af tråde sænker CPU-forbrug, men resulterer muligvis i at konverteringer ikke foregår hurtigt nok til en jævn afspilning.", "LabelTranscodingThreadCountHelp": "Vælg det maksimale antal af tråde der bruges under transcoding. Reduktion af antallet af tråde sænker CPU-forbrug, men resulterer muligvis i at konverteringer ikke foregår hurtigt nok til en jævn afspilning.",
@ -684,7 +666,6 @@
"MessagePluginConfigurationRequiresLocalAccess": "For at konfigurerer dette plugin log da venligst direkte ind på din lokale server.", "MessagePluginConfigurationRequiresLocalAccess": "For at konfigurerer dette plugin log da venligst direkte ind på din lokale server.",
"MessagePluginInstallDisclaimer": "Plugins fremstillet af medlemmer fra Jellyfin-fællesskabet er en alle tiders måde at forbedre din oplevelse af Jellyfin med yderligere features og fordele. Før installation, bedes du venligst være opmærksom på de effekter de kan have på din Jellyfin Server; så som lange scantider på biblioteker, yderligere baggrundsbehandling og forringet systemstabilitet.", "MessagePluginInstallDisclaimer": "Plugins fremstillet af medlemmer fra Jellyfin-fællesskabet er en alle tiders måde at forbedre din oplevelse af Jellyfin med yderligere features og fordele. Før installation, bedes du venligst være opmærksom på de effekter de kan have på din Jellyfin Server; så som lange scantider på biblioteker, yderligere baggrundsbehandling og forringet systemstabilitet.",
"MessageReenableUser": "Se nedenfor om genaktivering", "MessageReenableUser": "Se nedenfor om genaktivering",
"MessageSettingsSaved": "Indstillinger er gemt.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Følgende medieplaceringer fjernes fra dit bibliotek:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Følgende medieplaceringer fjernes fra dit bibliotek:",
"MessageUnableToConnectToServer": "Vi kan ikke forbinde til den valgte server på nuværende tidspunkt. Sikrer dig venligst at serveren kører og prøv igen.", "MessageUnableToConnectToServer": "Vi kan ikke forbinde til den valgte server på nuværende tidspunkt. Sikrer dig venligst at serveren kører og prøv igen.",
"MessageUnsetContentHelp": "Indhold vil blive vist som almindelige mapper. For det bedste resultat benyt metadata manageren til at vælge indholdstypen i undermapper.", "MessageUnsetContentHelp": "Indhold vil blive vist som almindelige mapper. For det bedste resultat benyt metadata manageren til at vælge indholdstypen i undermapper.",
@ -931,15 +912,12 @@
"SystemDlnaProfilesHelp": "Systemprofiler kan ikke overskrives. Ændringer i en systemprofil vil blive gemt i en ny brugerdefineret profil.", "SystemDlnaProfilesHelp": "Systemprofiler kan ikke overskrives. Ændringer i en systemprofil vil blive gemt i en ny brugerdefineret profil.",
"TabAccess": "Adgang", "TabAccess": "Adgang",
"TabAdvanced": "Avanceret", "TabAdvanced": "Avanceret",
"TabAlbumArtists": "Album-artister",
"TabCatalog": "Katalog", "TabCatalog": "Katalog",
"TabContainers": "Containere", "TabContainers": "Containere",
"TabDashboard": "Betjeningspanel", "TabDashboard": "Betjeningspanel",
"TabDirectPlay": "Direkte afspilning", "TabDirectPlay": "Direkte afspilning",
"TabEpisodes": "Episoder",
"TabLatest": "Seneste", "TabLatest": "Seneste",
"TabMusic": "Musik", "TabMusic": "Musik",
"TabMusicVideos": "Musikvideoer",
"TabMyPlugins": "Mine tilføjelser", "TabMyPlugins": "Mine tilføjelser",
"TabNetworks": "Netværk", "TabNetworks": "Netværk",
"TabNfoSettings": "NFO Indstillinger", "TabNfoSettings": "NFO Indstillinger",
@ -950,10 +928,8 @@
"TabProfile": "Profil", "TabProfile": "Profil",
"TabProfiles": "Profiler", "TabProfiles": "Profiler",
"TabResponses": "Svar", "TabResponses": "Svar",
"TabResumeSettings": "Genoptag",
"TabScheduledTasks": "Planlagte opgaver", "TabScheduledTasks": "Planlagte opgaver",
"TabSettings": "Indstillinger", "TabSettings": "Indstillinger",
"TabTrailers": "Trailere",
"TabUpcoming": "Kommende", "TabUpcoming": "Kommende",
"TellUsAboutYourself": "Fortæl os lidt om dig selv", "TellUsAboutYourself": "Fortæl os lidt om dig selv",
"ThisWizardWillGuideYou": "Denne guide vil hjælpe dig igennem opsætningen. For at begynde, vælg venligst dit fortrukne sprog.", "ThisWizardWillGuideYou": "Denne guide vil hjælpe dig igennem opsætningen. For at begynde, vælg venligst dit fortrukne sprog.",
@ -1027,7 +1003,6 @@
"Box": "Boks", "Box": "Boks",
"BoxRear": "Boks (bagside)", "BoxRear": "Boks (bagside)",
"BurnSubtitlesHelp": "Bestemmer om serveren skal brænde undertekster, når der afspilles transcoding videoer. Undgå dette vil forbedre ydelsen meget. Vælg Auto for at brænde billedbaserede formater (VOBSUB, PGS, SUB, IDX) og bestemte ASS- eller SSA-undertekster.", "BurnSubtitlesHelp": "Bestemmer om serveren skal brænde undertekster, når der afspilles transcoding videoer. Undgå dette vil forbedre ydelsen meget. Vælg Auto for at brænde billedbaserede formater (VOBSUB, PGS, SUB, IDX) og bestemte ASS- eller SSA-undertekster.",
"ButtonFilter": "Filter",
"ButtonGuide": "Vejledning", "ButtonGuide": "Vejledning",
"ButtonInfo": "Information", "ButtonInfo": "Information",
"ButtonOk": "Ok", "ButtonOk": "Ok",
@ -1073,9 +1048,7 @@
"EnableExternalVideoPlayersHelp": "En ekstern afspiller menu vil blive vist når video afspilning starter.", "EnableExternalVideoPlayersHelp": "En ekstern afspiller menu vil blive vist når video afspilning starter.",
"EnableNextVideoInfoOverlay": "Vis næste video information mens der afspilles", "EnableNextVideoInfoOverlay": "Vis næste video information mens der afspilles",
"EnableNextVideoInfoOverlayHelp": "I slutningen af en video, vis information om den næste video i nuværende afspilningsliste.", "EnableNextVideoInfoOverlayHelp": "I slutningen af en video, vis information om den næste video i nuværende afspilningsliste.",
"EnableThemeSongs": "Tema sange",
"EnableThemeSongsHelp": "Afspil tema sange i baggrunden mens man gennemser biblioteket.", "EnableThemeSongsHelp": "Afspil tema sange i baggrunden mens man gennemser biblioteket.",
"EnableThemeVideos": "Tema videoer",
"EnableThemeVideosHelp": "Afspil tema videoer i baggrunden mens man gennemser biblioteket.", "EnableThemeVideosHelp": "Afspil tema videoer i baggrunden mens man gennemser biblioteket.",
"Episodes": "Afsnit", "Episodes": "Afsnit",
"ErrorDeletingItem": "Der skete en fejl ved sletningen af mediet fra Jellyfin Server. Tjek venligst at Jellyfin Server har skrive adgang til mediemappen og prøv igen.", "ErrorDeletingItem": "Der skete en fejl ved sletningen af mediet fra Jellyfin Server. Tjek venligst at Jellyfin Server har skrive adgang til mediemappen og prøv igen.",
@ -1118,7 +1091,6 @@
"Horizontal": "Horisontalt", "Horizontal": "Horisontalt",
"Label3DFormat": "3D format:", "Label3DFormat": "3D format:",
"LabelAlbum": "Album:", "LabelAlbum": "Album:",
"LabelAudio": "Lyd",
"LabelBlockContentWithTags": "Blokér filer med etiketter:", "LabelBlockContentWithTags": "Blokér filer med etiketter:",
"LabelBurnSubtitles": "Brænd undertekster:", "LabelBurnSubtitles": "Brænd undertekster:",
"LabelCache": "Cache:", "LabelCache": "Cache:",
@ -1155,15 +1127,12 @@
"LabelSortBy": "Sortér efter:", "LabelSortBy": "Sortér efter:",
"LabelSortOrder": "Sorteringsorden:", "LabelSortOrder": "Sorteringsorden:",
"LabelStatus": "Status:", "LabelStatus": "Status:",
"LabelSubtitles": "Undertekster",
"LabelTVHomeScreen": "TV modus hjemmeskærm:", "LabelTVHomeScreen": "TV modus hjemmeskærm:",
"LabelTag": "Mærke:", "LabelTag": "Mærke:",
"LabelTagline": "Taglinje:", "LabelTagline": "Taglinje:",
"LabelTextBackgroundColor": "Tekst baggrundsfarve:", "LabelTextBackgroundColor": "Tekst baggrundsfarve:",
"LabelTextColor": "Tekstfarve:", "LabelTextColor": "Tekstfarve:",
"LabelTextSize": "Tekststørrelse:", "LabelTextSize": "Tekststørrelse:",
"LabelTranscodingContainer": "Beholder:",
"LabelTranscodingVideoCodec": "Video codec:",
"LabelType": "Type:", "LabelType": "Type:",
"LabelVersion": "Version:", "LabelVersion": "Version:",
"LabelVideo": "Video", "LabelVideo": "Video",
@ -1209,7 +1178,6 @@
"OptionAlbum": "Album", "OptionAlbum": "Album",
"OptionArtist": "Kunstner", "OptionArtist": "Kunstner",
"OptionAuto": "Automatisk", "OptionAuto": "Automatisk",
"OptionAutomatic": "Automatisk",
"OptionBanner": "Banner", "OptionBanner": "Banner",
"OptionBluray": "Blu-Ray", "OptionBluray": "Blu-Ray",
"OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)",
@ -1260,7 +1228,6 @@
"Suggestions": "Forslag", "Suggestions": "Forslag",
"TV": "TV", "TV": "TV",
"TabCodecs": "Codeks", "TabCodecs": "Codeks",
"TabInfo": "Information",
"TabLogs": "Log", "TabLogs": "Log",
"TabServer": "Server", "TabServer": "Server",
"TabStreaming": "Streamer", "TabStreaming": "Streamer",
@ -1294,7 +1261,6 @@
"HeaderFavoriteArtists": "Favoritkunstnere", "HeaderFavoriteArtists": "Favoritkunstnere",
"HeaderFavoriteSongs": "Favoritsange", "HeaderFavoriteSongs": "Favoritsange",
"HeaderFavoriteVideos": "Favoritvideoer", "HeaderFavoriteVideos": "Favoritvideoer",
"HeaderHome": "Hjem",
"LabelServerName": "Server navn:", "LabelServerName": "Server navn:",
"LabelUserLoginAttemptsBeforeLockout": "Fejlede loginforsøg før bruger lukkes ude:", "LabelUserLoginAttemptsBeforeLockout": "Fejlede loginforsøg før bruger lukkes ude:",
"ButtonAddImage": "Tilføj billede", "ButtonAddImage": "Tilføj billede",

View file

@ -55,8 +55,6 @@
"ButtonBack": "Zurück", "ButtonBack": "Zurück",
"ButtonCancel": "Abbrechen", "ButtonCancel": "Abbrechen",
"ButtonChangeServer": "Wechsel Server", "ButtonChangeServer": "Wechsel Server",
"ButtonEdit": "Bearbeiten",
"ButtonEditImages": "Bearbeite Bilder",
"ButtonEditOtherUserPreferences": "Bearbeite dieses Benutzerprofil, das Benutzerbild und die persönlichen Einstellungen.", "ButtonEditOtherUserPreferences": "Bearbeite dieses Benutzerprofil, das Benutzerbild und die persönlichen Einstellungen.",
"ButtonForgotPassword": "Passwort vergessen", "ButtonForgotPassword": "Passwort vergessen",
"ButtonFullscreen": "Vollbild", "ButtonFullscreen": "Vollbild",
@ -67,14 +65,11 @@
"ButtonMore": "Mehr", "ButtonMore": "Mehr",
"ButtonNetwork": "Netzwerk", "ButtonNetwork": "Netzwerk",
"ButtonNextTrack": "Nächstes Stück", "ButtonNextTrack": "Nächstes Stück",
"ButtonOff": "Ausschalten",
"ButtonOpen": "Öffnen", "ButtonOpen": "Öffnen",
"ButtonParentalControl": "Kindersicherung", "ButtonParentalControl": "Kindersicherung",
"ButtonPlay": "Abspielen",
"ButtonPreviousTrack": "Vorheriges Stück", "ButtonPreviousTrack": "Vorheriges Stück",
"ButtonProfile": "Profil", "ButtonProfile": "Profil",
"ButtonQuickStartGuide": "Schnellstart Anleitung", "ButtonQuickStartGuide": "Schnellstart Anleitung",
"ButtonRefresh": "Aktualisieren",
"ButtonRefreshGuideData": "Aktualisiere TV-Programmdaten", "ButtonRefreshGuideData": "Aktualisiere TV-Programmdaten",
"ButtonRemove": "Entfernen", "ButtonRemove": "Entfernen",
"ButtonRename": "Umbenennen", "ButtonRename": "Umbenennen",
@ -94,7 +89,6 @@
"ButtonSignOut": "Abmelden", "ButtonSignOut": "Abmelden",
"ButtonStop": "Stopp", "ButtonStop": "Stopp",
"ButtonSubmit": "Bestätigen", "ButtonSubmit": "Bestätigen",
"ButtonSubtitles": "Untertitel",
"ButtonUninstall": "Deinstallieren", "ButtonUninstall": "Deinstallieren",
"CancelRecording": "Aufnahme abbrechen", "CancelRecording": "Aufnahme abbrechen",
"CancelSeries": "Serien abbrechen", "CancelSeries": "Serien abbrechen",
@ -176,9 +170,7 @@
"EnablePhotosHelp": "Bilder werden erkannt und neben anderen Mediendateien angezeigt.", "EnablePhotosHelp": "Bilder werden erkannt und neben anderen Mediendateien angezeigt.",
"EnableStreamLooping": "Auto-Schleife Live Streams", "EnableStreamLooping": "Auto-Schleife Live Streams",
"EnableStreamLoopingHelp": "Aktivieren, wenn Live Streams nur ein paar Sekunden Daten enthalten und ständig angefragt werden müssen. Kann zu Problemen führen wenn aktiviert, obwohl nicht nötig.", "EnableStreamLoopingHelp": "Aktivieren, wenn Live Streams nur ein paar Sekunden Daten enthalten und ständig angefragt werden müssen. Kann zu Problemen führen wenn aktiviert, obwohl nicht nötig.",
"EnableThemeSongs": "Titelmelodien",
"EnableThemeSongsHelp": "Titelmusik wird während des Blätterns durch die Bibliothek im Hintergrund abgespielt.", "EnableThemeSongsHelp": "Titelmusik wird während des Blätterns durch die Bibliothek im Hintergrund abgespielt.",
"EnableThemeVideos": "Titelvideos",
"EnableThemeVideosHelp": "Titelvideos werden während des Blätterns durch die Bibliothek im Hintergrund abgespielt.", "EnableThemeVideosHelp": "Titelvideos werden während des Blätterns durch die Bibliothek im Hintergrund abgespielt.",
"Ended": "Beendent", "Ended": "Beendent",
"EndsAtValue": "Endet um {0}", "EndsAtValue": "Endet um {0}",
@ -230,11 +222,9 @@
"HeaderActiveDevices": "Aktive Geräte", "HeaderActiveDevices": "Aktive Geräte",
"HeaderActiveRecordings": "Aktive Aufnahmen", "HeaderActiveRecordings": "Aktive Aufnahmen",
"HeaderActivity": "Aktivitäten", "HeaderActivity": "Aktivitäten",
"HeaderAddScheduledTaskTrigger": "Auslöser hinzufügen",
"HeaderAddToCollection": "Zu Sammlung hinzufügen", "HeaderAddToCollection": "Zu Sammlung hinzufügen",
"HeaderAddToPlaylist": "Zur Wiedergabeliste hinzufügen", "HeaderAddToPlaylist": "Zur Wiedergabeliste hinzufügen",
"HeaderAddUpdateImage": "Bild hinzufügen/aktualisieren", "HeaderAddUpdateImage": "Bild hinzufügen/aktualisieren",
"HeaderAddUser": "Benutzer anlegen",
"HeaderAdditionalParts": "Zusätzliche Teile", "HeaderAdditionalParts": "Zusätzliche Teile",
"HeaderAlbumArtists": "Album-Interpreten", "HeaderAlbumArtists": "Album-Interpreten",
"HeaderAlert": "Alarm", "HeaderAlert": "Alarm",
@ -246,12 +236,10 @@
"HeaderAudioBooks": "Hörbücher", "HeaderAudioBooks": "Hörbücher",
"HeaderAudioSettings": "Audioeinstellungen", "HeaderAudioSettings": "Audioeinstellungen",
"HeaderBlockItemsWithNoRating": "Blockiere Inhalte mit keiner oder nicht erkannter Altersfreigabe:", "HeaderBlockItemsWithNoRating": "Blockiere Inhalte mit keiner oder nicht erkannter Altersfreigabe:",
"HeaderBooks": "Bücher",
"HeaderBranding": "Branding / CSS", "HeaderBranding": "Branding / CSS",
"HeaderCancelRecording": "Aufnahme abbrechen", "HeaderCancelRecording": "Aufnahme abbrechen",
"HeaderCancelSeries": "Serie abbrechen", "HeaderCancelSeries": "Serie abbrechen",
"HeaderCastAndCrew": "Besetzung & Mitwirkende", "HeaderCastAndCrew": "Besetzung & Mitwirkende",
"HeaderCastCrew": "Besetzung & Crew",
"HeaderChannelAccess": "Channelzugriff", "HeaderChannelAccess": "Channelzugriff",
"HeaderChapterImages": "Kapitel Bilder", "HeaderChapterImages": "Kapitel Bilder",
"HeaderCodecProfile": "Codec Profil", "HeaderCodecProfile": "Codec Profil",
@ -285,14 +273,12 @@
"HeaderEditImages": "Bilder bearbeiten", "HeaderEditImages": "Bilder bearbeiten",
"HeaderEnabledFields": "Aktiviere Felder", "HeaderEnabledFields": "Aktiviere Felder",
"HeaderEnabledFieldsHelp": "Wähle Felder ab um das Ändern von Daten zu verhindern.", "HeaderEnabledFieldsHelp": "Wähle Felder ab um das Ändern von Daten zu verhindern.",
"HeaderEpisodes": "Episoden",
"HeaderError": "Fehler", "HeaderError": "Fehler",
"HeaderExternalIds": "Externe IDs:", "HeaderExternalIds": "Externe IDs:",
"HeaderFeatureAccess": "Funktionszugriff", "HeaderFeatureAccess": "Funktionszugriff",
"HeaderFetchImages": "Bilder abrufen:", "HeaderFetchImages": "Bilder abrufen:",
"HeaderFetcherSettings": "Fetcher Einstellungen", "HeaderFetcherSettings": "Fetcher Einstellungen",
"HeaderForKids": "Für Kinder", "HeaderForKids": "Für Kinder",
"HeaderForgotPassword": "Passwort vergessen",
"HeaderFrequentlyPlayed": "Oft gesehen", "HeaderFrequentlyPlayed": "Oft gesehen",
"HeaderGuideProviders": "Fernsehprogramm Quellen", "HeaderGuideProviders": "Fernsehprogramm Quellen",
"HeaderIdentification": "Identifizierung", "HeaderIdentification": "Identifizierung",
@ -320,7 +306,6 @@
"HeaderLoginFailure": "Login Fehler", "HeaderLoginFailure": "Login Fehler",
"HeaderMedia": "Medien", "HeaderMedia": "Medien",
"HeaderMediaFolders": "Medienverzeichnisse", "HeaderMediaFolders": "Medienverzeichnisse",
"HeaderMediaInfo": "Medieninformation",
"HeaderMetadataSettings": "Metadaten Einstellungen", "HeaderMetadataSettings": "Metadaten Einstellungen",
"HeaderMoreLikeThis": "Mehr wie dieses", "HeaderMoreLikeThis": "Mehr wie dieses",
"HeaderMusicQuality": "Musikqualität", "HeaderMusicQuality": "Musikqualität",
@ -472,7 +457,6 @@
"LabelCustomCertificatePathHelp": "Pfad zu einer PKCS #12 Datei die ein Zertifikat und einen privaten Schlüssel enthält, um TLS Unterstützung für eine eigene Domain zu aktivieren.", "LabelCustomCertificatePathHelp": "Pfad zu einer PKCS #12 Datei die ein Zertifikat und einen privaten Schlüssel enthält, um TLS Unterstützung für eine eigene Domain zu aktivieren.",
"LabelCustomCss": "Benutzerdefiniertes CSS:", "LabelCustomCss": "Benutzerdefiniertes CSS:",
"LabelCustomCssHelp": "Wende deine eigenen benutzerdefinierte Styles auf die Weboberfläche an.", "LabelCustomCssHelp": "Wende deine eigenen benutzerdefinierte Styles auf die Weboberfläche an.",
"LabelCustomDeviceDisplayName": "Angezeigter Name:",
"LabelCustomDeviceDisplayNameHelp": "Lege einen individuellen Anzeigenamen fest oder lasse das Feld leer, um den vom gerät übermittelten Namen zu nutzen.", "LabelCustomDeviceDisplayNameHelp": "Lege einen individuellen Anzeigenamen fest oder lasse das Feld leer, um den vom gerät übermittelten Namen zu nutzen.",
"LabelCustomRating": "Eigene Bewertung:", "LabelCustomRating": "Eigene Bewertung:",
"LabelDateAdded": "Hinzugefügt am:", "LabelDateAdded": "Hinzugefügt am:",
@ -489,7 +473,6 @@
"LabelDiscNumber": "Discnummer:", "LabelDiscNumber": "Discnummer:",
"LabelDisplayLanguage": "Anzeigesprache:", "LabelDisplayLanguage": "Anzeigesprache:",
"LabelDisplayLanguageHelp": "Die Übersetzung von Jellyfin ist ein laufendes Projekt.", "LabelDisplayLanguageHelp": "Die Übersetzung von Jellyfin ist ein laufendes Projekt.",
"LabelDisplayMissingEpisodesWithinSeasons": "Zeige fehlende Episoden innerhalb von Staffeln",
"LabelDisplayMode": "Bildschirmmodus:", "LabelDisplayMode": "Bildschirmmodus:",
"LabelDisplayName": "Anzeige Name:", "LabelDisplayName": "Anzeige Name:",
"LabelDisplayOrder": "Anzeigereihenfolge:", "LabelDisplayOrder": "Anzeigereihenfolge:",
@ -640,7 +623,6 @@
"LabelPostProcessorArguments": "Nachbearbeitung Kommandozeilen-Argumente:", "LabelPostProcessorArguments": "Nachbearbeitung Kommandozeilen-Argumente:",
"LabelPostProcessorArgumentsHelp": "Verwende {path} als das Verzeichnis für Aufnahmen.", "LabelPostProcessorArgumentsHelp": "Verwende {path} als das Verzeichnis für Aufnahmen.",
"LabelPreferredDisplayLanguage": "Bevorzugte Anzeigesprache:", "LabelPreferredDisplayLanguage": "Bevorzugte Anzeigesprache:",
"LabelPreferredDisplayLanguageHelp": "Die Übersetzung von Jellyfin ist ein laufendes Projekt.",
"LabelPreferredSubtitleLanguage": "Bevorzugte Untertitelsprache:", "LabelPreferredSubtitleLanguage": "Bevorzugte Untertitelsprache:",
"LabelProfileAudioCodecs": "Audio Codecs:", "LabelProfileAudioCodecs": "Audio Codecs:",
"LabelProfileCodecsHelp": "Getrennt durch Komma. Leerlassen, um auf alle Codecs anzuwenden.", "LabelProfileCodecsHelp": "Getrennt durch Komma. Leerlassen, um auf alle Codecs anzuwenden.",
@ -697,7 +679,6 @@
"LabelSubtitleDownloaders": "Untertitel Downloader:", "LabelSubtitleDownloaders": "Untertitel Downloader:",
"LabelSubtitleFormatHelp": "Beispiel: srt", "LabelSubtitleFormatHelp": "Beispiel: srt",
"LabelSubtitlePlaybackMode": "Untertitelmodus:", "LabelSubtitlePlaybackMode": "Untertitelmodus:",
"LabelSubtitles": "Untertitel",
"LabelSupportedMediaTypes": "Unterstüzte Medientypen:", "LabelSupportedMediaTypes": "Unterstüzte Medientypen:",
"LabelTVHomeScreen": "TV-Mode Startseite:", "LabelTVHomeScreen": "TV-Mode Startseite:",
"LabelTextBackgroundColor": "Hintergrundfarbe des Textes:", "LabelTextBackgroundColor": "Hintergrundfarbe des Textes:",
@ -708,11 +689,9 @@
"LabelTimeLimitHours": "Zeitlimit (Stunden):", "LabelTimeLimitHours": "Zeitlimit (Stunden):",
"LabelTitle": "Titel:", "LabelTitle": "Titel:",
"LabelTrackNumber": "Stück Nummer:", "LabelTrackNumber": "Stück Nummer:",
"LabelTranscodingAudioCodec": "Audio Codec:",
"LabelTranscodingTempPathHelp": "Wähle einen eigenen Pfad für transkodierte Dateien. Lasse das Feld frei, um den Standardspeicherort zu nutzen.", "LabelTranscodingTempPathHelp": "Wähle einen eigenen Pfad für transkodierte Dateien. Lasse das Feld frei, um den Standardspeicherort zu nutzen.",
"LabelTranscodingThreadCount": "Anzahl Transkodierungs-Threads:", "LabelTranscodingThreadCount": "Anzahl Transkodierungs-Threads:",
"LabelTranscodingThreadCountHelp": "Legen Sie die maximale Anzahl von Transkodierungs-Threads fest. Das Reduzieren der Thread-Anzahl verringert die CPU Auslastung, wird aber möglicherweise die Transkodierung nicht schnell genug für eine störungsfrei Wiedergabe ermöglichen.", "LabelTranscodingThreadCountHelp": "Legen Sie die maximale Anzahl von Transkodierungs-Threads fest. Das Reduzieren der Thread-Anzahl verringert die CPU Auslastung, wird aber möglicherweise die Transkodierung nicht schnell genug für eine störungsfrei Wiedergabe ermöglichen.",
"LabelTranscodingVideoCodec": "Video Codec:",
"LabelTriggerType": "Auslöser Typ:", "LabelTriggerType": "Auslöser Typ:",
"LabelTunerIpAddress": "Tuner IP Adresse:", "LabelTunerIpAddress": "Tuner IP Adresse:",
"LabelTunerType": "Tuner Typ:", "LabelTunerType": "Tuner Typ:",
@ -810,7 +789,6 @@
"MessagePluginConfigurationRequiresLocalAccess": "Melde dich bitte direkt an deinem lokalen Server an, um dieses Plugin konfigurieren zu können.", "MessagePluginConfigurationRequiresLocalAccess": "Melde dich bitte direkt an deinem lokalen Server an, um dieses Plugin konfigurieren zu können.",
"MessagePluginInstallDisclaimer": "Plugins aus der Community sind eine gute Möglichkeit um dein Erlebnis mit weiteren Funktionen und Vorteilen aufzuwerten. Bevor du diese installierst, sei dir den daraus resultierenden möglichen Umständen für deinen Server bewusst. Dies können z.B. längere Bibliotheken Scans, weiterführende Verarbeitung von Daten im Hintergrund sowie Systeminstabilität sein.", "MessagePluginInstallDisclaimer": "Plugins aus der Community sind eine gute Möglichkeit um dein Erlebnis mit weiteren Funktionen und Vorteilen aufzuwerten. Bevor du diese installierst, sei dir den daraus resultierenden möglichen Umständen für deinen Server bewusst. Dies können z.B. längere Bibliotheken Scans, weiterführende Verarbeitung von Daten im Hintergrund sowie Systeminstabilität sein.",
"MessageReenableUser": "Für Reaktivierung schauen Sie unten", "MessageReenableUser": "Für Reaktivierung schauen Sie unten",
"MessageSettingsSaved": "Einstellungen gespeichert.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Die folgenden Medienverzeichnisse werden aus der Bibliothek entfernt:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Die folgenden Medienverzeichnisse werden aus der Bibliothek entfernt:",
"MessageUnableToConnectToServer": "Wir können gerade keine Verbindung zum gewählten Server herstellen. Bitte stellen Sie sicher das dieser läuft und versuchen Sie es erneut.", "MessageUnableToConnectToServer": "Wir können gerade keine Verbindung zum gewählten Server herstellen. Bitte stellen Sie sicher das dieser läuft und versuchen Sie es erneut.",
"MessageUnsetContentHelp": "Inhalte werden als Verzeichnisse dargestellt. Für eine besser Anzeige nutzen Sie nach Möglichkeit den Meta-Data Manager und wählen Sie einen Medien-Typen für Unterverzeichnisse.", "MessageUnsetContentHelp": "Inhalte werden als Verzeichnisse dargestellt. Für eine besser Anzeige nutzen Sie nach Möglichkeit den Meta-Data Manager und wählen Sie einen Medien-Typen für Unterverzeichnisse.",
@ -1092,15 +1070,12 @@
"SystemDlnaProfilesHelp": "Systemprofile sind schreibgeschützt. Änderungen an einem Systemprofil werden als neues benutzerdefiniertes Profil gespeichert.", "SystemDlnaProfilesHelp": "Systemprofile sind schreibgeschützt. Änderungen an einem Systemprofil werden als neues benutzerdefiniertes Profil gespeichert.",
"TabAccess": "Zugang", "TabAccess": "Zugang",
"TabAdvanced": "Erweitert", "TabAdvanced": "Erweitert",
"TabAlbumArtists": "Album-Interpreten",
"TabCatalog": "Katalog", "TabCatalog": "Katalog",
"TabContainers": "Container", "TabContainers": "Container",
"TabDashboard": "Übersicht", "TabDashboard": "Übersicht",
"TabDirectPlay": "Direktwiedergabe", "TabDirectPlay": "Direktwiedergabe",
"TabEpisodes": "Episoden",
"TabLatest": "Neueste", "TabLatest": "Neueste",
"TabMusic": "Musik", "TabMusic": "Musik",
"TabMusicVideos": "Musikvideos",
"TabMyPlugins": "Meine Plugins", "TabMyPlugins": "Meine Plugins",
"TabNetworks": "Sendergruppen", "TabNetworks": "Sendergruppen",
"TabNfoSettings": "NFO Einstellungen", "TabNfoSettings": "NFO Einstellungen",
@ -1110,10 +1085,8 @@
"TabProfile": "Profil", "TabProfile": "Profil",
"TabProfiles": "Profile", "TabProfiles": "Profile",
"TabResponses": "Antworten", "TabResponses": "Antworten",
"TabResumeSettings": "Fortsetzen",
"TabScheduledTasks": "Geplante Aufgaben", "TabScheduledTasks": "Geplante Aufgaben",
"TabSettings": "Einstellungen", "TabSettings": "Einstellungen",
"TabTrailers": "Trailer",
"TabUpcoming": "Bevorstehend", "TabUpcoming": "Bevorstehend",
"TellUsAboutYourself": "Sagen Sie uns etwas über sich selbst", "TellUsAboutYourself": "Sagen Sie uns etwas über sich selbst",
"ThemeSongs": "Titelsongs", "ThemeSongs": "Titelsongs",
@ -1176,8 +1149,6 @@
"Auto": "Auto", "Auto": "Auto",
"Banner": "Banner", "Banner": "Banner",
"Blacklist": "Sperrliste", "Blacklist": "Sperrliste",
"ButtonFilter": "Filter",
"ButtonHome": "Startseite",
"ButtonOk": "Ok", "ButtonOk": "Ok",
"ButtonPause": "Pause", "ButtonPause": "Pause",
"ButtonStart": "Start", "ButtonStart": "Start",
@ -1202,7 +1173,6 @@
"Home": "Startseite", "Home": "Startseite",
"Horizontal": "Horizontal", "Horizontal": "Horizontal",
"LabelAlbum": "Album:", "LabelAlbum": "Album:",
"LabelAudio": "Audio",
"LabelCache": "Cache:", "LabelCache": "Cache:",
"LabelFormat": "Format:", "LabelFormat": "Format:",
"LabelH264Crf": "H264 Encodierungs-CRF:", "LabelH264Crf": "H264 Encodierungs-CRF:",
@ -1226,7 +1196,6 @@
"Normal": "Normal", "Normal": "Normal",
"LabelDynamicExternalId": "{0} Id:", "LabelDynamicExternalId": "{0} Id:",
"LabelStatus": "Status:", "LabelStatus": "Status:",
"LabelTranscodingContainer": "Container:",
"Live": "Live", "Live": "Live",
"LiveTV": "Live-TV", "LiveTV": "Live-TV",
"Logo": "Logo", "Logo": "Logo",
@ -1238,7 +1207,6 @@
"Option3D": "3D", "Option3D": "3D",
"OptionAlbum": "Album", "OptionAlbum": "Album",
"OptionAuto": "Auto", "OptionAuto": "Auto",
"OptionAutomatic": "Auto",
"OptionBluray": "Blu-ray", "OptionBluray": "Blu-ray",
"OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)",
"OptionDownloadBannerImage": "Banner", "OptionDownloadBannerImage": "Banner",
@ -1259,7 +1227,6 @@
"Studios": "Studios", "Studios": "Studios",
"TV": "TV", "TV": "TV",
"TabCodecs": "Codecs", "TabCodecs": "Codecs",
"TabInfo": "Info",
"TabLogs": "Protokoll", "TabLogs": "Protokoll",
"TabPlugins": "Plugins", "TabPlugins": "Plugins",
"TabServer": "Server", "TabServer": "Server",
@ -1311,7 +1278,6 @@
"OptionLoginAttemptsBeforeLockoutHelp": "Null (0) bedeutet den Standardwert von drei Versuchen für normale, sowie fünf für Administrator-Benutzer zu übernehmen. Ein Wert von -1 deaktiviert die Funktion.", "OptionLoginAttemptsBeforeLockoutHelp": "Null (0) bedeutet den Standardwert von drei Versuchen für normale, sowie fünf für Administrator-Benutzer zu übernehmen. Ein Wert von -1 deaktiviert die Funktion.",
"PasswordResetProviderHelp": "Wählen Sie einen Password Reset Provider, der verwendet werden soll, wenn dieser Benutzer ein Passwort zurücksetzen möchte.", "PasswordResetProviderHelp": "Wählen Sie einen Password Reset Provider, der verwendet werden soll, wenn dieser Benutzer ein Passwort zurücksetzen möchte.",
"Box": "Box", "Box": "Box",
"HeaderHome": "Startseite",
"LabelAudioCodec": "Audiocodec:", "LabelAudioCodec": "Audiocodec:",
"LabelAudioChannels": "Audiokanäle:", "LabelAudioChannels": "Audiokanäle:",
"HeaderTypeImageFetchers": "{0} Bildquellen", "HeaderTypeImageFetchers": "{0} Bildquellen",
@ -1475,5 +1441,6 @@
"Preview": "Vorschau", "Preview": "Vorschau",
"LabelSubtitleVerticalPosition": "Vertikale Position:", "LabelSubtitleVerticalPosition": "Vertikale Position:",
"MessageGetInstalledPluginsError": "Beim Abrufen der Liste der derzeit installierten Plugins ist ein Fehler aufgetreten.", "MessageGetInstalledPluginsError": "Beim Abrufen der Liste der derzeit installierten Plugins ist ein Fehler aufgetreten.",
"MessagePluginInstallError": "Bei der Installation des Plugins ist ein Fehler aufgetreten." "MessagePluginInstallError": "Bei der Installation des Plugins ist ein Fehler aufgetreten.",
"PlaybackRate": "Wiedergabegeschwindigkeit"
} }

View file

@ -53,15 +53,11 @@
"ButtonBack": "Πίσω", "ButtonBack": "Πίσω",
"ButtonCancel": "Ακύρωση", "ButtonCancel": "Ακύρωση",
"ButtonChangeServer": "Αλλαγή Διακομιστή", "ButtonChangeServer": "Αλλαγή Διακομιστή",
"ButtonEdit": "Επεξεργασία",
"ButtonEditImages": "Επεξεργασία εικόνων",
"ButtonEditOtherUserPreferences": "Επεξεργαστείτε το προφίλ, την εικόνα και τις προσωπικές προτιμήσεις αυτού του χρήστη.", "ButtonEditOtherUserPreferences": "Επεξεργαστείτε το προφίλ, την εικόνα και τις προσωπικές προτιμήσεις αυτού του χρήστη.",
"ButtonFilter": "Φίλτρο",
"ButtonForgotPassword": "Ξέχασα τον κωδικό", "ButtonForgotPassword": "Ξέχασα τον κωδικό",
"ButtonFullscreen": "Πλήρης οθόνη", "ButtonFullscreen": "Πλήρης οθόνη",
"ButtonGotIt": "Το κατάλαβα", "ButtonGotIt": "Το κατάλαβα",
"ButtonGuide": "Οδηγός", "ButtonGuide": "Οδηγός",
"ButtonHome": "Αρχική",
"ButtonInfo": "Πληροφορία", "ButtonInfo": "Πληροφορία",
"ButtonLibraryAccess": "Πρόσβαση στη βιβλιοθήκη", "ButtonLibraryAccess": "Πρόσβαση στη βιβλιοθήκη",
"ButtonManualLogin": "Χειροκίνητη Είσοδος", "ButtonManualLogin": "Χειροκίνητη Είσοδος",
@ -70,11 +66,9 @@
"ButtonOpen": "Άνοιγμα", "ButtonOpen": "Άνοιγμα",
"ButtonParentalControl": "Γονικός έλεγχος", "ButtonParentalControl": "Γονικός έλεγχος",
"ButtonPause": "Παύση", "ButtonPause": "Παύση",
"ButtonPlay": "Αναπαραγωγή",
"ButtonPreviousTrack": "Προηγουμενο", "ButtonPreviousTrack": "Προηγουμενο",
"ButtonProfile": "Προφίλ", "ButtonProfile": "Προφίλ",
"ButtonQuickStartGuide": "Οδηγός Γρήγορης Εκκίνησης", "ButtonQuickStartGuide": "Οδηγός Γρήγορης Εκκίνησης",
"ButtonRefresh": "Ανανέωση",
"ButtonRefreshGuideData": "Ανανέωση Δεδομένων Οδηγού", "ButtonRefreshGuideData": "Ανανέωση Δεδομένων Οδηγού",
"ButtonRemove": "Κατάργηση", "ButtonRemove": "Κατάργηση",
"ButtonRename": "Μετονομασία", "ButtonRename": "Μετονομασία",
@ -95,7 +89,6 @@
"ButtonStart": "Έναρξη", "ButtonStart": "Έναρξη",
"ButtonStop": "Διακοπή", "ButtonStop": "Διακοπή",
"ButtonSubmit": "υποβολή", "ButtonSubmit": "υποβολή",
"ButtonSubtitles": "Υπότιτλοι",
"ButtonTrailer": "Τρέϊλερ", "ButtonTrailer": "Τρέϊλερ",
"ButtonUninstall": "Απεγκατάσταση", "ButtonUninstall": "Απεγκατάσταση",
"ButtonWebsite": "Ιστοσελίδα", "ButtonWebsite": "Ιστοσελίδα",
@ -177,9 +170,7 @@
"EnableHardwareEncoding": "Ενεργοποίηση αποκωδικοποίησης υλικού", "EnableHardwareEncoding": "Ενεργοποίηση αποκωδικοποίησης υλικού",
"EnableNextVideoInfoOverlay": "Ενεργοποιήστε τις επόμενες πληροφορίες βίντεο κατά την αναπαραγωγή", "EnableNextVideoInfoOverlay": "Ενεργοποιήστε τις επόμενες πληροφορίες βίντεο κατά την αναπαραγωγή",
"EnableNextVideoInfoOverlayHelp": "Στο τέλος ενός βίντεο, εμφανίστε πληροφορίες σχετικά με το επόμενο βίντεο που εμφανίζεται στην τρέχουσα λίστα αναπαραγωγής.", "EnableNextVideoInfoOverlayHelp": "Στο τέλος ενός βίντεο, εμφανίστε πληροφορίες σχετικά με το επόμενο βίντεο που εμφανίζεται στην τρέχουσα λίστα αναπαραγωγής.",
"EnableThemeSongs": "Ενεργοποίηση Θεματικών Τραγουδιών",
"EnableThemeSongsHelp": "Αν είναι ενεργοποιημένη, τα τραγούδια θεμάτων θα αναπαραχθούν στο παρασκήνιο κατά την περιήγηση στη βιβλιοθήκη.", "EnableThemeSongsHelp": "Αν είναι ενεργοποιημένη, τα τραγούδια θεμάτων θα αναπαραχθούν στο παρασκήνιο κατά την περιήγηση στη βιβλιοθήκη.",
"EnableThemeVideos": "Ενεργοποίηση βίντεο θέματος",
"EnableThemeVideosHelp": "Αν είναι ενεργοποιημένη, τα βίντεο θεμάτων θα αναπαραχθούν στο παρασκήνιο κατά την περιήγηση στη βιβλιοθήκη.", "EnableThemeVideosHelp": "Αν είναι ενεργοποιημένη, τα βίντεο θεμάτων θα αναπαραχθούν στο παρασκήνιο κατά την περιήγηση στη βιβλιοθήκη.",
"Ended": "Τέλος", "Ended": "Τέλος",
"EndsAtValue": "Τελειώνει σε {0}", "EndsAtValue": "Τελειώνει σε {0}",
@ -224,11 +215,9 @@
"HeaderActiveDevices": "Ενεργές Συσκευές", "HeaderActiveDevices": "Ενεργές Συσκευές",
"HeaderActiveRecordings": "Ενεργές εγγραφές", "HeaderActiveRecordings": "Ενεργές εγγραφές",
"HeaderActivity": "Δραστηριότητα", "HeaderActivity": "Δραστηριότητα",
"HeaderAddScheduledTaskTrigger": "Προσθήκη διακόπτη",
"HeaderAddToCollection": "Πρόσθεσε στη Συλλογή", "HeaderAddToCollection": "Πρόσθεσε στη Συλλογή",
"HeaderAddToPlaylist": "Πρόσθεσε σε Λίστα", "HeaderAddToPlaylist": "Πρόσθεσε σε Λίστα",
"HeaderAddUpdateImage": "Προσθήκη / Ενημέρωση εικόνας", "HeaderAddUpdateImage": "Προσθήκη / Ενημέρωση εικόνας",
"HeaderAddUser": "Προσθήκη Χρήστη",
"HeaderAdditionalParts": "Πρόσθετα Μέρη", "HeaderAdditionalParts": "Πρόσθετα Μέρη",
"HeaderAdmin": "Διαχειριστής", "HeaderAdmin": "Διαχειριστής",
"HeaderAlbumArtists": "Καλλιτέχνες του Άλμπουμ", "HeaderAlbumArtists": "Καλλιτέχνες του Άλμπουμ",
@ -241,11 +230,9 @@
"HeaderAudioBooks": "Μουσικά Βιβλία", "HeaderAudioBooks": "Μουσικά Βιβλία",
"HeaderAudioSettings": "Ρυθμίσεις Ήχου", "HeaderAudioSettings": "Ρυθμίσεις Ήχου",
"HeaderBlockItemsWithNoRating": "Αποκλεισμός στοιχείων χωρίς ή μη αναγνωρισμένων πληροφοριών αξιολόγησης:", "HeaderBlockItemsWithNoRating": "Αποκλεισμός στοιχείων χωρίς ή μη αναγνωρισμένων πληροφοριών αξιολόγησης:",
"HeaderBooks": "Βιβλία",
"HeaderCancelRecording": "Ακύρωση Εγγραφής", "HeaderCancelRecording": "Ακύρωση Εγγραφής",
"HeaderCancelSeries": "Ακύρωση Σειράς", "HeaderCancelSeries": "Ακύρωση Σειράς",
"HeaderCastAndCrew": "Ηθοποιοί και Συνεργείο", "HeaderCastAndCrew": "Ηθοποιοί και Συνεργείο",
"HeaderCastCrew": "Ηθοποιοί και συνεργείο",
"HeaderCodecProfileHelp": "Τα προφίλ κωδικοποιητή υποδεικνύουν τους περιορισμούς μιας συσκευής κατά την αναπαραγωγή συγκεκριμένων κωδικοποιητών. Εάν ισχύει περιορισμός, τότε τα μέσα θα κωδικοποιηθούν, ακόμα και αν ο κωδικοποιητής έχει ρυθμιστεί για άμεση αναπαραγωγή.", "HeaderCodecProfileHelp": "Τα προφίλ κωδικοποιητή υποδεικνύουν τους περιορισμούς μιας συσκευής κατά την αναπαραγωγή συγκεκριμένων κωδικοποιητών. Εάν ισχύει περιορισμός, τότε τα μέσα θα κωδικοποιηθούν, ακόμα και αν ο κωδικοποιητής έχει ρυθμιστεί για άμεση αναπαραγωγή.",
"HeaderConfigureRemoteAccess": "Ρύθμιση απομακρυσμένης πρόσβασης", "HeaderConfigureRemoteAccess": "Ρύθμιση απομακρυσμένης πρόσβασης",
"HeaderConfirmPluginInstallation": "Επιβεβαιώστε την εγκατάσταση της προσθήκης", "HeaderConfirmPluginInstallation": "Επιβεβαιώστε την εγκατάσταση της προσθήκης",
@ -271,13 +258,11 @@
"HeaderEditImages": "Επεξεργασία εικόνων", "HeaderEditImages": "Επεξεργασία εικόνων",
"HeaderEnabledFields": "Ενεργά Πεδία", "HeaderEnabledFields": "Ενεργά Πεδία",
"HeaderEnabledFieldsHelp": "Καταργήστε την επιλογή ενός πεδίου για να το κλειδώσετε και να αποτρέψετε την αλλαγή των δεδομένων του.", "HeaderEnabledFieldsHelp": "Καταργήστε την επιλογή ενός πεδίου για να το κλειδώσετε και να αποτρέψετε την αλλαγή των δεδομένων του.",
"HeaderEpisodes": "Επεισόδια",
"HeaderError": "Σφάλμα", "HeaderError": "Σφάλμα",
"HeaderExternalIds": "Εξωτερικά ID:", "HeaderExternalIds": "Εξωτερικά ID:",
"HeaderFeatureAccess": "Πρόσβαση χαρακτηριστικών", "HeaderFeatureAccess": "Πρόσβαση χαρακτηριστικών",
"HeaderFetchImages": "Λήψη εικόνων:", "HeaderFetchImages": "Λήψη εικόνων:",
"HeaderForKids": "Για τα Παιδιά", "HeaderForKids": "Για τα Παιδιά",
"HeaderForgotPassword": "Ξέχασα τον κωδικό",
"HeaderFrequentlyPlayed": "Συχνά έπαιξε", "HeaderFrequentlyPlayed": "Συχνά έπαιξε",
"HeaderIdentificationCriteriaHelp": "Καταχωρήστε τουλάχιστον ένα κριτήριο αναγνώρισης.", "HeaderIdentificationCriteriaHelp": "Καταχωρήστε τουλάχιστον ένα κριτήριο αναγνώρισης.",
"HeaderIdentificationHeader": "Αναγνωριστικό Header", "HeaderIdentificationHeader": "Αναγνωριστικό Header",
@ -301,7 +286,6 @@
"HeaderLoginFailure": "Αποτυχία εισόδου", "HeaderLoginFailure": "Αποτυχία εισόδου",
"HeaderMedia": "Πολυμέσα", "HeaderMedia": "Πολυμέσα",
"HeaderMediaFolders": "Φάκελοι Πολυμέσων", "HeaderMediaFolders": "Φάκελοι Πολυμέσων",
"HeaderMediaInfo": "Πληροφορίες πολυμέσων",
"HeaderMetadataSettings": "Ρυθμίσεις μεταδεδομένων", "HeaderMetadataSettings": "Ρυθμίσεις μεταδεδομένων",
"HeaderMoreLikeThis": "Περισσότερα Σαν Αυτό", "HeaderMoreLikeThis": "Περισσότερα Σαν Αυτό",
"HeaderMusicQuality": "Ποιότητα Μουσικής", "HeaderMusicQuality": "Ποιότητα Μουσικής",
@ -410,7 +394,6 @@
"LabelAppNameExample": "Παράδειγμα: Sickbeard, NzbDrone", "LabelAppNameExample": "Παράδειγμα: Sickbeard, NzbDrone",
"LabelArtists": "Καλλιτέχνες:", "LabelArtists": "Καλλιτέχνες:",
"LabelArtistsHelp": "Ξεχωρίστε πολλαπλά χρησιμοποιώντας;", "LabelArtistsHelp": "Ξεχωρίστε πολλαπλά χρησιμοποιώντας;",
"LabelAudio": "Ήχος",
"LabelAudioLanguagePreference": "Προτιμώμενη γλώσσα ήχου:", "LabelAudioLanguagePreference": "Προτιμώμενη γλώσσα ήχου:",
"LabelAutomaticallyRefreshInternetMetadataEvery": "Αυτόματη ανανέωση μεταδεδομένων από το internet:", "LabelAutomaticallyRefreshInternetMetadataEvery": "Αυτόματη ανανέωση μεταδεδομένων από το internet:",
"LabelBirthDate": "Ημερομηνία Γενεθλίων:", "LabelBirthDate": "Ημερομηνία Γενεθλίων:",
@ -433,7 +416,6 @@
"LabelCustomCertificatePathHelp": "Προσθέστε το δικό σας αρχείο .pfx πιστοποιητικού ssl.", "LabelCustomCertificatePathHelp": "Προσθέστε το δικό σας αρχείο .pfx πιστοποιητικού ssl.",
"LabelCustomCss": "Προσαρμοσμένο css:", "LabelCustomCss": "Προσαρμοσμένο css:",
"LabelCustomCssHelp": "Εφαρμόστε το δικό σας προσαρμοσμένο css στην διεπαφή ιστού.", "LabelCustomCssHelp": "Εφαρμόστε το δικό σας προσαρμοσμένο css στην διεπαφή ιστού.",
"LabelCustomDeviceDisplayName": "Εμφάνιση ονόματος:",
"LabelCustomRating": "Προσαρμοσμένη αξιολόγηση:", "LabelCustomRating": "Προσαρμοσμένη αξιολόγηση:",
"LabelDateAdded": "Ημερνία προσθήκης:", "LabelDateAdded": "Ημερνία προσθήκης:",
"LabelDateTimeLocale": "Ημερομηνία τοπική ώρα:", "LabelDateTimeLocale": "Ημερομηνία τοπική ώρα:",
@ -446,7 +428,6 @@
"LabelDiscNumber": "Αριθμός Δίσκου:", "LabelDiscNumber": "Αριθμός Δίσκου:",
"LabelDisplayLanguage": "Γλώσσα Εμφάνισης:", "LabelDisplayLanguage": "Γλώσσα Εμφάνισης:",
"LabelDisplayLanguageHelp": "Η μετάφραση του Jellyfin είναι ένα συνεχιζόμενο έργο.", "LabelDisplayLanguageHelp": "Η μετάφραση του Jellyfin είναι ένα συνεχιζόμενο έργο.",
"LabelDisplayMissingEpisodesWithinSeasons": "Εμφάνιση επεισοδίων που λείπουν από την σαιζόν",
"LabelDisplayMode": "Λειτουργία προβολής:", "LabelDisplayMode": "Λειτουργία προβολής:",
"LabelDisplayName": "Εμφάνιση ονόματος:", "LabelDisplayName": "Εμφάνιση ονόματος:",
"LabelDisplayOrder": "Σειρά εμφάνισης:", "LabelDisplayOrder": "Σειρά εμφάνισης:",
@ -573,7 +554,6 @@
"LabelPlayDefaultAudioTrack": "Αναπαραγωγή προεπιλεγμένου κομματιού ήχου ανεξάρτητα από τη γλώσσα", "LabelPlayDefaultAudioTrack": "Αναπαραγωγή προεπιλεγμένου κομματιού ήχου ανεξάρτητα από τη γλώσσα",
"LabelPlaylist": "Λίστα:", "LabelPlaylist": "Λίστα:",
"LabelPreferredDisplayLanguage": "Προτιμώμενη γλώσσα εμφάνισης:", "LabelPreferredDisplayLanguage": "Προτιμώμενη γλώσσα εμφάνισης:",
"LabelPreferredDisplayLanguageHelp": "Η μετάφραση του Jellyfin είναι ένα συνεχιζόμενο έργο.",
"LabelPreferredSubtitleLanguage": "Προτεινόμενη Γλώσσα υποτίτλων:", "LabelPreferredSubtitleLanguage": "Προτεινόμενη Γλώσσα υποτίτλων:",
"LabelProfileCodecsHelp": "Διαχωρίζονται με κόμμα. Αυτό μπορεί να μείνει κενό για να εφαρμοστεί σε όλα τα codecs.", "LabelProfileCodecsHelp": "Διαχωρίζονται με κόμμα. Αυτό μπορεί να μείνει κενό για να εφαρμοστεί σε όλα τα codecs.",
"LabelProfileContainersHelp": "Διαχωρίζονται με κόμμα. Αυτό μπορεί να μείνει κενό για να εφαρμοστεί σε όλα τα containers.", "LabelProfileContainersHelp": "Διαχωρίζονται με κόμμα. Αυτό μπορεί να μείνει κενό για να εφαρμοστεί σε όλα τα containers.",
@ -619,7 +599,6 @@
"LabelStopWhenPossible": "Διακοπή όταν είναι δυνατόν:", "LabelStopWhenPossible": "Διακοπή όταν είναι δυνατόν:",
"LabelSubtitleFormatHelp": "Παράδειγμα: srt", "LabelSubtitleFormatHelp": "Παράδειγμα: srt",
"LabelSubtitlePlaybackMode": "Λειτουργία υποτίτλων:", "LabelSubtitlePlaybackMode": "Λειτουργία υποτίτλων:",
"LabelSubtitles": "Υπότιτλοι",
"LabelSupportedMediaTypes": "Υποστηριζόμενοι τύποι μέσων:", "LabelSupportedMediaTypes": "Υποστηριζόμενοι τύποι μέσων:",
"LabelTVHomeScreen": "Αρχική οθόνη λειτουργίας τηλεόρασης:", "LabelTVHomeScreen": "Αρχική οθόνη λειτουργίας τηλεόρασης:",
"LabelTag": "Ετικέτα:", "LabelTag": "Ετικέτα:",
@ -719,7 +698,6 @@
"MessagePleaseWait": "Παρακαλώ περιμένετε. Αυτό μπορεί να πάρει ένα λεπτό.", "MessagePleaseWait": "Παρακαλώ περιμένετε. Αυτό μπορεί να πάρει ένα λεπτό.",
"MessagePluginConfigurationRequiresLocalAccess": "Για να ρυθμίσετε αυτό το πρόσθετο παρακαλώ συνδεθείτε στον τοπικό διακομιστή σας άμεσα.", "MessagePluginConfigurationRequiresLocalAccess": "Για να ρυθμίσετε αυτό το πρόσθετο παρακαλώ συνδεθείτε στον τοπικό διακομιστή σας άμεσα.",
"MessageReenableUser": "Δες παρακάτω για ενεργοποιήση", "MessageReenableUser": "Δες παρακάτω για ενεργοποιήση",
"MessageSettingsSaved": "Οι ρυθμίσεις αποθηκεύτηκαν.",
"MessageUnableToConnectToServer": "Δεν είναι δυνατή η σύνδεση με τον επιλεγμένο διακομιστή αυτή τη στιγμή. Βεβαιωθείτε ότι εκτελείται και προσπαθήστε ξανά.", "MessageUnableToConnectToServer": "Δεν είναι δυνατή η σύνδεση με τον επιλεγμένο διακομιστή αυτή τη στιγμή. Βεβαιωθείτε ότι εκτελείται και προσπαθήστε ξανά.",
"MessageYouHaveVersionInstalled": "Αυτήν τη στιγμή έχετε εγκατεστημένη την έκδοση {0}.", "MessageYouHaveVersionInstalled": "Αυτήν τη στιγμή έχετε εγκατεστημένη την έκδοση {0}.",
"Metadata": "Μεταδεδομένα", "Metadata": "Μεταδεδομένα",
@ -781,7 +759,6 @@
"OptionArtist": "Καλλιτέχνες", "OptionArtist": "Καλλιτέχνες",
"OptionAscending": "Αύξουσα", "OptionAscending": "Αύξουσα",
"OptionAuto": "Αυτόματο", "OptionAuto": "Αυτόματο",
"OptionAutomatic": "Αυτόματο",
"OptionBlockBooks": "Βιβλία", "OptionBlockBooks": "Βιβλία",
"OptionBlockChannelContent": "Περιεχόμενο Διαδικτυακών Καναλιών", "OptionBlockChannelContent": "Περιεχόμενο Διαδικτυακών Καναλιών",
"OptionBlockLiveTvChannels": "ΚΑΝΑΛΙΑ ΖΩΝΤΑΝΗΣ ΤΗΛΕΟΡΑΣΗΣ", "OptionBlockLiveTvChannels": "ΚΑΝΑΛΙΑ ΖΩΝΤΑΝΗΣ ΤΗΛΕΟΡΑΣΗΣ",
@ -982,15 +959,11 @@
"TV": "Τηλεόραση", "TV": "Τηλεόραση",
"TabAccess": "Πρόσβαση", "TabAccess": "Πρόσβαση",
"TabAdvanced": "Για προχωρημένους", "TabAdvanced": "Για προχωρημένους",
"TabAlbumArtists": "Άλμπουμ Καλλιτέχνες",
"TabCatalog": "Κατάλογος", "TabCatalog": "Κατάλογος",
"TabDashboard": "Πίνακας Ελέγχου", "TabDashboard": "Πίνακας Ελέγχου",
"TabDirectPlay": "Άμεση Αναπαραγωγή", "TabDirectPlay": "Άμεση Αναπαραγωγή",
"TabEpisodes": "Επεισόδια",
"TabInfo": "Πληροφορία",
"TabLatest": "Τελευταία", "TabLatest": "Τελευταία",
"TabMusic": "Μουσική", "TabMusic": "Μουσική",
"TabMusicVideos": "Μουσικά βίντεο",
"TabMyPlugins": "Τα πρόσθετα μου", "TabMyPlugins": "Τα πρόσθετα μου",
"TabNetworks": "Δίκτυα", "TabNetworks": "Δίκτυα",
"TabNfoSettings": "Ρυθμίσεις NFO", "TabNfoSettings": "Ρυθμίσεις NFO",
@ -1005,7 +978,6 @@
"TabServer": "Διακομιστής", "TabServer": "Διακομιστής",
"TabSettings": "Ρυθμισεις", "TabSettings": "Ρυθμισεις",
"TabStreaming": "Ροή", "TabStreaming": "Ροή",
"TabTrailers": "Τρέιλερς",
"TabUpcoming": "Επερχόμενα", "TabUpcoming": "Επερχόμενα",
"Tags": "Ετικέτες", "Tags": "Ετικέτες",
"TagsValue": "Ετικέτες: {0}", "TagsValue": "Ετικέτες: {0}",
@ -1081,7 +1053,6 @@
"HeaderSelectCertificatePath": "Επιλέξτε Διαδρομή Πιστοποιητικού", "HeaderSelectCertificatePath": "Επιλέξτε Διαδρομή Πιστοποιητικού",
"HeaderRemoveMediaFolder": "Αφαίρεση Φακέλου Μέσων", "HeaderRemoveMediaFolder": "Αφαίρεση Φακέλου Μέσων",
"HeaderIdentification": "Ταυτοποίηση", "HeaderIdentification": "Ταυτοποίηση",
"HeaderHome": "Αρχική",
"HeaderGuideProviders": "Πάροχοι Δεδομένων Προγράμματος Τηλεόρασης", "HeaderGuideProviders": "Πάροχοι Δεδομένων Προγράμματος Τηλεόρασης",
"HeaderFavoriteVideos": "Αγαπημένα Βίντεο", "HeaderFavoriteVideos": "Αγαπημένα Βίντεο",
"HeaderFavoriteMovies": "Αγαπημένες Ταινίες", "HeaderFavoriteMovies": "Αγαπημένες Ταινίες",
@ -1111,7 +1082,6 @@
"EnablePhotos": "Εμφάνιση φωτογραφιών", "EnablePhotos": "Εμφάνιση φωτογραφιών",
"DrmChannelsNotImported": "Κανάλια με DRM δεν θα εισαχθούν.", "DrmChannelsNotImported": "Κανάλια με DRM δεν θα εισαχθούν.",
"ButtonOk": "Οκ", "ButtonOk": "Οκ",
"ButtonOff": "Απενεργοποίηση",
"ButtonNetwork": "Δίκτυο", "ButtonNetwork": "Δίκτυο",
"AllowOnTheFlySubtitleExtractionHelp": "Οι ενσωματωμένοι υπότιτλοι μπορούν να εξαχθούν από βίντεο και να σταλούν στις συσκευές σε απλό κείμενο για να αποφευχθούν μετατροπές βίντεο. Σε μερικά συστήματα αυτό μπορεί να πάρει πολύ ώρα και να κάνει το βίντεο να κολλάει κατά την διάρκεια της εξαγωγής. Απενεργοποιήστε το για να έχετε ενσωματωμένους υπότιτλους πάνω στο βίντεο όταν αυτοί δεν υποστηρίζονται από την συσκευή.", "AllowOnTheFlySubtitleExtractionHelp": "Οι ενσωματωμένοι υπότιτλοι μπορούν να εξαχθούν από βίντεο και να σταλούν στις συσκευές σε απλό κείμενο για να αποφευχθούν μετατροπές βίντεο. Σε μερικά συστήματα αυτό μπορεί να πάρει πολύ ώρα και να κάνει το βίντεο να κολλάει κατά την διάρκεια της εξαγωγής. Απενεργοποιήστε το για να έχετε ενσωματωμένους υπότιτλους πάνω στο βίντεο όταν αυτοί δεν υποστηρίζονται από την συσκευή.",
"AllowOnTheFlySubtitleExtraction": "Επίτρεψε την εξαγωγή υποτίτλων σε πραγματικό χρόνο", "AllowOnTheFlySubtitleExtraction": "Επίτρεψε την εξαγωγή υποτίτλων σε πραγματικό χρόνο",

View file

@ -105,31 +105,24 @@
"ButtonBack": "Back", "ButtonBack": "Back",
"ButtonCancel": "Cancel", "ButtonCancel": "Cancel",
"ButtonChangeServer": "Change Server", "ButtonChangeServer": "Change Server",
"ButtonEdit": "Edit",
"ButtonEditImages": "Edit images",
"ButtonEditOtherUserPreferences": "Edit this user's profile, image and personal preferences.", "ButtonEditOtherUserPreferences": "Edit this user's profile, image and personal preferences.",
"ButtonFilter": "Filter",
"ButtonForgotPassword": "Forgot Password", "ButtonForgotPassword": "Forgot Password",
"ButtonFullscreen": "Fullscreen", "ButtonFullscreen": "Fullscreen",
"ButtonGotIt": "Got It", "ButtonGotIt": "Got It",
"ButtonGuide": "Guide", "ButtonGuide": "Guide",
"ButtonHome": "Home",
"ButtonInfo": "Info", "ButtonInfo": "Info",
"ButtonLibraryAccess": "Library access", "ButtonLibraryAccess": "Library access",
"ButtonManualLogin": "Manual Login", "ButtonManualLogin": "Manual Login",
"ButtonMore": "More", "ButtonMore": "More",
"ButtonNetwork": "Network", "ButtonNetwork": "Network",
"ButtonNextTrack": "Next track", "ButtonNextTrack": "Next track",
"ButtonOff": "Off",
"ButtonOk": "OK", "ButtonOk": "OK",
"ButtonOpen": "Open", "ButtonOpen": "Open",
"ButtonParentalControl": "Parental control", "ButtonParentalControl": "Parental control",
"ButtonPause": "Pause", "ButtonPause": "Pause",
"ButtonPlay": "Play",
"ButtonPreviousTrack": "Previous track", "ButtonPreviousTrack": "Previous track",
"ButtonProfile": "Profile", "ButtonProfile": "Profile",
"ButtonQuickStartGuide": "Quick Start Guide", "ButtonQuickStartGuide": "Quick Start Guide",
"ButtonRefresh": "Refresh",
"ButtonRefreshGuideData": "Refresh Guide Data", "ButtonRefreshGuideData": "Refresh Guide Data",
"ButtonRemove": "Remove", "ButtonRemove": "Remove",
"ButtonRename": "Rename", "ButtonRename": "Rename",
@ -150,7 +143,6 @@
"ButtonStart": "Start", "ButtonStart": "Start",
"ButtonStop": "Stop", "ButtonStop": "Stop",
"ButtonSubmit": "Submit", "ButtonSubmit": "Submit",
"ButtonSubtitles": "Subtitles",
"ButtonTrailer": "Trailer", "ButtonTrailer": "Trailer",
"ButtonUninstall": "Uninstall", "ButtonUninstall": "Uninstall",
"ButtonWebsite": "Website", "ButtonWebsite": "Website",
@ -231,9 +223,7 @@
"EnablePhotosHelp": "Images will be detected and displayed alongside other media files.", "EnablePhotosHelp": "Images will be detected and displayed alongside other media files.",
"EnableStreamLooping": "Auto-loop live streams", "EnableStreamLooping": "Auto-loop live streams",
"EnableStreamLoopingHelp": "Enable this if live streams only contain a few seconds of data and need to be continuously requested. Enabling this when not needed may cause problems.", "EnableStreamLoopingHelp": "Enable this if live streams only contain a few seconds of data and need to be continuously requested. Enabling this when not needed may cause problems.",
"EnableThemeSongs": "Theme songs",
"EnableThemeSongsHelp": "Play theme songs in the background while browsing the library.", "EnableThemeSongsHelp": "Play theme songs in the background while browsing the library.",
"EnableThemeVideos": "Theme videos",
"EnableThemeVideosHelp": "Play theme videos in the background while browsing the library.", "EnableThemeVideosHelp": "Play theme videos in the background while browsing the library.",
"Ended": "Ended", "Ended": "Ended",
"EndsAtValue": "Ends at {0}", "EndsAtValue": "Ends at {0}",
@ -285,11 +275,9 @@
"HeaderActiveDevices": "Active Devices", "HeaderActiveDevices": "Active Devices",
"HeaderActiveRecordings": "Active Recordings", "HeaderActiveRecordings": "Active Recordings",
"HeaderActivity": "Activity", "HeaderActivity": "Activity",
"HeaderAddScheduledTaskTrigger": "Add Trigger",
"HeaderAddToCollection": "Add to Collection", "HeaderAddToCollection": "Add to Collection",
"HeaderAddToPlaylist": "Add to Playlist", "HeaderAddToPlaylist": "Add to Playlist",
"HeaderAddUpdateImage": "Add/Update Image", "HeaderAddUpdateImage": "Add/Update Image",
"HeaderAddUser": "Add User",
"HeaderAdditionalParts": "Additional Parts", "HeaderAdditionalParts": "Additional Parts",
"HeaderAdmin": "Admin", "HeaderAdmin": "Admin",
"HeaderAlert": "Alert", "HeaderAlert": "Alert",
@ -301,12 +289,10 @@
"HeaderAppearsOn": "Appears On", "HeaderAppearsOn": "Appears On",
"HeaderAudioBooks": "Audio Books", "HeaderAudioBooks": "Audio Books",
"HeaderAudioSettings": "Audio Settings", "HeaderAudioSettings": "Audio Settings",
"HeaderBooks": "Books",
"HeaderBranding": "Branding", "HeaderBranding": "Branding",
"HeaderCancelRecording": "Cancel Recording", "HeaderCancelRecording": "Cancel Recording",
"HeaderCancelSeries": "Cancel Series", "HeaderCancelSeries": "Cancel Series",
"HeaderCastAndCrew": "Cast & Crew", "HeaderCastAndCrew": "Cast & Crew",
"HeaderCastCrew": "Cast & Crew",
"HeaderChannelAccess": "Channel Access", "HeaderChannelAccess": "Channel Access",
"HeaderChapterImages": "Chapter Images", "HeaderChapterImages": "Chapter Images",
"HeaderCodecProfile": "Codec Profile", "HeaderCodecProfile": "Codec Profile",
@ -339,7 +325,6 @@
"HeaderEditImages": "Edit Images", "HeaderEditImages": "Edit Images",
"HeaderEnabledFields": "Enabled Fields", "HeaderEnabledFields": "Enabled Fields",
"HeaderEnabledFieldsHelp": "Uncheck a field to lock it and prevent its data from being changed.", "HeaderEnabledFieldsHelp": "Uncheck a field to lock it and prevent its data from being changed.",
"HeaderEpisodes": "Episodes",
"HeaderError": "Error", "HeaderError": "Error",
"HeaderExternalIds": "External IDs:", "HeaderExternalIds": "External IDs:",
"HeaderFavoriteBooks": "Favourite Books", "HeaderFavoriteBooks": "Favourite Books",
@ -355,7 +340,6 @@
"HeaderFetchImages": "Fetch Images:", "HeaderFetchImages": "Fetch Images:",
"HeaderFetcherSettings": "Fetcher Settings", "HeaderFetcherSettings": "Fetcher Settings",
"HeaderForKids": "For Kids", "HeaderForKids": "For Kids",
"HeaderForgotPassword": "Forgot Password",
"HeaderFrequentlyPlayed": "Frequently Played", "HeaderFrequentlyPlayed": "Frequently Played",
"HeaderGuideProviders": "TV Guide Data Providers", "HeaderGuideProviders": "TV Guide Data Providers",
"HeaderHttpHeaders": "HTTP Headers", "HeaderHttpHeaders": "HTTP Headers",
@ -384,7 +368,6 @@
"HeaderLoginFailure": "Login Failure", "HeaderLoginFailure": "Login Failure",
"HeaderMedia": "Media", "HeaderMedia": "Media",
"HeaderMediaFolders": "Media Folders", "HeaderMediaFolders": "Media Folders",
"HeaderMediaInfo": "Media Info",
"HeaderMetadataSettings": "Metadata Settings", "HeaderMetadataSettings": "Metadata Settings",
"HeaderMoreLikeThis": "More Like This", "HeaderMoreLikeThis": "More Like This",
"HeaderMusicQuality": "Music Quality", "HeaderMusicQuality": "Music Quality",
@ -443,17 +426,14 @@
"TabSettings": "Settings", "TabSettings": "Settings",
"TabServer": "Server", "TabServer": "Server",
"TabScheduledTasks": "Scheduled Tasks", "TabScheduledTasks": "Scheduled Tasks",
"TabResumeSettings": "Resume",
"TabResponses": "Responses", "TabResponses": "Responses",
"TabOther": "Other", "TabOther": "Other",
"TabNotifications": "Notifications", "TabNotifications": "Notifications",
"TabNetworks": "Networks", "TabNetworks": "Networks",
"TabMyPlugins": "My Plugins", "TabMyPlugins": "My Plugins",
"TabMusicVideos": "Music Videos",
"TabMusic": "Music", "TabMusic": "Music",
"TabLogs": "Logs", "TabLogs": "Logs",
"TabDirectPlay": "Direct Play", "TabDirectPlay": "Direct Play",
"TabAlbumArtists": "Album Artists",
"TabAdvanced": "Advanced", "TabAdvanced": "Advanced",
"TabAccess": "Access", "TabAccess": "Access",
"TV": "TV", "TV": "TV",
@ -723,22 +703,18 @@
"LabelTypeText": "Text", "LabelTypeText": "Text",
"LabelTunerIpAddress": "Tuner IP Address:", "LabelTunerIpAddress": "Tuner IP Address:",
"LabelTriggerType": "Trigger Type:", "LabelTriggerType": "Trigger Type:",
"LabelTranscodingVideoCodec": "Video codec:",
"LabelTranscodingThreadCountHelp": "Select the maximum number of threads to use when transcoding. Reducing the thread count will lower CPU usage but may not convert fast enough for a smooth playback experience.", "LabelTranscodingThreadCountHelp": "Select the maximum number of threads to use when transcoding. Reducing the thread count will lower CPU usage but may not convert fast enough for a smooth playback experience.",
"LabelTranscodingThreadCount": "Transcoding thread count:", "LabelTranscodingThreadCount": "Transcoding thread count:",
"LabelTranscodingFramerate": "Transcoding framerate:", "LabelTranscodingFramerate": "Transcoding framerate:",
"LabelTranscodes": "Transcodes:", "LabelTranscodes": "Transcodes:",
"LabelTranscodingTempPathHelp": "Specify a custom path for the transcode files served to clients. Leave blank to use the server default.", "LabelTranscodingTempPathHelp": "Specify a custom path for the transcode files served to clients. Leave blank to use the server default.",
"LabelTranscodePath": "Transcode path:", "LabelTranscodePath": "Transcode path:",
"LabelTranscodingContainer": "Container:",
"LabelTranscodingAudioCodec": "Audio codec:",
"LabelTrackNumber": "Track number:", "LabelTrackNumber": "Track number:",
"LabelTitle": "Title:", "LabelTitle": "Title:",
"LabelTagline": "Tagline:", "LabelTagline": "Tagline:",
"LabelTag": "Tag:", "LabelTag": "Tag:",
"LabelTVHomeScreen": "TV mode home screen:", "LabelTVHomeScreen": "TV mode home screen:",
"LabelSupportedMediaTypes": "Supported Media Types:", "LabelSupportedMediaTypes": "Supported Media Types:",
"LabelSubtitles": "Subtitles",
"LabelSubtitlePlaybackMode": "Subtitle mode:", "LabelSubtitlePlaybackMode": "Subtitle mode:",
"LabelSubtitleFormatHelp": "Example: srt", "LabelSubtitleFormatHelp": "Example: srt",
"LabelSubtitleDownloaders": "Subtitle downloaders:", "LabelSubtitleDownloaders": "Subtitle downloaders:",
@ -778,7 +754,6 @@
"LabelPublicHttpPortHelp": "The public port number that should be mapped to the local HTTP port.", "LabelPublicHttpPortHelp": "The public port number that should be mapped to the local HTTP port.",
"LabelPublicHttpPort": "Public HTTP port number:", "LabelPublicHttpPort": "Public HTTP port number:",
"LabelMetadataDownloadersHelp": "Enable and rank your preferred metadata downloaders in order of priority. Lower priority downloaders will only be used to fill in missing information.", "LabelMetadataDownloadersHelp": "Enable and rank your preferred metadata downloaders in order of priority. Lower priority downloaders will only be used to fill in missing information.",
"LabelDisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons",
"LabelDidlMode": "DIDL mode:", "LabelDidlMode": "DIDL mode:",
"LabelDefaultUser": "Default user:", "LabelDefaultUser": "Default user:",
"LabelDefaultScreen": "Default screen:", "LabelDefaultScreen": "Default screen:",
@ -876,7 +851,6 @@
"TagsValue": "Tags: {0}", "TagsValue": "Tags: {0}",
"Tags": "Tags", "Tags": "Tags",
"TabUpcoming": "Upcoming", "TabUpcoming": "Upcoming",
"TabTrailers": "Trailers",
"LabelDisplayMode": "Display mode:", "LabelDisplayMode": "Display mode:",
"LabelDisplayLanguageHelp": "Translating Jellyfin is an ongoing project.", "LabelDisplayLanguageHelp": "Translating Jellyfin is an ongoing project.",
"LabelDisplayLanguage": "Display language:", "LabelDisplayLanguage": "Display language:",
@ -890,8 +864,6 @@
"TabNfoSettings": "NFO Settings", "TabNfoSettings": "NFO Settings",
"TabNetworking": "Networking", "TabNetworking": "Networking",
"TabLatest": "Latest", "TabLatest": "Latest",
"TabInfo": "Info",
"TabEpisodes": "Episodes",
"TabDashboard": "Dashboard", "TabDashboard": "Dashboard",
"TabContainers": "Containers", "TabContainers": "Containers",
"TabCodecs": "Codecs", "TabCodecs": "Codecs",
@ -956,7 +928,6 @@
"LabelProfileCodecsHelp": "Separated by comma. This can be left empty to apply to all codecs.", "LabelProfileCodecsHelp": "Separated by comma. This can be left empty to apply to all codecs.",
"LabelProfileAudioCodecs": "Audio codecs:", "LabelProfileAudioCodecs": "Audio codecs:",
"LabelPreferredSubtitleLanguage": "Preferred subtitle language:", "LabelPreferredSubtitleLanguage": "Preferred subtitle language:",
"LabelPreferredDisplayLanguageHelp": "Translating Jellyfin is an ongoing project.",
"LabelPreferredDisplayLanguage": "Preferred display language:", "LabelPreferredDisplayLanguage": "Preferred display language:",
"LabelPostProcessor": "Post-processing application:", "LabelPostProcessor": "Post-processing application:",
"LabelPlayer": "Player:", "LabelPlayer": "Player:",
@ -1058,7 +1029,6 @@
"LabelDisplayOrder": "Display order:", "LabelDisplayOrder": "Display order:",
"LabelDisplayName": "Display name:", "LabelDisplayName": "Display name:",
"LabelDateAddedBehaviorHelp": "If a metadata value is present it will always be used before either of these options.", "LabelDateAddedBehaviorHelp": "If a metadata value is present it will always be used before either of these options.",
"LabelCustomDeviceDisplayName": "Display name:",
"LabelCustomCss": "Custom CSS:", "LabelCustomCss": "Custom CSS:",
"LabelCustomCertificatePathHelp": "Path to a PKCS #12 file containing a certificate and private key to enable TLS support on a custom domain.", "LabelCustomCertificatePathHelp": "Path to a PKCS #12 file containing a certificate and private key to enable TLS support on a custom domain.",
"LabelCurrentPassword": "Current password:", "LabelCurrentPassword": "Current password:",
@ -1083,7 +1053,6 @@
"LabelAudioChannels": "Audio channels:", "LabelAudioChannels": "Audio channels:",
"LabelAudioBitrate": "Audio bitrate:", "LabelAudioBitrate": "Audio bitrate:",
"LabelAudioBitDepth": "Audio bit depth:", "LabelAudioBitDepth": "Audio bit depth:",
"LabelAudio": "Audio",
"LabelArtistsHelp": "Separate multiple using ;", "LabelArtistsHelp": "Separate multiple using ;",
"LabelArtists": "Artists:", "LabelArtists": "Artists:",
"LabelAppName": "App name", "LabelAppName": "App name",
@ -1274,7 +1243,6 @@
"OptionBlockMusic": "Music", "OptionBlockMusic": "Music",
"OptionBlockLiveTvChannels": "Live TV Channels", "OptionBlockLiveTvChannels": "Live TV Channels",
"OptionBlockBooks": "Books", "OptionBlockBooks": "Books",
"OptionAutomatic": "Auto",
"OptionAuto": "Auto", "OptionAuto": "Auto",
"OptionAscending": "Ascending", "OptionAscending": "Ascending",
"OptionAdminUsers": "Administrators", "OptionAdminUsers": "Administrators",
@ -1286,7 +1254,6 @@
"MessageYouHaveVersionInstalled": "You currently have version {0} installed.", "MessageYouHaveVersionInstalled": "You currently have version {0} installed.",
"MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please ensure it is running and try again.", "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please ensure it is running and try again.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "The following media locations will be removed from your library:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "The following media locations will be removed from your library:",
"MessageSettingsSaved": "Settings saved.",
"MessageReenableUser": "See below to reenable", "MessageReenableUser": "See below to reenable",
"MessageLeaveEmptyToInherit": "Leave empty to inherit settings from a parent item or the global default value.", "MessageLeaveEmptyToInherit": "Leave empty to inherit settings from a parent item or the global default value.",
"MessageItemsAdded": "Items added.", "MessageItemsAdded": "Items added.",
@ -1350,7 +1317,6 @@
"HeaderPlayAll": "Play All", "HeaderPlayAll": "Play All",
"HeaderPinCodeReset": "Reset Pin Code", "HeaderPinCodeReset": "Reset Pin Code",
"HeaderPhotoAlbums": "Photo Albums", "HeaderPhotoAlbums": "Photo Albums",
"HeaderHome": "Home",
"HeaderFavoritePeople": "Favourite People", "HeaderFavoritePeople": "Favourite People",
"FetchingData": "Fetching additional data", "FetchingData": "Fetching additional data",
"ButtonAddImage": "Add Image", "ButtonAddImage": "Add Image",

View file

@ -71,31 +71,24 @@
"ButtonBack": "Back", "ButtonBack": "Back",
"ButtonCancel": "Cancel", "ButtonCancel": "Cancel",
"ButtonChangeServer": "Change Server", "ButtonChangeServer": "Change Server",
"ButtonEdit": "Edit",
"ButtonEditImages": "Edit images",
"ButtonEditOtherUserPreferences": "Edit this user's profile, image and personal preferences.", "ButtonEditOtherUserPreferences": "Edit this user's profile, image and personal preferences.",
"ButtonFilter": "Filter",
"ButtonForgotPassword": "Forgot Password", "ButtonForgotPassword": "Forgot Password",
"ButtonFullscreen": "Fullscreen", "ButtonFullscreen": "Fullscreen",
"ButtonGotIt": "Got It", "ButtonGotIt": "Got It",
"ButtonGuide": "Guide", "ButtonGuide": "Guide",
"ButtonHome": "Home",
"ButtonInfo": "Info", "ButtonInfo": "Info",
"ButtonLibraryAccess": "Library access", "ButtonLibraryAccess": "Library access",
"ButtonManualLogin": "Manual Login", "ButtonManualLogin": "Manual Login",
"ButtonMore": "More", "ButtonMore": "More",
"ButtonNetwork": "Network", "ButtonNetwork": "Network",
"ButtonNextTrack": "Next track", "ButtonNextTrack": "Next track",
"ButtonOff": "Off",
"ButtonOk": "Ok", "ButtonOk": "Ok",
"ButtonOpen": "Open", "ButtonOpen": "Open",
"ButtonParentalControl": "Parental control", "ButtonParentalControl": "Parental control",
"ButtonPause": "Pause", "ButtonPause": "Pause",
"ButtonPlay": "Play",
"ButtonPreviousTrack": "Previous track", "ButtonPreviousTrack": "Previous track",
"ButtonProfile": "Profile", "ButtonProfile": "Profile",
"ButtonQuickStartGuide": "Quick Start Guide", "ButtonQuickStartGuide": "Quick Start Guide",
"ButtonRefresh": "Refresh",
"ButtonRefreshGuideData": "Refresh Guide Data", "ButtonRefreshGuideData": "Refresh Guide Data",
"ButtonRemove": "Remove", "ButtonRemove": "Remove",
"ButtonRename": "Rename", "ButtonRename": "Rename",
@ -117,7 +110,6 @@
"ButtonStop": "Stop", "ButtonStop": "Stop",
"ButtonSplit": "Split", "ButtonSplit": "Split",
"ButtonSubmit": "Submit", "ButtonSubmit": "Submit",
"ButtonSubtitles": "Subtitles",
"ButtonTogglePlaylist": "Playlist", "ButtonTogglePlaylist": "Playlist",
"ButtonTrailer": "Trailer", "ButtonTrailer": "Trailer",
"ButtonUninstall": "Uninstall", "ButtonUninstall": "Uninstall",
@ -213,9 +205,7 @@
"EnablePhotosHelp": "Images will be detected and displayed alongside other media files.", "EnablePhotosHelp": "Images will be detected and displayed alongside other media files.",
"EnableStreamLooping": "Auto-loop live streams", "EnableStreamLooping": "Auto-loop live streams",
"EnableStreamLoopingHelp": "Enable this if live streams only contain a few seconds of data and need to be continuously requested. Enabling this when not needed may cause problems.", "EnableStreamLoopingHelp": "Enable this if live streams only contain a few seconds of data and need to be continuously requested. Enabling this when not needed may cause problems.",
"EnableThemeSongs": "Theme songs",
"EnableThemeSongsHelp": "Play theme songs in the background while browsing the library.", "EnableThemeSongsHelp": "Play theme songs in the background while browsing the library.",
"EnableThemeVideos": "Theme videos",
"EnableThemeVideosHelp": "Play theme videos in the background while browsing the library.", "EnableThemeVideosHelp": "Play theme videos in the background while browsing the library.",
"EnableDetailsBanner": "Details Banner", "EnableDetailsBanner": "Details Banner",
"EnableDetailsBannerHelp": "Display a banner image at the top of the item details page.", "EnableDetailsBannerHelp": "Display a banner image at the top of the item details page.",
@ -276,11 +266,9 @@
"HeaderActiveDevices": "Active Devices", "HeaderActiveDevices": "Active Devices",
"HeaderActiveRecordings": "Active Recordings", "HeaderActiveRecordings": "Active Recordings",
"HeaderActivity": "Activity", "HeaderActivity": "Activity",
"HeaderAddScheduledTaskTrigger": "Add Trigger",
"HeaderAddToCollection": "Add to Collection", "HeaderAddToCollection": "Add to Collection",
"HeaderAddToPlaylist": "Add to Playlist", "HeaderAddToPlaylist": "Add to Playlist",
"HeaderAddUpdateImage": "Add/Update Image", "HeaderAddUpdateImage": "Add/Update Image",
"HeaderAddUser": "Add User",
"HeaderAdditionalParts": "Additional Parts", "HeaderAdditionalParts": "Additional Parts",
"HeaderAdmin": "Admin", "HeaderAdmin": "Admin",
"HeaderAlbumArtists": "Album Artists", "HeaderAlbumArtists": "Album Artists",
@ -295,12 +283,10 @@
"HeaderAudioBooks": "Audio Books", "HeaderAudioBooks": "Audio Books",
"HeaderAudioSettings": "Audio Settings", "HeaderAudioSettings": "Audio Settings",
"HeaderBlockItemsWithNoRating": "Block items with no or unrecognized rating information:", "HeaderBlockItemsWithNoRating": "Block items with no or unrecognized rating information:",
"HeaderBooks": "Books",
"HeaderBranding": "Branding", "HeaderBranding": "Branding",
"HeaderCancelRecording": "Cancel Recording", "HeaderCancelRecording": "Cancel Recording",
"HeaderCancelSeries": "Cancel Series", "HeaderCancelSeries": "Cancel Series",
"HeaderCastAndCrew": "Cast & Crew", "HeaderCastAndCrew": "Cast & Crew",
"HeaderCastCrew": "Cast & Crew",
"HeaderChannelAccess": "Channel Access", "HeaderChannelAccess": "Channel Access",
"HeaderChapterImages": "Chapter Images", "HeaderChapterImages": "Chapter Images",
"HeaderCodecProfile": "Codec Profile", "HeaderCodecProfile": "Codec Profile",
@ -335,7 +321,6 @@
"HeaderEditImages": "Edit Images", "HeaderEditImages": "Edit Images",
"HeaderEnabledFields": "Enabled Fields", "HeaderEnabledFields": "Enabled Fields",
"HeaderEnabledFieldsHelp": "Uncheck a field to lock it and prevent its data from being changed.", "HeaderEnabledFieldsHelp": "Uncheck a field to lock it and prevent its data from being changed.",
"HeaderEpisodes": "Episodes",
"HeaderError": "Error", "HeaderError": "Error",
"HeaderExternalIds": "External IDs:", "HeaderExternalIds": "External IDs:",
"HeaderFavoriteBooks": "Favorite Books", "HeaderFavoriteBooks": "Favorite Books",
@ -352,10 +337,8 @@
"HeaderFetchImages": "Fetch Images:", "HeaderFetchImages": "Fetch Images:",
"HeaderFetcherSettings": "Fetcher Settings", "HeaderFetcherSettings": "Fetcher Settings",
"HeaderForKids": "For Kids", "HeaderForKids": "For Kids",
"HeaderForgotPassword": "Forgot Password",
"HeaderFrequentlyPlayed": "Frequently Played", "HeaderFrequentlyPlayed": "Frequently Played",
"HeaderGuideProviders": "TV Guide Data Providers", "HeaderGuideProviders": "TV Guide Data Providers",
"HeaderHome": "Home",
"HeaderHttpHeaders": "HTTP Headers", "HeaderHttpHeaders": "HTTP Headers",
"HeaderHttpsSettings": "HTTPS Settings", "HeaderHttpsSettings": "HTTPS Settings",
"HeaderIdentification": "Identification", "HeaderIdentification": "Identification",
@ -383,7 +366,6 @@
"HeaderLoginFailure": "Login Failure", "HeaderLoginFailure": "Login Failure",
"HeaderMedia": "Media", "HeaderMedia": "Media",
"HeaderMediaFolders": "Media Folders", "HeaderMediaFolders": "Media Folders",
"HeaderMediaInfo": "Media Info",
"HeaderMetadataSettings": "Metadata Settings", "HeaderMetadataSettings": "Metadata Settings",
"HeaderMoreLikeThis": "More Like This", "HeaderMoreLikeThis": "More Like This",
"HeaderMusicQuality": "Music Quality", "HeaderMusicQuality": "Music Quality",
@ -521,7 +503,6 @@
"LabelAppNameExample": "Example: Sickbeard, Sonarr", "LabelAppNameExample": "Example: Sickbeard, Sonarr",
"LabelArtists": "Artists:", "LabelArtists": "Artists:",
"LabelArtistsHelp": "Separate multiple artists with a semicolon.", "LabelArtistsHelp": "Separate multiple artists with a semicolon.",
"LabelAudio": "Audio",
"LabelAudioBitDepth": "Audio bit depth:", "LabelAudioBitDepth": "Audio bit depth:",
"LabelAudioBitrate": "Audio bitrate:", "LabelAudioBitrate": "Audio bitrate:",
"LabelAudioChannels": "Audio channels:", "LabelAudioChannels": "Audio channels:",
@ -557,7 +538,6 @@
"LabelCustomCertificatePathHelp": "Path to a PKCS #12 file containing a certificate and private key to enable TLS support on a custom domain.", "LabelCustomCertificatePathHelp": "Path to a PKCS #12 file containing a certificate and private key to enable TLS support on a custom domain.",
"LabelCustomCss": "Custom CSS:", "LabelCustomCss": "Custom CSS:",
"LabelCustomCssHelp": "Apply your own custom styles on the web interface.", "LabelCustomCssHelp": "Apply your own custom styles on the web interface.",
"LabelCustomDeviceDisplayName": "Display name:",
"LabelCustomDeviceDisplayNameHelp": "Supply a custom display name or leave empty to use the name reported by the device.", "LabelCustomDeviceDisplayNameHelp": "Supply a custom display name or leave empty to use the name reported by the device.",
"LabelCustomRating": "Custom rating:", "LabelCustomRating": "Custom rating:",
"LabelDateAdded": "Date added:", "LabelDateAdded": "Date added:",
@ -575,7 +555,6 @@
"LabelDiscNumber": "Disc number:", "LabelDiscNumber": "Disc number:",
"LabelDisplayLanguage": "Display language:", "LabelDisplayLanguage": "Display language:",
"LabelDisplayLanguageHelp": "Translating Jellyfin is an ongoing project.", "LabelDisplayLanguageHelp": "Translating Jellyfin is an ongoing project.",
"LabelDisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons",
"LabelDisplayMode": "Display mode:", "LabelDisplayMode": "Display mode:",
"LabelDisplayName": "Display name:", "LabelDisplayName": "Display name:",
"LabelDisplayOrder": "Display order:", "LabelDisplayOrder": "Display order:",
@ -747,7 +726,6 @@
"LabelPostProcessorArguments": "Post-processor command line arguments:", "LabelPostProcessorArguments": "Post-processor command line arguments:",
"LabelPostProcessorArgumentsHelp": "Use {path} as the path to the recording file.", "LabelPostProcessorArgumentsHelp": "Use {path} as the path to the recording file.",
"LabelPreferredDisplayLanguage": "Preferred display language:", "LabelPreferredDisplayLanguage": "Preferred display language:",
"LabelPreferredDisplayLanguageHelp": "Translating Jellyfin is an ongoing project.",
"LabelPreferredSubtitleLanguage": "Preferred subtitle language:", "LabelPreferredSubtitleLanguage": "Preferred subtitle language:",
"LabelProfileAudioCodecs": "Audio codecs:", "LabelProfileAudioCodecs": "Audio codecs:",
"LabelProfileCodecs": "Codecs:", "LabelProfileCodecs": "Codecs:",
@ -814,7 +792,6 @@
"LabelSubtitleDownloaders": "Subtitle downloaders:", "LabelSubtitleDownloaders": "Subtitle downloaders:",
"LabelSubtitleFormatHelp": "Example: srt", "LabelSubtitleFormatHelp": "Example: srt",
"LabelSubtitlePlaybackMode": "Subtitle mode:", "LabelSubtitlePlaybackMode": "Subtitle mode:",
"LabelSubtitles": "Subtitles",
"LabelSupportedMediaTypes": "Supported Media Types:", "LabelSupportedMediaTypes": "Supported Media Types:",
"LabelSyncPlayTimeOffset": "Time offset with the server:", "LabelSyncPlayTimeOffset": "Time offset with the server:",
"MillisecondsUnit": "ms", "MillisecondsUnit": "ms",
@ -839,8 +816,6 @@
"LabelTimeLimitHours": "Time limit (hours):", "LabelTimeLimitHours": "Time limit (hours):",
"LabelTitle": "Title:", "LabelTitle": "Title:",
"LabelTrackNumber": "Track number:", "LabelTrackNumber": "Track number:",
"LabelTranscodingAudioCodec": "Audio codec:",
"LabelTranscodingContainer": "Container:",
"LabelTranscodePath": "Transcode path:", "LabelTranscodePath": "Transcode path:",
"LabelTranscodingTempPathHelp": "Specify a custom path for the transcode files served to clients. Leave blank to use the server default.", "LabelTranscodingTempPathHelp": "Specify a custom path for the transcode files served to clients. Leave blank to use the server default.",
"LabelTranscodes": "Transcodes:", "LabelTranscodes": "Transcodes:",
@ -848,7 +823,6 @@
"LabelTranscodingProgress": "Transcoding progress:", "LabelTranscodingProgress": "Transcoding progress:",
"LabelTranscodingThreadCount": "Transcoding thread count:", "LabelTranscodingThreadCount": "Transcoding thread count:",
"LabelTranscodingThreadCountHelp": "Select the maximum number of threads to use when transcoding. Reducing the thread count will lower CPU usage but may not convert fast enough for a smooth playback experience.", "LabelTranscodingThreadCountHelp": "Select the maximum number of threads to use when transcoding. Reducing the thread count will lower CPU usage but may not convert fast enough for a smooth playback experience.",
"LabelTranscodingVideoCodec": "Video codec:",
"LabelTriggerType": "Trigger Type:", "LabelTriggerType": "Trigger Type:",
"LabelTunerIpAddress": "Tuner IP Address:", "LabelTunerIpAddress": "Tuner IP Address:",
"LabelTunerType": "Tuner type:", "LabelTunerType": "Tuner type:",
@ -986,7 +960,6 @@
"MessagePluginConfigurationRequiresLocalAccess": "To configure this plugin please sign in to your local server directly.", "MessagePluginConfigurationRequiresLocalAccess": "To configure this plugin please sign in to your local server directly.",
"MessagePluginInstallDisclaimer": "Plugins built by community members are a great way to enhance your experience with additional features and benefits. Before installing, please be aware of the effects they may have on your server, such as longer library scans, additional background processing, and decreased system stability.", "MessagePluginInstallDisclaimer": "Plugins built by community members are a great way to enhance your experience with additional features and benefits. Before installing, please be aware of the effects they may have on your server, such as longer library scans, additional background processing, and decreased system stability.",
"MessageReenableUser": "See below to reenable", "MessageReenableUser": "See below to reenable",
"MessageSettingsSaved": "Settings saved.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "The following media locations will be removed from your library:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "The following media locations will be removed from your library:",
"MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please ensure it is running and try again.", "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please ensure it is running and try again.",
"MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders.", "MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders.",
@ -1077,7 +1050,6 @@
"OptionArtist": "Artist", "OptionArtist": "Artist",
"OptionAscending": "Ascending", "OptionAscending": "Ascending",
"OptionAuto": "Auto", "OptionAuto": "Auto",
"OptionAutomatic": "Auto",
"OptionAutomaticallyGroupSeries": "Automatically merge series that are spread across multiple folders", "OptionAutomaticallyGroupSeries": "Automatically merge series that are spread across multiple folders",
"OptionAutomaticallyGroupSeriesHelp": "Series that are spread across multiple folders within this library will be automatically merged into a single series.", "OptionAutomaticallyGroupSeriesHelp": "Series that are spread across multiple folders within this library will be automatically merged into a single series.",
"OptionBanner": "Banner", "OptionBanner": "Banner",
@ -1220,6 +1192,7 @@
"Play": "Play", "Play": "Play",
"PlayAllFromHere": "Play all from here", "PlayAllFromHere": "Play all from here",
"PlaybackData": "Playback Data", "PlaybackData": "Playback Data",
"PlaybackRate": "Playback Rate",
"PlayCount": "Play count", "PlayCount": "Play count",
"PlayFromBeginning": "Play from beginning", "PlayFromBeginning": "Play from beginning",
"PlayNext": "Play next", "PlayNext": "Play next",
@ -1350,19 +1323,15 @@
"TV": "TV", "TV": "TV",
"TabAccess": "Access", "TabAccess": "Access",
"TabAdvanced": "Advanced", "TabAdvanced": "Advanced",
"TabAlbumArtists": "Album Artists",
"TabCatalog": "Catalog", "TabCatalog": "Catalog",
"TabRepositories": "Repositories", "TabRepositories": "Repositories",
"TabCodecs": "Codecs", "TabCodecs": "Codecs",
"TabContainers": "Containers", "TabContainers": "Containers",
"TabDashboard": "Dashboard", "TabDashboard": "Dashboard",
"TabDirectPlay": "Direct Play", "TabDirectPlay": "Direct Play",
"TabEpisodes": "Episodes",
"TabInfo": "Info",
"TabLatest": "Latest", "TabLatest": "Latest",
"TabLogs": "Logs", "TabLogs": "Logs",
"TabMusic": "Music", "TabMusic": "Music",
"TabMusicVideos": "Music Videos",
"TabMyPlugins": "My Plugins", "TabMyPlugins": "My Plugins",
"TabNetworks": "Networks", "TabNetworks": "Networks",
"TabNetworking": "Networking", "TabNetworking": "Networking",
@ -1374,12 +1343,10 @@
"TabProfile": "Profile", "TabProfile": "Profile",
"TabProfiles": "Profiles", "TabProfiles": "Profiles",
"TabResponses": "Responses", "TabResponses": "Responses",
"TabResumeSettings": "Resume",
"TabScheduledTasks": "Scheduled Tasks", "TabScheduledTasks": "Scheduled Tasks",
"TabServer": "Server", "TabServer": "Server",
"TabSettings": "Settings", "TabSettings": "Settings",
"TabStreaming": "Streaming", "TabStreaming": "Streaming",
"TabTrailers": "Trailers",
"TabUpcoming": "Upcoming", "TabUpcoming": "Upcoming",
"Tags": "Tags", "Tags": "Tags",
"TagsValue": "Tags: {0}", "TagsValue": "Tags: {0}",

View file

@ -3,9 +3,7 @@
"ButtonSignOut": "Cerrar sesión", "ButtonSignOut": "Cerrar sesión",
"EnableHardwareEncoding": "Habilitar la codificación de hardware", "EnableHardwareEncoding": "Habilitar la codificación de hardware",
"FolderTypeTvShows": "TV", "FolderTypeTvShows": "TV",
"HeaderAddUser": "Agregar Usuario",
"HeaderLatestEpisodes": "Últimos capítulos", "HeaderLatestEpisodes": "Últimos capítulos",
"LabelDisplayMissingEpisodesWithinSeasons": "Mostrar capítulos no disponibles en temporadas",
"LabelFinish": "Terminar", "LabelFinish": "Terminar",
"LabelYoureDone": "Ha terminado!", "LabelYoureDone": "Ha terminado!",
"MoreUsersCanBeAddedLater": "Se pueden agregar más usuarios más tarde desde el tablero.", "MoreUsersCanBeAddedLater": "Se pueden agregar más usuarios más tarde desde el tablero.",
@ -13,7 +11,6 @@
"OptionMissingEpisode": "Capítulos faltantes", "OptionMissingEpisode": "Capítulos faltantes",
"OptionUnairedEpisode": "Capítulos no emitidos", "OptionUnairedEpisode": "Capítulos no emitidos",
"ParentalRating": "Parental Rating", "ParentalRating": "Parental Rating",
"TabEpisodes": "Capítulos",
"TellUsAboutYourself": "Contanos acerca de vos", "TellUsAboutYourself": "Contanos acerca de vos",
"ThisWizardWillGuideYou": "Este asistente le ayudará a guiarlo durante el proceso de configuración. Para comenzar, seleccione su idioma preferido.", "ThisWizardWillGuideYou": "Este asistente le ayudará a guiarlo durante el proceso de configuración. Para comenzar, seleccione su idioma preferido.",
"UserProfilesIntro": "Jellyfin incluye soporte para perfiles de usuario con configuraciones de visualización granulares, estado de reproducción y controles parentales.", "UserProfilesIntro": "Jellyfin incluye soporte para perfiles de usuario con configuraciones de visualización granulares, estado de reproducción y controles parentales.",
@ -61,7 +58,7 @@
"AllowMediaConversionHelp": "Permitir o denegar acceso a la opción de convertir medios.", "AllowMediaConversionHelp": "Permitir o denegar acceso a la opción de convertir medios.",
"AllowOnTheFlySubtitleExtraction": "Permitir extracción de subtítulos al vuelo", "AllowOnTheFlySubtitleExtraction": "Permitir extracción de subtítulos al vuelo",
"AllowOnTheFlySubtitleExtractionHelp": "Los subtítulos incrustados se pueden extraer de los videos y entregar a los clientes en texto plano, para ayudar a evitar la transcodificación de videos. En algunos sistemas, esto puede llevar mucho tiempo y provocar que la reproducción de video se detenga durante el proceso de extracción. Deshabilite esto para que los subtítulos incrustados se graben con la transcodificación de video cuando el dispositivo cliente no los admite de forma nativa.", "AllowOnTheFlySubtitleExtractionHelp": "Los subtítulos incrustados se pueden extraer de los videos y entregar a los clientes en texto plano, para ayudar a evitar la transcodificación de videos. En algunos sistemas, esto puede llevar mucho tiempo y provocar que la reproducción de video se detenga durante el proceso de extracción. Deshabilite esto para que los subtítulos incrustados se graben con la transcodificación de video cuando el dispositivo cliente no los admite de forma nativa.",
"AllowRemoteAccess": "Permitir conexiones remotas a este servidor Jellyfin.", "AllowRemoteAccess": "Permitir conexiones remotas a este servidor.",
"AllowRemoteAccessHelp": "Si no está tildado, todas las conexiones remotas serán bloqueadas.", "AllowRemoteAccessHelp": "Si no está tildado, todas las conexiones remotas serán bloqueadas.",
"AlwaysPlaySubtitles": "Reproducir siempre", "AlwaysPlaySubtitles": "Reproducir siempre",
"AnyLanguage": "Cualquier idioma", "AnyLanguage": "Cualquier idioma",
@ -99,30 +96,23 @@
"ButtonBack": "Atrás", "ButtonBack": "Atrás",
"ButtonCancel": "Cancelar", "ButtonCancel": "Cancelar",
"ButtonChangeServer": "Cambiar servidor", "ButtonChangeServer": "Cambiar servidor",
"ButtonEdit": "Editar",
"ButtonEditImages": "Editar imágenes",
"ButtonEditOtherUserPreferences": "Editar perfil, imagen y preferencias personales del usuario.", "ButtonEditOtherUserPreferences": "Editar perfil, imagen y preferencias personales del usuario.",
"ButtonFilter": "Filtrar",
"ButtonForgotPassword": "Olvidé mi contraseña", "ButtonForgotPassword": "Olvidé mi contraseña",
"ButtonFullscreen": "Pantalla completa", "ButtonFullscreen": "Pantalla completa",
"ButtonGotIt": "Lo entendí", "ButtonGotIt": "Lo entendí",
"ButtonGuide": "Guía", "ButtonGuide": "Guía",
"ButtonHome": "Inicio",
"ButtonInfo": "Información", "ButtonInfo": "Información",
"ButtonLibraryAccess": "Acceso a la biblioteca", "ButtonLibraryAccess": "Acceso a la biblioteca",
"ButtonManualLogin": "Inicio de sesión manual", "ButtonManualLogin": "Inicio de sesión manual",
"ButtonMore": "Más", "ButtonMore": "Más",
"ButtonNetwork": "Red", "ButtonNetwork": "Red",
"ButtonNextTrack": "Pista siguiente", "ButtonNextTrack": "Pista siguiente",
"ButtonOff": "Desactivado",
"ButtonOk": "Aceptar", "ButtonOk": "Aceptar",
"ButtonOpen": "Abrir", "ButtonOpen": "Abrir",
"ButtonParentalControl": "Control parental", "ButtonParentalControl": "Control parental",
"ButtonPause": "Pausar", "ButtonPause": "Pausar",
"ButtonPlay": "Reproducir",
"ButtonPreviousTrack": "Pista anterior", "ButtonPreviousTrack": "Pista anterior",
"ButtonProfile": "Perfil", "ButtonProfile": "Perfil",
"ButtonRefresh": "Actualizar",
"ButtonRefreshGuideData": "Actualizar datos de la guía", "ButtonRefreshGuideData": "Actualizar datos de la guía",
"ButtonRemove": "Quitar", "ButtonRemove": "Quitar",
"ButtonRename": "Renombrar", "ButtonRename": "Renombrar",
@ -142,7 +132,6 @@
"ButtonStart": "Iniciar", "ButtonStart": "Iniciar",
"ButtonStop": "Detener", "ButtonStop": "Detener",
"ButtonSubmit": "Enviar", "ButtonSubmit": "Enviar",
"ButtonSubtitles": "Subtítulos",
"ButtonTrailer": "Avance", "ButtonTrailer": "Avance",
"ButtonUninstall": "Desinstalar", "ButtonUninstall": "Desinstalar",
"ButtonWebsite": "Sitio web", "ButtonWebsite": "Sitio web",
@ -159,7 +148,7 @@
"ColorTransfer": "Transferencia de color", "ColorTransfer": "Transferencia de color",
"CommunityRating": "Puntuación de la comunidad", "CommunityRating": "Puntuación de la comunidad",
"Composer": "Compositor", "Composer": "Compositor",
"ConfigureDateAdded": "Configura cómo se va a determinar las fechas de adición en la pestaña Bibliotecas del panel del servidor Jellyfin", "ConfigureDateAdded": "Configure cómo se determina la fecha agregada en el panel en la configuración de la biblioteca",
"ConfirmDeleteImage": "¿Eliminar imagen?", "ConfirmDeleteImage": "¿Eliminar imagen?",
"ConfirmDeleteItem": "Eliminar este elemento lo eliminará tanto del sistema de archivos como de la biblioteca de medios. ¿Está seguro que desea continuar?", "ConfirmDeleteItem": "Eliminar este elemento lo eliminará tanto del sistema de archivos como de la biblioteca de medios. ¿Está seguro que desea continuar?",
"ConfirmDeleteItems": "Eliminar estos elementos los eliminará tanto del sistema de archivos como de la biblioteca de medios. ¿Está seguro que desea continuar?", "ConfirmDeleteItems": "Eliminar estos elementos los eliminará tanto del sistema de archivos como de la biblioteca de medios. ¿Está seguro que desea continuar?",
@ -216,7 +205,7 @@
"EnableBackdropsHelp": "Muestra imágenes de fondo en el fondo de algunas páginas mientras se navega por la biblioteca.", "EnableBackdropsHelp": "Muestra imágenes de fondo en el fondo de algunas páginas mientras se navega por la biblioteca.",
"EnableCinemaMode": "Modo cine", "EnableCinemaMode": "Modo cine",
"EnableColorCodedBackgrounds": "Habilitar colores en el fondo del código", "EnableColorCodedBackgrounds": "Habilitar colores en el fondo del código",
"AuthProviderHelp": "Seleccione un proveedor de autenticación que se utilizará para autenticar la contraseña de este usuario.", "AuthProviderHelp": "Seleccione un proveedor de autenticación para ser utilizado para autenticar la contraseña de este usuario.",
"CriticRating": "Valoración crítica", "CriticRating": "Valoración crítica",
"DefaultSubtitlesHelp": "Los subtítulos se cargan según los indicadores predeterminados y forzados en los metadatos incrustados. Las preferencias de idioma se consideran cuando hay varias opciones disponibles.", "DefaultSubtitlesHelp": "Los subtítulos se cargan según los indicadores predeterminados y forzados en los metadatos incrustados. Las preferencias de idioma se consideran cuando hay varias opciones disponibles.",
"Dislike": "No me gusta", "Dislike": "No me gusta",
@ -229,9 +218,7 @@
"EnablePhotosHelp": "Las imágenes serán detectadas y mostradas junto con otros archivos multimedia.", "EnablePhotosHelp": "Las imágenes serán detectadas y mostradas junto con otros archivos multimedia.",
"EnableStreamLooping": "Repetir automáticamente transmisiones en vivo", "EnableStreamLooping": "Repetir automáticamente transmisiones en vivo",
"EnableStreamLoopingHelp": "Habilita esto sí las transmisiones en vivo sólo contienen unos cuantos segundos y es necesario solicitarlos continuamente. Habilitar esto cuando no es necesario puede causar problemas.", "EnableStreamLoopingHelp": "Habilita esto sí las transmisiones en vivo sólo contienen unos cuantos segundos y es necesario solicitarlos continuamente. Habilitar esto cuando no es necesario puede causar problemas.",
"EnableThemeSongs": "Canciones temáticas",
"EnableThemeSongsHelp": "Reproducir canciones temáticas en el fondo mientras se navega por la biblioteca.", "EnableThemeSongsHelp": "Reproducir canciones temáticas en el fondo mientras se navega por la biblioteca.",
"EnableThemeVideos": "Videos temáticos",
"EnableThemeVideosHelp": "Al habilitarse, los vídeos de tema se reproducirán de fondo mientras navegues por la biblioteca.", "EnableThemeVideosHelp": "Al habilitarse, los vídeos de tema se reproducirán de fondo mientras navegues por la biblioteca.",
"Ended": "Finalizado", "Ended": "Finalizado",
"EndsAtValue": "Termina en {0}", "EndsAtValue": "Termina en {0}",
@ -290,7 +277,6 @@
"AllowFfmpegThrottling": "Transcodificación Throttle", "AllowFfmpegThrottling": "Transcodificación Throttle",
"HeaderCancelRecording": "Cancelar Grabación", "HeaderCancelRecording": "Cancelar Grabación",
"HeaderBranding": "Marca", "HeaderBranding": "Marca",
"HeaderBooks": "Libros",
"HeaderBlockItemsWithNoRating": "Bloquear elementos con rating de información vacía o no reconocible:", "HeaderBlockItemsWithNoRating": "Bloquear elementos con rating de información vacía o no reconocible:",
"HeaderAudioSettings": "Configuraciones de audio", "HeaderAudioSettings": "Configuraciones de audio",
"HeaderAudioBooks": "Audiolibros", "HeaderAudioBooks": "Audiolibros",
@ -306,7 +292,6 @@
"HeaderAddUpdateImage": "Agregar/Actualizar imagen", "HeaderAddUpdateImage": "Agregar/Actualizar imagen",
"HeaderAddToPlaylist": "Agregar a la lista de reproducción", "HeaderAddToPlaylist": "Agregar a la lista de reproducción",
"HeaderAddToCollection": "Agregar a la Colección", "HeaderAddToCollection": "Agregar a la Colección",
"HeaderAddScheduledTaskTrigger": "Agregar disparador",
"HeaderActivity": "Actividad", "HeaderActivity": "Actividad",
"HeaderActiveRecordings": "Grabaciones activas", "HeaderActiveRecordings": "Grabaciones activas",
"HeaderActiveDevices": "Dispositivos activos", "HeaderActiveDevices": "Dispositivos activos",
@ -338,7 +323,6 @@
"HeaderCodecProfile": "Perfil del códec", "HeaderCodecProfile": "Perfil del códec",
"HeaderChapterImages": "Imágenes del capitulo", "HeaderChapterImages": "Imágenes del capitulo",
"HeaderChannelAccess": "Acceso al canal", "HeaderChannelAccess": "Acceso al canal",
"HeaderCastCrew": "Reparto",
"HeaderCastAndCrew": "Reparto", "HeaderCastAndCrew": "Reparto",
"HeaderCancelSeries": "Cancelar serie", "HeaderCancelSeries": "Cancelar serie",
"H264CrfHelp": "El Factor de velocidad constante (CRF) es la configuración de calidad predeterminada para el codificador x264. Puede establecer los valores entre 0 y 51, donde valores más bajos resultarían en una mejor calidad (a expensas de tamaños de archivo más altos). Los valores correctos están entre 18 y 28. El valor predeterminado para x264 es 23, por lo que puede usar esto como punto de partida.", "H264CrfHelp": "El Factor de velocidad constante (CRF) es la configuración de calidad predeterminada para el codificador x264. Puede establecer los valores entre 0 y 51, donde valores más bajos resultarían en una mejor calidad (a expensas de tamaños de archivo más altos). Los valores correctos están entre 18 y 28. El valor predeterminado para x264 es 23, por lo que puede usar esto como punto de partida.",
@ -349,7 +333,6 @@
"HeaderFavoriteBooks": "Libros favoritos", "HeaderFavoriteBooks": "Libros favoritos",
"HeaderExternalIds": "IDs externos:", "HeaderExternalIds": "IDs externos:",
"HeaderError": "Error", "HeaderError": "Error",
"HeaderEpisodes": "Capítulos",
"HeaderEnabledFields": "Campos habilitados", "HeaderEnabledFields": "Campos habilitados",
"HeaderEditImages": "Editar imágenes", "HeaderEditImages": "Editar imágenes",
"HeaderEasyPinCode": "Código PIN fácil", "HeaderEasyPinCode": "Código PIN fácil",
@ -390,10 +373,8 @@
"HeaderIdentificationCriteriaHelp": "Ingrese al menos un criterio de identificación.", "HeaderIdentificationCriteriaHelp": "Ingrese al menos un criterio de identificación.",
"HeaderIdentification": "Identificación", "HeaderIdentification": "Identificación",
"HeaderHttpHeaders": "Encabezados HTTP", "HeaderHttpHeaders": "Encabezados HTTP",
"HeaderHome": "Inicio",
"HeaderGuideProviders": "Proveedores de datos de guías de TV", "HeaderGuideProviders": "Proveedores de datos de guías de TV",
"HeaderFrequentlyPlayed": "Reproducido con frecuencia", "HeaderFrequentlyPlayed": "Reproducido con frecuencia",
"HeaderForgotPassword": "Olvidé la contraseña",
"HeaderForKids": "Para niños", "HeaderForKids": "Para niños",
"HeaderFetcherSettings": "Configuración del recuperador", "HeaderFetcherSettings": "Configuración del recuperador",
"HeaderFetchImages": "Obtener imágenes:", "HeaderFetchImages": "Obtener imágenes:",
@ -510,7 +491,6 @@
"HeaderNextEpisodePlayingInValue": "Reproducción del siguiente capítulo en {0}", "HeaderNextEpisodePlayingInValue": "Reproducción del siguiente capítulo en {0}",
"HeaderMoreLikeThis": "Más como esto", "HeaderMoreLikeThis": "Más como esto",
"HeaderMetadataSettings": "Configuraciones de metadatos", "HeaderMetadataSettings": "Configuraciones de metadatos",
"HeaderMediaInfo": "Información de medios",
"HeaderHttpsSettings": "Configuraciones HTTPS", "HeaderHttpsSettings": "Configuraciones HTTPS",
"HeaderEnabledFieldsHelp": "Desmarque un campo para bloquearlo y evitar que se modifiquen sus datos.", "HeaderEnabledFieldsHelp": "Desmarque un campo para bloquearlo y evitar que se modifiquen sus datos.",
"HeaderDirectPlayProfileHelp": "Agregue perfiles de reproducción directa para indicar qué formatos puede manejar el dispositivo de forma nativa.", "HeaderDirectPlayProfileHelp": "Agregue perfiles de reproducción directa para indicar qué formatos puede manejar el dispositivo de forma nativa.",
@ -539,7 +519,6 @@
"LabelAudioCodec": "Códec de audio:", "LabelAudioCodec": "Códec de audio:",
"LabelAudioChannels": "Canales de audio:", "LabelAudioChannels": "Canales de audio:",
"LabelAudioBitrate": "Velocidad de bits de audio:", "LabelAudioBitrate": "Velocidad de bits de audio:",
"LabelAudio": "Audio",
"LabelAllowedRemoteAddresses": "Filtro de dirección IP remota:", "LabelAllowedRemoteAddresses": "Filtro de dirección IP remota:",
"LabelAllowHWTranscoding": "Permitir transcodificación con hardware", "LabelAllowHWTranscoding": "Permitir transcodificación con hardware",
"LabelAlbumArtists": "Artistas del álbum:", "LabelAlbumArtists": "Artistas del álbum:",
@ -639,7 +618,6 @@
"LabelDateAdded": "Fecha agregada:", "LabelDateAdded": "Fecha agregada:",
"LabelCustomRating": "Calificación personalizada:", "LabelCustomRating": "Calificación personalizada:",
"LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre personalizado para mostrar o déjelo vacío para usar el nombre informado por el dispositivo.", "LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre personalizado para mostrar o déjelo vacío para usar el nombre informado por el dispositivo.",
"LabelCustomDeviceDisplayName": "Nombre para mostrar:",
"LabelCustomCssHelp": "Aplique su propio estilo personalizado a la interfaz web.", "LabelCustomCssHelp": "Aplique su propio estilo personalizado a la interfaz web.",
"LabelCustomCss": "CSS personalizado:", "LabelCustomCss": "CSS personalizado:",
"LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS #12 que contiene un certificado y una clave privada para habilitar el soporte TLS en un dominio personalizado.", "LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS #12 que contiene un certificado y una clave privada para habilitar el soporte TLS en un dominio personalizado.",
@ -679,7 +657,6 @@
"MillisecondsUnit": "ms", "MillisecondsUnit": "ms",
"LabelSyncPlayTimeOffset": "Compensación horaria con el servidor:", "LabelSyncPlayTimeOffset": "Compensación horaria con el servidor:",
"LabelSupportedMediaTypes": "Tipos de medios soportados:", "LabelSupportedMediaTypes": "Tipos de medios soportados:",
"LabelSubtitles": "Subtítulos",
"LabelSubtitlePlaybackMode": "Modo de subtítulos:", "LabelSubtitlePlaybackMode": "Modo de subtítulos:",
"LabelSubtitleFormatHelp": "Ejemplo: srt", "LabelSubtitleFormatHelp": "Ejemplo: srt",
"LabelSubtitleDownloaders": "Descargadores de subtítulos:", "LabelSubtitleDownloaders": "Descargadores de subtítulos:",
@ -741,7 +718,6 @@
"LabelProfileCodecs": "Códecs:", "LabelProfileCodecs": "Códecs:",
"LabelProfileAudioCodecs": "Códecs de audio:", "LabelProfileAudioCodecs": "Códecs de audio:",
"LabelPreferredSubtitleLanguage": "Idioma de subtítulos preferido:", "LabelPreferredSubtitleLanguage": "Idioma de subtítulos preferido:",
"LabelPreferredDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en curso.",
"LabelPreferredDisplayLanguage": "Idioma de visualización preferido:", "LabelPreferredDisplayLanguage": "Idioma de visualización preferido:",
"LabelPostProcessorArgumentsHelp": "Use {ruta} como la ruta al archivo de grabación.", "LabelPostProcessorArgumentsHelp": "Use {ruta} como la ruta al archivo de grabación.",
"LabelPostProcessorArguments": "Argumentos de la línea de comando del post-procesador:", "LabelPostProcessorArguments": "Argumentos de la línea de comando del post-procesador:",
@ -829,7 +805,6 @@
"OptionBanner": "Pancarta", "OptionBanner": "Pancarta",
"OptionAutomaticallyGroupSeriesHelp": "Si está habilitado, las series que se distribuyen en varias carpetas dentro de esta biblioteca se fusionarán automáticamente en una sola serie.", "OptionAutomaticallyGroupSeriesHelp": "Si está habilitado, las series que se distribuyen en varias carpetas dentro de esta biblioteca se fusionarán automáticamente en una sola serie.",
"OptionAutomaticallyGroupSeries": "Combinar automáticamente series que se extienden a través de múltiples carpetas", "OptionAutomaticallyGroupSeries": "Combinar automáticamente series que se extienden a través de múltiples carpetas",
"OptionAutomatic": "Auto",
"OptionAuto": "Auto", "OptionAuto": "Auto",
"OptionAscending": "Ascendente", "OptionAscending": "Ascendente",
"OptionArtist": "Artista", "OptionArtist": "Artista",
@ -914,7 +889,6 @@
"MessageUnsetContentHelp": "El contenido se mostrará como carpetas simples. Para obtener mejores resultados, use el administrador de metadatos para configurar los tipos de contenido de las subcarpetas.", "MessageUnsetContentHelp": "El contenido se mostrará como carpetas simples. Para obtener mejores resultados, use el administrador de metadatos para configurar los tipos de contenido de las subcarpetas.",
"MessageUnableToConnectToServer": "No podemos conectarnos al servidor seleccionado en este momento. Asegúrese de que se esté ejecutando e intente nuevamente.", "MessageUnableToConnectToServer": "No podemos conectarnos al servidor seleccionado en este momento. Asegúrese de que se esté ejecutando e intente nuevamente.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Las siguientes ubicaciones de medios se eliminarán de su biblioteca:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Las siguientes ubicaciones de medios se eliminarán de su biblioteca:",
"MessageSettingsSaved": "Configuraciones guardadas.",
"MessageReenableUser": "Ver abajo para volver a habilitar", "MessageReenableUser": "Ver abajo para volver a habilitar",
"MessagePluginInstallDisclaimer": "Los complementos creados por miembros de la comunidad Jellyfin son una excelente manera de mejorar su experiencia Jellyfin con características y beneficios adicionales. Antes de la instalación, tenga en cuenta los efectos que pueden tener en su servidor Jellyfin, como escaneos de bibliotecas más largos, procesamiento en segundo plano adicional y disminución de la estabilidad del sistema.", "MessagePluginInstallDisclaimer": "Los complementos creados por miembros de la comunidad Jellyfin son una excelente manera de mejorar su experiencia Jellyfin con características y beneficios adicionales. Antes de la instalación, tenga en cuenta los efectos que pueden tener en su servidor Jellyfin, como escaneos de bibliotecas más largos, procesamiento en segundo plano adicional y disminución de la estabilidad del sistema.",
"MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento, inicie sesión directamente en su servidor local.", "MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento, inicie sesión directamente en su servidor local.",
@ -1042,7 +1016,6 @@
"LabelTunerType": "Tipo de sintonizador:", "LabelTunerType": "Tipo de sintonizador:",
"LabelTunerIpAddress": "Dirección IP del sintonizador:", "LabelTunerIpAddress": "Dirección IP del sintonizador:",
"LabelTriggerType": "Tipo de disparador:", "LabelTriggerType": "Tipo de disparador:",
"LabelTranscodingVideoCodec": "Códec de vídeo:",
"LabelTranscodingThreadCountHelp": "Elija el número máximo de hilos para usar al transcodificar. Reducir el recuento de hilos disminuirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido para una experiencia de reproducción fluida.", "LabelTranscodingThreadCountHelp": "Elija el número máximo de hilos para usar al transcodificar. Reducir el recuento de hilos disminuirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido para una experiencia de reproducción fluida.",
"LabelTranscodingThreadCount": "Conteo de hilos de transcodificación:", "LabelTranscodingThreadCount": "Conteo de hilos de transcodificación:",
"LabelTranscodingProgress": "Progreso de transcodificación:", "LabelTranscodingProgress": "Progreso de transcodificación:",
@ -1050,8 +1023,6 @@
"LabelTranscodes": "Transcodificaciones:", "LabelTranscodes": "Transcodificaciones:",
"LabelTranscodingTempPathHelp": "Especifique una ruta personalizada para los archivos de transcodificación servidos a los clientes. Déjelo en blanco para usar el servidor predeterminado.", "LabelTranscodingTempPathHelp": "Especifique una ruta personalizada para los archivos de transcodificación servidos a los clientes. Déjelo en blanco para usar el servidor predeterminado.",
"LabelTranscodePath": "Ruta para las transcodificaciones:", "LabelTranscodePath": "Ruta para las transcodificaciones:",
"LabelTranscodingContainer": "Contenedor:",
"LabelTranscodingAudioCodec": "Códec de audio:",
"LabelTrackNumber": "Número de pista:", "LabelTrackNumber": "Número de pista:",
"LabelTitle": "Título:", "LabelTitle": "Título:",
"LabelTimeLimitHours": "Límite de tiempo (horas):", "LabelTimeLimitHours": "Límite de tiempo (horas):",
@ -1363,12 +1334,10 @@
"MarkPlayed": "Marcar reproducido", "MarkPlayed": "Marcar reproducido",
"LabelSkipForwardLength": "Saltar hacia adelante longitud:", "LabelSkipForwardLength": "Saltar hacia adelante longitud:",
"Trailers": "Avances", "Trailers": "Avances",
"TabTrailers": "Avances",
"TabStreaming": "Transmisión", "TabStreaming": "Transmisión",
"TabSettings": "Configuraciones", "TabSettings": "Configuraciones",
"TabServer": "Servidor", "TabServer": "Servidor",
"TabScheduledTasks": "Tareas programadas", "TabScheduledTasks": "Tareas programadas",
"TabResumeSettings": "Continuar",
"TabResponses": "Respuestas", "TabResponses": "Respuestas",
"TabProfiles": "Perfiles", "TabProfiles": "Perfiles",
"TabProfile": "Perfil", "TabProfile": "Perfil",
@ -1380,18 +1349,15 @@
"TabNetworking": "Redes", "TabNetworking": "Redes",
"TabNetworks": "Redes", "TabNetworks": "Redes",
"TabMyPlugins": "Mis complementos", "TabMyPlugins": "Mis complementos",
"TabMusicVideos": "Videos musicales",
"TabMusic": "Música", "TabMusic": "Música",
"TabLogs": "Registros", "TabLogs": "Registros",
"TabLatest": "Último", "TabLatest": "Último",
"TabInfo": "Información",
"TabDirectPlay": "Reproducción directa", "TabDirectPlay": "Reproducción directa",
"TabDashboard": "Tablero", "TabDashboard": "Tablero",
"TabContainers": "Contenedores", "TabContainers": "Contenedores",
"TabCodecs": "Códecs", "TabCodecs": "Códecs",
"TabRepositories": "Repositorios", "TabRepositories": "Repositorios",
"TabCatalog": "Catálogo", "TabCatalog": "Catálogo",
"TabAlbumArtists": "Artistas del álbum",
"TabAdvanced": "Avanzado", "TabAdvanced": "Avanzado",
"TabAccess": "Acceso", "TabAccess": "Acceso",
"TV": "TV", "TV": "TV",
@ -1467,5 +1433,13 @@
"Writers": "Escritores", "Writers": "Escritores",
"ClearQueue": "Eliminar cola", "ClearQueue": "Eliminar cola",
"StopPlayback": "Detener reproducción", "StopPlayback": "Detener reproducción",
"ViewAlbumArtist": "Ver artista del álbum" "ViewAlbumArtist": "Ver artista del álbum",
"Preview": "Avance",
"SubtitleVerticalPositionHelp": "Número de línea donde aparece el texto. Los números positivos indican de arriba hacia abajo. Los números negativos indican de abajo hacia arriba.",
"LabelSubtitleVerticalPosition": "Posición vertical:",
"PreviousTrack": "Pasar al anterior",
"MessageGetInstalledPluginsError": "Se produjo un error al obtener la lista de complementos instalados actualmente.",
"MessagePluginInstallError": "Ocurrió un error al instalar el complemento.",
"NextTrack": "Pasar al siguiente",
"LabelUnstable": "Inestable"
} }

View file

@ -59,29 +59,22 @@
"ButtonBack": "Atrás", "ButtonBack": "Atrás",
"ButtonCancel": "Cancelar", "ButtonCancel": "Cancelar",
"ButtonChangeServer": "Cambiar servidor", "ButtonChangeServer": "Cambiar servidor",
"ButtonEdit": "Editar",
"ButtonEditImages": "Editar imágenes",
"ButtonEditOtherUserPreferences": "Editar el perfil, la imagen y las preferencias personales de este usuario.", "ButtonEditOtherUserPreferences": "Editar el perfil, la imagen y las preferencias personales de este usuario.",
"ButtonFilter": "Filtro",
"ButtonForgotPassword": "Olvidé mi contraseña", "ButtonForgotPassword": "Olvidé mi contraseña",
"ButtonFullscreen": "Pantalla completa", "ButtonFullscreen": "Pantalla completa",
"ButtonGotIt": "Hecho", "ButtonGotIt": "Hecho",
"ButtonGuide": "Guía", "ButtonGuide": "Guía",
"ButtonHome": "Inicio",
"ButtonLibraryAccess": "Acceso a biblioteca(s)", "ButtonLibraryAccess": "Acceso a biblioteca(s)",
"ButtonManualLogin": "Inicio de sesión manual", "ButtonManualLogin": "Inicio de sesión manual",
"ButtonMore": "Más", "ButtonMore": "Más",
"ButtonNetwork": "Red", "ButtonNetwork": "Red",
"ButtonNextTrack": "Pista siguiente", "ButtonNextTrack": "Pista siguiente",
"ButtonOff": "Apagar",
"ButtonOpen": "Abrir", "ButtonOpen": "Abrir",
"ButtonParentalControl": "Control parental", "ButtonParentalControl": "Control parental",
"ButtonPause": "Pausar", "ButtonPause": "Pausar",
"ButtonPlay": "Reproducir",
"ButtonPreviousTrack": "Pista anterior", "ButtonPreviousTrack": "Pista anterior",
"ButtonProfile": "Perfil", "ButtonProfile": "Perfil",
"ButtonQuickStartGuide": "Guía de inicio rápido", "ButtonQuickStartGuide": "Guía de inicio rápido",
"ButtonRefresh": "Actualizar",
"ButtonRefreshGuideData": "Actualizar datos de la guía", "ButtonRefreshGuideData": "Actualizar datos de la guía",
"ButtonRemove": "Remover", "ButtonRemove": "Remover",
"ButtonRename": "Renombrar", "ButtonRename": "Renombrar",
@ -102,7 +95,6 @@
"ButtonStart": "Iniciar", "ButtonStart": "Iniciar",
"ButtonStop": "Detener", "ButtonStop": "Detener",
"ButtonSubmit": "Enviar", "ButtonSubmit": "Enviar",
"ButtonSubtitles": "Subtítulos",
"ButtonUninstall": "Desinstalar", "ButtonUninstall": "Desinstalar",
"ButtonWebsite": "Sitio web", "ButtonWebsite": "Sitio web",
"CancelRecording": "Cancelar grabación", "CancelRecording": "Cancelar grabación",
@ -189,9 +181,7 @@
"EnablePhotosHelp": "Las imágenes serán detectadas y mostradas junto con otros archivos multimedia.", "EnablePhotosHelp": "Las imágenes serán detectadas y mostradas junto con otros archivos multimedia.",
"EnableStreamLooping": "Repetir automáticamente las transmisiones en vivo", "EnableStreamLooping": "Repetir automáticamente las transmisiones en vivo",
"EnableStreamLoopingHelp": "Habilita esta opción si las transmisiones en vivo contienen solo unos pocos segundos de datos y necesitan ser solicitadas continuamente. Habilitar esto cuando no es requerido puede causar problemas.", "EnableStreamLoopingHelp": "Habilita esta opción si las transmisiones en vivo contienen solo unos pocos segundos de datos y necesitan ser solicitadas continuamente. Habilitar esto cuando no es requerido puede causar problemas.",
"EnableThemeSongs": "Canciones temáticas",
"EnableThemeSongsHelp": "Reproducir canciones temáticas en el fondo mientras se navega por la biblioteca.", "EnableThemeSongsHelp": "Reproducir canciones temáticas en el fondo mientras se navega por la biblioteca.",
"EnableThemeVideos": "Videos temáticos",
"EnableThemeVideosHelp": "Reproducir videos temáticos en el fondo mientras se navega por la biblioteca.", "EnableThemeVideosHelp": "Reproducir videos temáticos en el fondo mientras se navega por la biblioteca.",
"Ended": "Finalizado", "Ended": "Finalizado",
"EndsAtValue": "Termina a las {0}", "EndsAtValue": "Termina a las {0}",
@ -246,11 +236,9 @@
"HeaderActiveDevices": "Dispositivos activos", "HeaderActiveDevices": "Dispositivos activos",
"HeaderActiveRecordings": "Grabaciones activas", "HeaderActiveRecordings": "Grabaciones activas",
"HeaderActivity": "Actividad", "HeaderActivity": "Actividad",
"HeaderAddScheduledTaskTrigger": "Agregar disparador",
"HeaderAddToCollection": "Agregar a colección", "HeaderAddToCollection": "Agregar a colección",
"HeaderAddToPlaylist": "Agregar a lista de reproducción", "HeaderAddToPlaylist": "Agregar a lista de reproducción",
"HeaderAddUpdateImage": "Agregar/Actualizar Imagen", "HeaderAddUpdateImage": "Agregar/Actualizar Imagen",
"HeaderAddUser": "Agregar usuario",
"HeaderAdditionalParts": "Partes adicionales", "HeaderAdditionalParts": "Partes adicionales",
"HeaderAlbumArtists": "Artistas del álbum", "HeaderAlbumArtists": "Artistas del álbum",
"HeaderAlert": "Alerta", "HeaderAlert": "Alerta",
@ -262,12 +250,10 @@
"HeaderAudioBooks": "Audiolibros", "HeaderAudioBooks": "Audiolibros",
"HeaderAudioSettings": "Configuración de audio", "HeaderAudioSettings": "Configuración de audio",
"HeaderBlockItemsWithNoRating": "Bloquear elementos sin clasificación o con información de clasificación desconocida:", "HeaderBlockItemsWithNoRating": "Bloquear elementos sin clasificación o con información de clasificación desconocida:",
"HeaderBooks": "Libros",
"HeaderBranding": "Establecer marca", "HeaderBranding": "Establecer marca",
"HeaderCancelRecording": "Cancelar grabación", "HeaderCancelRecording": "Cancelar grabación",
"HeaderCancelSeries": "Cancelar serie", "HeaderCancelSeries": "Cancelar serie",
"HeaderCastAndCrew": "Reparto y equipo", "HeaderCastAndCrew": "Reparto y equipo",
"HeaderCastCrew": "Reparto y equipo",
"HeaderChannelAccess": "Acceso a los canales", "HeaderChannelAccess": "Acceso a los canales",
"HeaderChapterImages": "Imágenes de los capítulos", "HeaderChapterImages": "Imágenes de los capítulos",
"HeaderCodecProfile": "Perfil de códec", "HeaderCodecProfile": "Perfil de códec",
@ -301,13 +287,11 @@
"HeaderEditImages": "Editar imágenes", "HeaderEditImages": "Editar imágenes",
"HeaderEnabledFields": "Campos habilitados", "HeaderEnabledFields": "Campos habilitados",
"HeaderEnabledFieldsHelp": "Desmarca un campo para bloquearlo y prevenir que sus datos sean cambiados.", "HeaderEnabledFieldsHelp": "Desmarca un campo para bloquearlo y prevenir que sus datos sean cambiados.",
"HeaderEpisodes": "Episodios",
"HeaderExternalIds": "IDs externos:", "HeaderExternalIds": "IDs externos:",
"HeaderFeatureAccess": "Acceso a características", "HeaderFeatureAccess": "Acceso a características",
"HeaderFetchImages": "Obtener imágenes:", "HeaderFetchImages": "Obtener imágenes:",
"HeaderFetcherSettings": "Configuración del recolector", "HeaderFetcherSettings": "Configuración del recolector",
"HeaderForKids": "Para niños", "HeaderForKids": "Para niños",
"HeaderForgotPassword": "Olvidé mi contraseña",
"HeaderFrequentlyPlayed": "Reproducido frecuentemente", "HeaderFrequentlyPlayed": "Reproducido frecuentemente",
"HeaderGuideProviders": "Proveedores de Guías de TV", "HeaderGuideProviders": "Proveedores de Guías de TV",
"HeaderHttpHeaders": "Encabezados HTTP", "HeaderHttpHeaders": "Encabezados HTTP",
@ -336,7 +320,6 @@
"HeaderLoginFailure": "Falló el inicio de sesión", "HeaderLoginFailure": "Falló el inicio de sesión",
"HeaderMedia": "Medios", "HeaderMedia": "Medios",
"HeaderMediaFolders": "Carpetas de medios", "HeaderMediaFolders": "Carpetas de medios",
"HeaderMediaInfo": "Info del medio",
"HeaderMetadataSettings": "Configuración de metadatos", "HeaderMetadataSettings": "Configuración de metadatos",
"HeaderMoreLikeThis": "Más como esto", "HeaderMoreLikeThis": "Más como esto",
"HeaderMusicQuality": "Calidad de la música", "HeaderMusicQuality": "Calidad de la música",
@ -494,7 +477,6 @@
"LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS #12 que contiene un certificado y una clave privada para habilitar el soporte TLS en un dominio personalizado.", "LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS #12 que contiene un certificado y una clave privada para habilitar el soporte TLS en un dominio personalizado.",
"LabelCustomCss": "CSS personalizado:", "LabelCustomCss": "CSS personalizado:",
"LabelCustomCssHelp": "Aplica tu propio estilo personalizado a la interfaz web.", "LabelCustomCssHelp": "Aplica tu propio estilo personalizado a la interfaz web.",
"LabelCustomDeviceDisplayName": "Nombre a mostrar:",
"LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre personalizado para mostrar o déjalo vacío para usar el nombre reportado por el dispositivo.", "LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre personalizado para mostrar o déjalo vacío para usar el nombre reportado por el dispositivo.",
"LabelCustomRating": "Calificación personalizada:", "LabelCustomRating": "Calificación personalizada:",
"LabelDateAdded": "Fecha de adición:", "LabelDateAdded": "Fecha de adición:",
@ -511,7 +493,6 @@
"LabelDiscNumber": "Número de disco:", "LabelDiscNumber": "Número de disco:",
"LabelDisplayLanguage": "Idioma de pantalla:", "LabelDisplayLanguage": "Idioma de pantalla:",
"LabelDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en curso.", "LabelDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en curso.",
"LabelDisplayMissingEpisodesWithinSeasons": "Mostrar episodios faltantes en las temporadas",
"LabelDisplayMode": "Modo de pantalla:", "LabelDisplayMode": "Modo de pantalla:",
"LabelDisplayName": "Nombre a mostrar:", "LabelDisplayName": "Nombre a mostrar:",
"LabelDisplayOrder": "Orden para mostrar:", "LabelDisplayOrder": "Orden para mostrar:",
@ -666,7 +647,6 @@
"LabelPostProcessorArguments": "Argumentos de la línea de comandos del post-procesador:", "LabelPostProcessorArguments": "Argumentos de la línea de comandos del post-procesador:",
"LabelPostProcessorArgumentsHelp": "Usar {path} como la ruta del archivo grabado.", "LabelPostProcessorArgumentsHelp": "Usar {path} como la ruta del archivo grabado.",
"LabelPreferredDisplayLanguage": "Idioma de pantalla preferido:", "LabelPreferredDisplayLanguage": "Idioma de pantalla preferido:",
"LabelPreferredDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en curso.",
"LabelPreferredSubtitleLanguage": "Idioma preferido para los subtítulos:", "LabelPreferredSubtitleLanguage": "Idioma preferido para los subtítulos:",
"LabelProfileAudioCodecs": "Códecs de audio:", "LabelProfileAudioCodecs": "Códecs de audio:",
"LabelProfileCodecsHelp": "Separados por comas. Puede dejarse vacío para aplicarlo a todos los códecs.", "LabelProfileCodecsHelp": "Separados por comas. Puede dejarse vacío para aplicarlo a todos los códecs.",
@ -725,7 +705,6 @@
"LabelSubtitleDownloaders": "Recolectores de subtítulos:", "LabelSubtitleDownloaders": "Recolectores de subtítulos:",
"LabelSubtitleFormatHelp": "Ejemplo: srt", "LabelSubtitleFormatHelp": "Ejemplo: srt",
"LabelSubtitlePlaybackMode": "Modo de subtítulo:", "LabelSubtitlePlaybackMode": "Modo de subtítulo:",
"LabelSubtitles": "Subtítulos",
"LabelSupportedMediaTypes": "Tipos de medios soportados:", "LabelSupportedMediaTypes": "Tipos de medios soportados:",
"LabelTVHomeScreen": "Modo de pantalla de TV:", "LabelTVHomeScreen": "Modo de pantalla de TV:",
"LabelTag": "Etiqueta:", "LabelTag": "Etiqueta:",
@ -738,12 +717,9 @@
"LabelTimeLimitHours": "Límite de tiempo (horas):", "LabelTimeLimitHours": "Límite de tiempo (horas):",
"LabelTitle": "Título:", "LabelTitle": "Título:",
"LabelTrackNumber": "Número de pista:", "LabelTrackNumber": "Número de pista:",
"LabelTranscodingAudioCodec": "Códec de audio:",
"LabelTranscodingContainer": "Contenedor:",
"LabelTranscodingTempPathHelp": "Especifica una ruta personalizada para los archivos de transcodificación servidos a los clientes. Deja en blanco para utilizar el predeterminado del servidor.", "LabelTranscodingTempPathHelp": "Especifica una ruta personalizada para los archivos de transcodificación servidos a los clientes. Deja en blanco para utilizar el predeterminado del servidor.",
"LabelTranscodingThreadCount": "Conteo de hilos de la transcodificación:", "LabelTranscodingThreadCount": "Conteo de hilos de la transcodificación:",
"LabelTranscodingThreadCountHelp": "Selecciona el número máximo de hilos a utilizar al transcodificar. Reducir el número de hilos reducirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido como para que la experiencia de reproducción sea fluida.", "LabelTranscodingThreadCountHelp": "Selecciona el número máximo de hilos a utilizar al transcodificar. Reducir el número de hilos reducirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido como para que la experiencia de reproducción sea fluida.",
"LabelTranscodingVideoCodec": "Códec de video:",
"LabelTriggerType": "Tipo de disparador:", "LabelTriggerType": "Tipo de disparador:",
"LabelTunerIpAddress": "Dirección IP del sintonizador:", "LabelTunerIpAddress": "Dirección IP del sintonizador:",
"LabelTunerType": "Tipo de sintonizador:", "LabelTunerType": "Tipo de sintonizador:",
@ -851,7 +827,6 @@
"MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento por favor, inicia sesión en tu servidor local directamente.", "MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento por favor, inicia sesión en tu servidor local directamente.",
"MessagePluginInstallDisclaimer": "Los complementos desarrollados por miembros de la comunidad Jellyfin son una gran forma de mejorar tu experiencia con Jellyfin con características y beneficios adicionales. Antes de instalar, por favor, conoce el impacto que pueden ocasionar en tu servidor Jellyfin, tales como escaneo más largo de bibliotecas, procesamiento en segundo plano adicional y reducción de la estabilidad del sistema.", "MessagePluginInstallDisclaimer": "Los complementos desarrollados por miembros de la comunidad Jellyfin son una gran forma de mejorar tu experiencia con Jellyfin con características y beneficios adicionales. Antes de instalar, por favor, conoce el impacto que pueden ocasionar en tu servidor Jellyfin, tales como escaneo más largo de bibliotecas, procesamiento en segundo plano adicional y reducción de la estabilidad del sistema.",
"MessageReenableUser": "Ver abajo para volver a habilitar", "MessageReenableUser": "Ver abajo para volver a habilitar",
"MessageSettingsSaved": "Configuraciones guardadas.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Las siguientes ubicaciones de medios se removerán de tu biblioteca:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Las siguientes ubicaciones de medios se removerán de tu biblioteca:",
"MessageUnableToConnectToServer": "No podemos conectarnos al servidor seleccionado en este momento. Por favor, asegúrate de que está funcionando e inténtalo de nuevo.", "MessageUnableToConnectToServer": "No podemos conectarnos al servidor seleccionado en este momento. Por favor, asegúrate de que está funcionando e inténtalo de nuevo.",
"MessageUnsetContentHelp": "El contenido será mostrado como carpetas simples. Para mejores resultados utiliza el administrador de metadatos para establecer los tipos de contenido para las subcarpetas.", "MessageUnsetContentHelp": "El contenido será mostrado como carpetas simples. Para mejores resultados utiliza el administrador de metadatos para establecer los tipos de contenido para las subcarpetas.",
@ -915,7 +890,6 @@
"OptionArtist": "Artista", "OptionArtist": "Artista",
"OptionAscending": "Ascendente", "OptionAscending": "Ascendente",
"OptionAuto": "Automático", "OptionAuto": "Automático",
"OptionAutomatic": "Automático",
"OptionAutomaticallyGroupSeries": "Fusionar automáticamente series esparcidas a través de múltiples carpetas", "OptionAutomaticallyGroupSeries": "Fusionar automáticamente series esparcidas a través de múltiples carpetas",
"OptionAutomaticallyGroupSeriesHelp": "Si se habilita, las series que se reparten a través de múltiples carpetas dentro de esta biblioteca serán fusionadas en una sola serie.", "OptionAutomaticallyGroupSeriesHelp": "Si se habilita, las series que se reparten a través de múltiples carpetas dentro de esta biblioteca serán fusionadas en una sola serie.",
"OptionBlockBooks": "Libros", "OptionBlockBooks": "Libros",
@ -1150,16 +1124,13 @@
"SystemDlnaProfilesHelp": "Los perfiles del sistema son de solo lectura. Los cambios a un perfil del sistema serán guardados en un nuevo perfil personalizado.", "SystemDlnaProfilesHelp": "Los perfiles del sistema son de solo lectura. Los cambios a un perfil del sistema serán guardados en un nuevo perfil personalizado.",
"TabAccess": "Acceso", "TabAccess": "Acceso",
"TabAdvanced": "Avanzado", "TabAdvanced": "Avanzado",
"TabAlbumArtists": "Artistas del álbum",
"TabCatalog": "Catálogo", "TabCatalog": "Catálogo",
"TabContainers": "Contenedores", "TabContainers": "Contenedores",
"TabDashboard": "Panel de control", "TabDashboard": "Panel de control",
"TabDirectPlay": "Reproducción directa", "TabDirectPlay": "Reproducción directa",
"TabEpisodes": "Episodios",
"TabLatest": "Recientes", "TabLatest": "Recientes",
"TabLogs": "Registros", "TabLogs": "Registros",
"TabMusic": "Música", "TabMusic": "Música",
"TabMusicVideos": "Videos musicales",
"TabMyPlugins": "Mis complementos", "TabMyPlugins": "Mis complementos",
"TabNetworks": "Cadenas", "TabNetworks": "Cadenas",
"TabNfoSettings": "Configuración de NFO", "TabNfoSettings": "Configuración de NFO",
@ -1170,12 +1141,10 @@
"TabProfile": "Perfil", "TabProfile": "Perfil",
"TabProfiles": "Perfiles", "TabProfiles": "Perfiles",
"TabResponses": "Respuestas", "TabResponses": "Respuestas",
"TabResumeSettings": "Reanudar",
"TabScheduledTasks": "Tareas programadas", "TabScheduledTasks": "Tareas programadas",
"TabServer": "Servidor", "TabServer": "Servidor",
"TabSettings": "Configuración", "TabSettings": "Configuración",
"TabStreaming": "Transmisión", "TabStreaming": "Transmisión",
"TabTrailers": "Trailers",
"TabUpcoming": "Próximamente", "TabUpcoming": "Próximamente",
"Tags": "Etiquetas", "Tags": "Etiquetas",
"TagsValue": "Etiquetas: {0}", "TagsValue": "Etiquetas: {0}",
@ -1261,10 +1230,8 @@
"HeaderFavoriteArtists": "Artistas favoritos", "HeaderFavoriteArtists": "Artistas favoritos",
"HeaderFavoriteSongs": "Canciones favoritas", "HeaderFavoriteSongs": "Canciones favoritas",
"HeaderFavoriteVideos": "Videos favoritos", "HeaderFavoriteVideos": "Videos favoritos",
"HeaderHome": "Inicio",
"HeaderVideos": "Videos", "HeaderVideos": "Videos",
"Horizontal": "Horizontal", "Horizontal": "Horizontal",
"LabelAudio": "Audio",
"LabelAuthProvider": "Proveedor de autenticación:", "LabelAuthProvider": "Proveedor de autenticación:",
"LabelDynamicExternalId": "{0} Id:", "LabelDynamicExternalId": "{0} Id:",
"LabelPasswordResetProvider": "Proveedor de restablecimiento de contraseña:", "LabelPasswordResetProvider": "Proveedor de restablecimiento de contraseña:",
@ -1317,7 +1284,6 @@
"SubtitleOffset": "Desplazamiento de subtítulos", "SubtitleOffset": "Desplazamiento de subtítulos",
"TV": "TV", "TV": "TV",
"TabCodecs": "Códecs", "TabCodecs": "Códecs",
"TabInfo": "Información",
"ValueMinutes": "{0} min", "ValueMinutes": "{0} min",
"ValueSeriesCount": "{0} series", "ValueSeriesCount": "{0} series",
"Vertical": "Vertical", "Vertical": "Vertical",

View file

@ -49,30 +49,23 @@
"ButtonBack": "Atrás", "ButtonBack": "Atrás",
"ButtonCancel": "Cancelar", "ButtonCancel": "Cancelar",
"ButtonChangeServer": "Cambiar servidor", "ButtonChangeServer": "Cambiar servidor",
"ButtonEdit": "Editar",
"ButtonEditImages": "Editar imágenes",
"ButtonEditOtherUserPreferences": "Editar este perfil, la imagen y los ajustes personales.", "ButtonEditOtherUserPreferences": "Editar este perfil, la imagen y los ajustes personales.",
"ButtonFilter": "Filtro",
"ButtonForgotPassword": "Contraseña olvidada", "ButtonForgotPassword": "Contraseña olvidada",
"ButtonFullscreen": "Pantalla completa", "ButtonFullscreen": "Pantalla completa",
"ButtonGotIt": "Entendido", "ButtonGotIt": "Entendido",
"ButtonGuide": "Guía", "ButtonGuide": "Guía",
"ButtonHome": "Inicio",
"ButtonLibraryAccess": "Acceso a la biblioteca", "ButtonLibraryAccess": "Acceso a la biblioteca",
"ButtonManualLogin": "Acceder manualmente", "ButtonManualLogin": "Acceder manualmente",
"ButtonMore": "Más", "ButtonMore": "Más",
"ButtonNetwork": "Red", "ButtonNetwork": "Red",
"ButtonNextTrack": "Pista siguiente", "ButtonNextTrack": "Pista siguiente",
"ButtonOff": "Apagado",
"ButtonOk": "OK", "ButtonOk": "OK",
"ButtonOpen": "Abrir", "ButtonOpen": "Abrir",
"ButtonParentalControl": "Control parental", "ButtonParentalControl": "Control parental",
"ButtonPause": "Pausa", "ButtonPause": "Pausa",
"ButtonPlay": "Reproducir",
"ButtonPreviousTrack": "Pista anterior", "ButtonPreviousTrack": "Pista anterior",
"ButtonProfile": "Perfil", "ButtonProfile": "Perfil",
"ButtonQuickStartGuide": "Guía de inicio rápido", "ButtonQuickStartGuide": "Guía de inicio rápido",
"ButtonRefresh": "Refrescar",
"ButtonRefreshGuideData": "Actualizar datos de la guía", "ButtonRefreshGuideData": "Actualizar datos de la guía",
"ButtonRemove": "Quitar", "ButtonRemove": "Quitar",
"ButtonRename": "Renombrar", "ButtonRename": "Renombrar",
@ -93,7 +86,6 @@
"ButtonStart": "Inicio", "ButtonStart": "Inicio",
"ButtonStop": "Detener", "ButtonStop": "Detener",
"ButtonSubmit": "Enviar", "ButtonSubmit": "Enviar",
"ButtonSubtitles": "Subtítulos",
"ButtonTrailer": "Tráiler", "ButtonTrailer": "Tráiler",
"ButtonUninstall": "Desinstalar", "ButtonUninstall": "Desinstalar",
"ButtonWebsite": "Sitio web", "ButtonWebsite": "Sitio web",
@ -156,7 +148,6 @@
"EnablePhotosHelp": "Las imágenes se detectarán y se mostrarán junto con otros archivos multimedia.", "EnablePhotosHelp": "Las imágenes se detectarán y se mostrarán junto con otros archivos multimedia.",
"EnableStreamLooping": "Bucle automático de las emisiones en directo", "EnableStreamLooping": "Bucle automático de las emisiones en directo",
"EnableStreamLoopingHelp": "Habilite esto si las emisiones en directo sólo contienen unos pocos segundos de datos y necesitan ser solicitados continuamente.", "EnableStreamLoopingHelp": "Habilite esto si las emisiones en directo sólo contienen unos pocos segundos de datos y necesitan ser solicitados continuamente.",
"EnableThemeVideos": "Vídeos temáticos",
"Ended": "Finalizado", "Ended": "Finalizado",
"EndsAtValue": "Termina a las {0}", "EndsAtValue": "Termina a las {0}",
"Episodes": "Episodios", "Episodes": "Episodios",
@ -203,11 +194,9 @@
"HeaderActiveDevices": "Dispositivos activos", "HeaderActiveDevices": "Dispositivos activos",
"HeaderActiveRecordings": "Grabaciones activas", "HeaderActiveRecordings": "Grabaciones activas",
"HeaderActivity": "Actividad", "HeaderActivity": "Actividad",
"HeaderAddScheduledTaskTrigger": "Agregar Activador",
"HeaderAddToCollection": "Agregar a la colección", "HeaderAddToCollection": "Agregar a la colección",
"HeaderAddToPlaylist": "Añadir a la lista de reproducción", "HeaderAddToPlaylist": "Añadir a la lista de reproducción",
"HeaderAddUpdateImage": "Añadir/Actualizar imagen", "HeaderAddUpdateImage": "Añadir/Actualizar imagen",
"HeaderAddUser": "Agregar usuario",
"HeaderAdditionalParts": "Partes adicionales", "HeaderAdditionalParts": "Partes adicionales",
"HeaderAdmin": "Administrador", "HeaderAdmin": "Administrador",
"HeaderAlert": "Alerta", "HeaderAlert": "Alerta",
@ -218,11 +207,9 @@
"HeaderAudioBooks": "Audiolibros", "HeaderAudioBooks": "Audiolibros",
"HeaderAudioSettings": "Ajustes de audio", "HeaderAudioSettings": "Ajustes de audio",
"HeaderBlockItemsWithNoRating": "Bloquear artículos sin valoraciones o si son desconocidas:", "HeaderBlockItemsWithNoRating": "Bloquear artículos sin valoraciones o si son desconocidas:",
"HeaderBooks": "Libros",
"HeaderCancelRecording": "Cancelar grabación", "HeaderCancelRecording": "Cancelar grabación",
"HeaderCancelSeries": "Cancelar series", "HeaderCancelSeries": "Cancelar series",
"HeaderCastAndCrew": "Reparto y equipo", "HeaderCastAndCrew": "Reparto y equipo",
"HeaderCastCrew": "Reparto y equipo técnico",
"HeaderChannelAccess": "Acceso a los canales", "HeaderChannelAccess": "Acceso a los canales",
"HeaderChapterImages": "Imágenes de capítulos", "HeaderChapterImages": "Imágenes de capítulos",
"HeaderCodecProfile": "Perfil de códec", "HeaderCodecProfile": "Perfil de códec",
@ -256,13 +243,11 @@
"HeaderEditImages": "Editar imágenes", "HeaderEditImages": "Editar imágenes",
"HeaderEnabledFields": "Campos activados", "HeaderEnabledFields": "Campos activados",
"HeaderEnabledFieldsHelp": "Desmarca un campo para bloquearlo y evitar que se cambie su contenido.", "HeaderEnabledFieldsHelp": "Desmarca un campo para bloquearlo y evitar que se cambie su contenido.",
"HeaderEpisodes": "Episodios",
"HeaderExternalIds": "IDs externos:", "HeaderExternalIds": "IDs externos:",
"HeaderFeatureAccess": "Permisos de acceso", "HeaderFeatureAccess": "Permisos de acceso",
"HeaderFetchImages": "Buscar imágenes:", "HeaderFetchImages": "Buscar imágenes:",
"HeaderFetcherSettings": "Ajustes del capturador", "HeaderFetcherSettings": "Ajustes del capturador",
"HeaderForKids": "Para niños", "HeaderForKids": "Para niños",
"HeaderForgotPassword": "Contraseña olvidada",
"HeaderFrequentlyPlayed": "Reproducido frecuentemente", "HeaderFrequentlyPlayed": "Reproducido frecuentemente",
"HeaderGuideProviders": "Proveedores de guías", "HeaderGuideProviders": "Proveedores de guías",
"HeaderHttpHeaders": "Cabeceras HTTP", "HeaderHttpHeaders": "Cabeceras HTTP",
@ -291,7 +276,6 @@
"HeaderLoginFailure": "Fallo de inicio de sesión", "HeaderLoginFailure": "Fallo de inicio de sesión",
"HeaderMedia": "Medios", "HeaderMedia": "Medios",
"HeaderMediaFolders": "Carpetas de medios", "HeaderMediaFolders": "Carpetas de medios",
"HeaderMediaInfo": "Información multimedia",
"HeaderMetadataSettings": "Ajustes de etiquetas", "HeaderMetadataSettings": "Ajustes de etiquetas",
"HeaderMoreLikeThis": "Más como este", "HeaderMoreLikeThis": "Más como este",
"HeaderMusicVideos": "Vídeos musicales", "HeaderMusicVideos": "Vídeos musicales",
@ -442,7 +426,6 @@
"LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS # 12 que contiene un certificado y una clave privada para habilitar el soporte de TLS en un dominio personalizado.", "LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS # 12 que contiene un certificado y una clave privada para habilitar el soporte de TLS en un dominio personalizado.",
"LabelCustomCss": "CSS personalizado:", "LabelCustomCss": "CSS personalizado:",
"LabelCustomCssHelp": "Aplicar su propio CSS personalizado a la interfaz de la web.", "LabelCustomCssHelp": "Aplicar su propio CSS personalizado a la interfaz de la web.",
"LabelCustomDeviceDisplayName": "Nombre para mostrar:",
"LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre para mostrar o déjelo vacío para usar el nombre proporcionado por el dispositivo.", "LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre para mostrar o déjelo vacío para usar el nombre proporcionado por el dispositivo.",
"LabelCustomRating": "Valoración pesonalizada:", "LabelCustomRating": "Valoración pesonalizada:",
"LabelDateAdded": "Fecha de añadido:", "LabelDateAdded": "Fecha de añadido:",
@ -451,11 +434,10 @@
"LabelDay": "Día:", "LabelDay": "Día:",
"LabelDeathDate": "Fecha de muerte:", "LabelDeathDate": "Fecha de muerte:",
"LabelDefaultUser": "Usuario por defecto:", "LabelDefaultUser": "Usuario por defecto:",
"LabelDefaultUserHelp": "Determina de qúe usuario se utilizará su biblioteca de medios para mostrarla por defecto en los dipositivos conectados. Esto puede cambiarse para cada dispositivo mediante el uso de perfiles.", "LabelDefaultUserHelp": "Determina de q usuario se utilizará su biblioteca de medios para mostrarla por defecto en los dipositivos conectados. Esto puede cambiarse para cada dispositivo mediante el uso de perfiles.",
"LabelDeviceDescription": "Descripción del dispositivo", "LabelDeviceDescription": "Descripción del dispositivo",
"LabelDidlMode": "Modo DIDL:", "LabelDidlMode": "Modo DIDL:",
"LabelDiscNumber": "Número de disco:", "LabelDiscNumber": "Número de disco:",
"LabelDisplayMissingEpisodesWithinSeasons": "Mostar episodios no disponibles en temporadas",
"LabelDisplayMode": "Modo de visualización:", "LabelDisplayMode": "Modo de visualización:",
"LabelDisplayName": "Mostrar nombre:", "LabelDisplayName": "Mostrar nombre:",
"LabelDisplayOrder": "Mostrar orden:", "LabelDisplayOrder": "Mostrar orden:",
@ -607,7 +589,6 @@
"LabelPostProcessorArguments": "Argumentos de línea de comandos posprocesador:", "LabelPostProcessorArguments": "Argumentos de línea de comandos posprocesador:",
"LabelPostProcessorArgumentsHelp": "Utilice {path} como ruta del archivo de grabación.", "LabelPostProcessorArgumentsHelp": "Utilice {path} como ruta del archivo de grabación.",
"LabelPreferredDisplayLanguage": "Idioma preferido visualizado:", "LabelPreferredDisplayLanguage": "Idioma preferido visualizado:",
"LabelPreferredDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en marcha.",
"LabelPreferredSubtitleLanguage": "Idioma de subtítulos preferido:", "LabelPreferredSubtitleLanguage": "Idioma de subtítulos preferido:",
"LabelProfileAudioCodecs": "Códecs de audio:", "LabelProfileAudioCodecs": "Códecs de audio:",
"LabelProfileCodecs": "Códecs:", "LabelProfileCodecs": "Códecs:",
@ -673,12 +654,9 @@
"LabelTimeLimitHours": "Límite de tiempo (horas):", "LabelTimeLimitHours": "Límite de tiempo (horas):",
"LabelTitle": "Título:", "LabelTitle": "Título:",
"LabelTrackNumber": "Número de pista:", "LabelTrackNumber": "Número de pista:",
"LabelTranscodingAudioCodec": "Códec de audio:",
"LabelTranscodingContainer": "Contenedor:",
"LabelTranscodingTempPathHelp": "Establece la carpeta que se usará para almacenar los archivos temporales de las conversiones. Déjalo en blanco para usar la ruta por defecto.", "LabelTranscodingTempPathHelp": "Establece la carpeta que se usará para almacenar los archivos temporales de las conversiones. Déjalo en blanco para usar la ruta por defecto.",
"LabelTranscodingThreadCount": "Núcleos a utilizar durante la conversión:", "LabelTranscodingThreadCount": "Núcleos a utilizar durante la conversión:",
"LabelTranscodingThreadCountHelp": "Selecciona el número de núcleos a utilizar para la conversión. A menos núcleos, menor será el uso del procesador, pero puede que la conversión no vaya lo suficientemente rápido para una reproducción fluida.", "LabelTranscodingThreadCountHelp": "Selecciona el número de núcleos a utilizar para la conversión. A menos núcleos, menor será el uso del procesador, pero puede que la conversión no vaya lo suficientemente rápido para una reproducción fluida.",
"LabelTranscodingVideoCodec": "Códec de video:",
"LabelTriggerType": "Tipo de evento:", "LabelTriggerType": "Tipo de evento:",
"LabelTunerIpAddress": "IP del sintonizador:", "LabelTunerIpAddress": "IP del sintonizador:",
"LabelTunerType": "Tipo de sintonizador:", "LabelTunerType": "Tipo de sintonizador:",
@ -779,7 +757,6 @@
"MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento inicia sesión en tu servidor local directamente.", "MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento inicia sesión en tu servidor local directamente.",
"MessagePluginInstallDisclaimer": "Las extensiones creadas por los miembros de la comunidad de Jellyfin son una buena forma de mejorar tu experiencia con características adicionales y otros beneficios. Antes de instalarlos considera los efectos que pueden tener en tu servidor Jellyfin, como escaneos de la biblioteca más largos, procesado en segundo plano adicional y una reducción de la estabilidad del sistema.", "MessagePluginInstallDisclaimer": "Las extensiones creadas por los miembros de la comunidad de Jellyfin son una buena forma de mejorar tu experiencia con características adicionales y otros beneficios. Antes de instalarlos considera los efectos que pueden tener en tu servidor Jellyfin, como escaneos de la biblioteca más largos, procesado en segundo plano adicional y una reducción de la estabilidad del sistema.",
"MessageReenableUser": "Mira abajo para reactivarlo", "MessageReenableUser": "Mira abajo para reactivarlo",
"MessageSettingsSaved": "Ajustes guardados.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Se eliminarán las siguientes ubicaciones de medios de tu biblioteca:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Se eliminarán las siguientes ubicaciones de medios de tu biblioteca:",
"MessageUnableToConnectToServer": "No podemos conectar con el servidor seleccionado ahora mismo. Por favor, asegúrate de que esta funcionando e inténtalo otra vez.", "MessageUnableToConnectToServer": "No podemos conectar con el servidor seleccionado ahora mismo. Por favor, asegúrate de que esta funcionando e inténtalo otra vez.",
"MessageUnsetContentHelp": "El contenido se mostrará como carpetas planas. Para tener mejores resultados utiliza el gestor de metadatos para establecer los tipos de contenidos de las sub-carpetas.", "MessageUnsetContentHelp": "El contenido se mostrará como carpetas planas. Para tener mejores resultados utiliza el gestor de metadatos para establecer los tipos de contenidos de las sub-carpetas.",
@ -1053,16 +1030,13 @@
"SystemDlnaProfilesHelp": "El perfil del sistema es solo lectura. Cambios al perfil del sistema seran guardados en un perfil nuevo modificado.", "SystemDlnaProfilesHelp": "El perfil del sistema es solo lectura. Cambios al perfil del sistema seran guardados en un perfil nuevo modificado.",
"TabAccess": "Acceso", "TabAccess": "Acceso",
"TabAdvanced": "Avanzado", "TabAdvanced": "Avanzado",
"TabAlbumArtists": "Artistas de los álbumes",
"TabCatalog": "Catálogo", "TabCatalog": "Catálogo",
"TabCodecs": "Códecs", "TabCodecs": "Códecs",
"TabContainers": "Contenedores", "TabContainers": "Contenedores",
"TabDashboard": "Panel de control", "TabDashboard": "Panel de control",
"TabDirectPlay": "Reproducción directa", "TabDirectPlay": "Reproducción directa",
"TabEpisodes": "Episodios",
"TabLatest": "Novedades", "TabLatest": "Novedades",
"TabMusic": "Música", "TabMusic": "Música",
"TabMusicVideos": "Videos musicales",
"TabMyPlugins": "Mis extensiones", "TabMyPlugins": "Mis extensiones",
"TabNetworks": "Cadenas", "TabNetworks": "Cadenas",
"TabNfoSettings": "Ajustes de NFO", "TabNfoSettings": "Ajustes de NFO",
@ -1072,7 +1046,6 @@
"TabProfile": "Perfil", "TabProfile": "Perfil",
"TabProfiles": "Perfiles", "TabProfiles": "Perfiles",
"TabResponses": "Respuestas", "TabResponses": "Respuestas",
"TabResumeSettings": "Reanudación",
"TabScheduledTasks": "Tareas programadas", "TabScheduledTasks": "Tareas programadas",
"TabServer": "Servidor", "TabServer": "Servidor",
"TabSettings": "Opciones", "TabSettings": "Opciones",
@ -1175,7 +1148,6 @@
"EnableColorCodedBackgrounds": "Fondos con código de colores", "EnableColorCodedBackgrounds": "Fondos con código de colores",
"EnableExternalVideoPlayersHelp": "Se mostrará un menú para reproductor externo cuando comience la reproducción del vídeo.", "EnableExternalVideoPlayersHelp": "Se mostrará un menú para reproductor externo cuando comience la reproducción del vídeo.",
"EnableNextVideoInfoOverlayHelp": "Al finalizar un vídeo, mostrar información sobre el siguiente de la lista de reproducción actual.", "EnableNextVideoInfoOverlayHelp": "Al finalizar un vídeo, mostrar información sobre el siguiente de la lista de reproducción actual.",
"EnableThemeSongs": "Canciones temáticas",
"EnableThemeSongsHelp": "Reproducir las canciones temáticas de fondo mientras se explora la biblioteca.", "EnableThemeSongsHelp": "Reproducir las canciones temáticas de fondo mientras se explora la biblioteca.",
"EnableThemeVideosHelp": "Reproducir vídeos temáticos de fondo mientras se explora la biblioteca.", "EnableThemeVideosHelp": "Reproducir vídeos temáticos de fondo mientras se explora la biblioteca.",
"ErrorDeletingItem": "Se ha producido un error eliminando el elemento del servidor Jellyfin. Por favor, comprueba que el servidor Jellyfin tiene permisos de escritura y prueba de nuevo.", "ErrorDeletingItem": "Se ha producido un error eliminando el elemento del servidor Jellyfin. Por favor, comprueba que el servidor Jellyfin tiene permisos de escritura y prueba de nuevo.",
@ -1200,7 +1172,6 @@
"HeaderVideoType": "Tipo de vídeo", "HeaderVideoType": "Tipo de vídeo",
"Home": "Inicio", "Home": "Inicio",
"Horizontal": "Horizontal", "Horizontal": "Horizontal",
"LabelAudio": "Audio",
"LabelBurnSubtitles": "Incrustar subtítulos:", "LabelBurnSubtitles": "Incrustar subtítulos:",
"LabelDateTimeLocale": "Fecha y hora local:", "LabelDateTimeLocale": "Fecha y hora local:",
"LabelDefaultScreen": "Pantalla por defecto:", "LabelDefaultScreen": "Pantalla por defecto:",
@ -1215,7 +1186,6 @@
"LabelSkipForwardLength": "Tiempo de avance:", "LabelSkipForwardLength": "Tiempo de avance:",
"LabelSortBy": "Ordenar por:", "LabelSortBy": "Ordenar por:",
"LabelSortOrder": "Orden:", "LabelSortOrder": "Orden:",
"LabelSubtitles": "Subtítulos",
"LabelTVHomeScreen": "Modo televisión en pantalla de inicio:", "LabelTVHomeScreen": "Modo televisión en pantalla de inicio:",
"LabelVersion": "Versión:", "LabelVersion": "Versión:",
"LabelVideo": "Vídeo", "LabelVideo": "Vídeo",
@ -1238,7 +1208,6 @@
"Off": "Apagado", "Off": "Apagado",
"Option3D": "3D", "Option3D": "3D",
"OptionAuto": "Automático", "OptionAuto": "Automático",
"OptionAutomatic": "Automático",
"OptionBanner": "Cabecera", "OptionBanner": "Cabecera",
"OptionBlockTrailers": "Tráilers", "OptionBlockTrailers": "Tráilers",
"OptionBluray": "Blu-ray", "OptionBluray": "Blu-ray",
@ -1255,7 +1224,6 @@
"HeaderFavoriteArtists": "Artistas favoritos", "HeaderFavoriteArtists": "Artistas favoritos",
"HeaderFavoriteSongs": "Canciones favoritas", "HeaderFavoriteSongs": "Canciones favoritas",
"HeaderFavoriteVideos": "Vídeos favoritos", "HeaderFavoriteVideos": "Vídeos favoritos",
"HeaderHome": "Inicio",
"LabelAuthProvider": "Proveedor de autenticación:", "LabelAuthProvider": "Proveedor de autenticación:",
"LabelPasswordResetProvider": "Proveedor de restablecimiento de contraseña:", "LabelPasswordResetProvider": "Proveedor de restablecimiento de contraseña:",
"LabelServerName": "Nombre del servidor:", "LabelServerName": "Nombre del servidor:",
@ -1310,10 +1278,8 @@
"SubtitleAppearanceSettingsDisclaimer": "Estos ajustes no se aplicarán a los subtítulos gráficos (PGS, DVD, etc.), ni a ASS/SSA que tengan incluidos sus propios estilos.", "SubtitleAppearanceSettingsDisclaimer": "Estos ajustes no se aplicarán a los subtítulos gráficos (PGS, DVD, etc.), ni a ASS/SSA que tengan incluidos sus propios estilos.",
"SubtitleOffset": "Desplazamiento de subtítulos", "SubtitleOffset": "Desplazamiento de subtítulos",
"TV": "Televisión", "TV": "Televisión",
"TabInfo": "Info",
"TabLogs": "Registros", "TabLogs": "Registros",
"TabPlugins": "Extensiones", "TabPlugins": "Extensiones",
"TabTrailers": "Tráilers",
"TagsValue": "Etiquetas: {0}", "TagsValue": "Etiquetas: {0}",
"ThemeSongs": "Banda sonora", "ThemeSongs": "Banda sonora",
"Trailers": "Tráilers", "Trailers": "Tráilers",

View file

@ -38,7 +38,6 @@
"Absolute": "Absoluto", "Absolute": "Absoluto",
"YadifBob": "YADIF Bob", "YadifBob": "YADIF Bob",
"Trailers": "Trailers", "Trailers": "Trailers",
"TabTrailers": "Trailers",
"OptionThumbCard": "Miniatura de imagen", "OptionThumbCard": "Miniatura de imagen",
"OptionResElement": "elemento reanudable", "OptionResElement": "elemento reanudable",
"OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)",
@ -133,7 +132,6 @@
"TabSettings": "Configuración", "TabSettings": "Configuración",
"TabServer": "Servidor", "TabServer": "Servidor",
"TabScheduledTasks": "Tareas programadas", "TabScheduledTasks": "Tareas programadas",
"TabResumeSettings": "Reanudar",
"TabResponses": "Respuestas", "TabResponses": "Respuestas",
"TabProfiles": "Perfiles", "TabProfiles": "Perfiles",
"TabProfile": "Perfil", "TabProfile": "Perfil",
@ -145,11 +143,8 @@
"TabNetworking": "Redes", "TabNetworking": "Redes",
"TabNetworks": "Cadenas", "TabNetworks": "Cadenas",
"TabMyPlugins": "Mis complementos", "TabMyPlugins": "Mis complementos",
"TabMusicVideos": "Videos musicales",
"TabMusic": "Música", "TabMusic": "Música",
"TabLogs": "Registros", "TabLogs": "Registros",
"TabInfo": "Información",
"TabEpisodes": "Episodios",
"TabDirectPlay": "Reproducción directa", "TabDirectPlay": "Reproducción directa",
"TabDashboard": "Panel de control", "TabDashboard": "Panel de control",
"TabContainers": "Contenedores", "TabContainers": "Contenedores",
@ -239,7 +234,6 @@
"OptionBanner": "Banner", "OptionBanner": "Banner",
"OptionAutomaticallyGroupSeriesHelp": "Series que estén repartidas en múltiples carpetas dentro de esta biblioteca serán automáticamente fusionadas en una sola serie.", "OptionAutomaticallyGroupSeriesHelp": "Series que estén repartidas en múltiples carpetas dentro de esta biblioteca serán automáticamente fusionadas en una sola serie.",
"OptionAutomaticallyGroupSeries": "Fusionar automáticamente series esparcidas a través de múltiples carpetas", "OptionAutomaticallyGroupSeries": "Fusionar automáticamente series esparcidas a través de múltiples carpetas",
"OptionAutomatic": "Automático",
"OptionAuto": "Automático", "OptionAuto": "Automático",
"OptionAscending": "Ascendente", "OptionAscending": "Ascendente",
"OptionArtist": "Artista", "OptionArtist": "Artista",
@ -328,7 +322,6 @@
"MessageUnsetContentHelp": "El contenido será mostrado como carpetas simples. Para mejores resultados utiliza el administrador de metadatos para establecer los tipos de contenido para las subcarpetas.", "MessageUnsetContentHelp": "El contenido será mostrado como carpetas simples. Para mejores resultados utiliza el administrador de metadatos para establecer los tipos de contenido para las subcarpetas.",
"MessageUnableToConnectToServer": "No podemos conectarnos al servidor seleccionado en este momento. Por favor, asegúrate de que está funcionando e inténtalo de nuevo.", "MessageUnableToConnectToServer": "No podemos conectarnos al servidor seleccionado en este momento. Por favor, asegúrate de que está funcionando e inténtalo de nuevo.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "Las siguientes ubicaciones de medios se removerán de tu biblioteca:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "Las siguientes ubicaciones de medios se removerán de tu biblioteca:",
"MessageSettingsSaved": "Configuraciones guardadas.",
"MessageReenableUser": "Ver abajo para volver a habilitar", "MessageReenableUser": "Ver abajo para volver a habilitar",
"MessagePluginInstallDisclaimer": "Los complementos desarrollados por miembros de la comunidad son una gran forma de mejorar tu experiencia con características y beneficios adicionales. Antes de instalar, por favor, conoce el impacto que pueden ocasionar en tu servidor, tales como escaneo más largo de bibliotecas, procesamiento en segundo plano adicional y reducción de la estabilidad del sistema.", "MessagePluginInstallDisclaimer": "Los complementos desarrollados por miembros de la comunidad son una gran forma de mejorar tu experiencia con características y beneficios adicionales. Antes de instalar, por favor, conoce el impacto que pueden ocasionar en tu servidor, tales como escaneo más largo de bibliotecas, procesamiento en segundo plano adicional y reducción de la estabilidad del sistema.",
"MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento por favor, inicia sesión en tu servidor local directamente.", "MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento por favor, inicia sesión en tu servidor local directamente.",
@ -402,7 +395,6 @@
"LabelTunerType": "Tipo de sintonizador:", "LabelTunerType": "Tipo de sintonizador:",
"LabelTunerIpAddress": "Dirección IP del sintonizador:", "LabelTunerIpAddress": "Dirección IP del sintonizador:",
"LabelTriggerType": "Tipo de disparador:", "LabelTriggerType": "Tipo de disparador:",
"LabelTranscodingVideoCodec": "Códec de video:",
"LabelTranscodingThreadCountHelp": "Selecciona el número máximo de hilos a utilizar al transcodificar. Reducir el número de hilos reducirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido como para que la experiencia de reproducción sea fluida.", "LabelTranscodingThreadCountHelp": "Selecciona el número máximo de hilos a utilizar al transcodificar. Reducir el número de hilos reducirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido como para que la experiencia de reproducción sea fluida.",
"LabelTranscodingThreadCount": "Conteo de hilos de la transcodificación:", "LabelTranscodingThreadCount": "Conteo de hilos de la transcodificación:",
"LabelTranscodingProgress": "Progreso de la transcodificación:", "LabelTranscodingProgress": "Progreso de la transcodificación:",
@ -410,8 +402,6 @@
"LabelTranscodes": "Transcodificaciones:", "LabelTranscodes": "Transcodificaciones:",
"LabelTranscodingTempPathHelp": "Especifica una ruta personalizada para los archivos de transcodificación servidos a los clientes. Deja en blanco para utilizar el predeterminado del servidor.", "LabelTranscodingTempPathHelp": "Especifica una ruta personalizada para los archivos de transcodificación servidos a los clientes. Deja en blanco para utilizar el predeterminado del servidor.",
"LabelTranscodePath": "Ruta de transcodificación:", "LabelTranscodePath": "Ruta de transcodificación:",
"LabelTranscodingContainer": "Contenedor:",
"LabelTranscodingAudioCodec": "Códec de audio:",
"LabelTrackNumber": "Número de pista:", "LabelTrackNumber": "Número de pista:",
"LabelTitle": "Título:", "LabelTitle": "Título:",
"LabelTimeLimitHours": "Límite de tiempo (horas):", "LabelTimeLimitHours": "Límite de tiempo (horas):",
@ -436,7 +426,6 @@
"MillisecondsUnit": "ms", "MillisecondsUnit": "ms",
"LabelSyncPlayTimeOffset": "Tiempo compensado respecto al servidor:", "LabelSyncPlayTimeOffset": "Tiempo compensado respecto al servidor:",
"LabelSupportedMediaTypes": "Tipos de medios soportados:", "LabelSupportedMediaTypes": "Tipos de medios soportados:",
"LabelSubtitles": "Subtítulos",
"LabelSubtitlePlaybackMode": "Modo de subtítulo:", "LabelSubtitlePlaybackMode": "Modo de subtítulo:",
"LabelSubtitleFormatHelp": "Ejemplo: srt", "LabelSubtitleFormatHelp": "Ejemplo: srt",
"LabelSubtitleDownloaders": "Recolectores de subtítulos:", "LabelSubtitleDownloaders": "Recolectores de subtítulos:",
@ -669,7 +658,6 @@
"LabelProfileCodecs": "Códecs:", "LabelProfileCodecs": "Códecs:",
"LabelProfileAudioCodecs": "Códecs de audio:", "LabelProfileAudioCodecs": "Códecs de audio:",
"LabelPreferredSubtitleLanguage": "Idioma preferido para los subtítulos:", "LabelPreferredSubtitleLanguage": "Idioma preferido para los subtítulos:",
"LabelPreferredDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en curso.",
"LabelPreferredDisplayLanguage": "Idioma de pantalla preferido:", "LabelPreferredDisplayLanguage": "Idioma de pantalla preferido:",
"LabelPostProcessorArgumentsHelp": "Usar {path} como la ruta del archivo grabado.", "LabelPostProcessorArgumentsHelp": "Usar {path} como la ruta del archivo grabado.",
"LabelPostProcessorArguments": "Argumentos de la línea de comandos del post-procesador:", "LabelPostProcessorArguments": "Argumentos de la línea de comandos del post-procesador:",
@ -802,7 +790,6 @@
"LabelDisplayOrder": "Orden para mostrar:", "LabelDisplayOrder": "Orden para mostrar:",
"LabelDisplayName": "Nombre a mostrar:", "LabelDisplayName": "Nombre a mostrar:",
"LabelDisplayMode": "Modo de pantalla:", "LabelDisplayMode": "Modo de pantalla:",
"LabelDisplayMissingEpisodesWithinSeasons": "Mostrar episodios faltantes en las temporadas",
"LabelDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en curso.", "LabelDisplayLanguageHelp": "La traducción de Jellyfin es un proyecto en curso.",
"LabelDisplayLanguage": "Idioma de pantalla:", "LabelDisplayLanguage": "Idioma de pantalla:",
"LabelDiscNumber": "Número de disco:", "LabelDiscNumber": "Número de disco:",
@ -820,7 +807,6 @@
"LabelDateAdded": "Fecha de adición:", "LabelDateAdded": "Fecha de adición:",
"LabelCustomRating": "Calificación personalizada:", "LabelCustomRating": "Calificación personalizada:",
"LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre personalizado para mostrar o déjalo vacío para usar el nombre reportado por el dispositivo.", "LabelCustomDeviceDisplayNameHelp": "Proporcione un nombre personalizado para mostrar o déjalo vacío para usar el nombre reportado por el dispositivo.",
"LabelCustomDeviceDisplayName": "Nombre a mostrar:",
"LabelCustomCssHelp": "Aplica tu propio estilo personalizado a la interfaz web.", "LabelCustomCssHelp": "Aplica tu propio estilo personalizado a la interfaz web.",
"LabelCustomCss": "CSS personalizado:", "LabelCustomCss": "CSS personalizado:",
"LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS #12 que contiene un certificado y una clave privada para habilitar el soporte TLS en un dominio personalizado.", "LabelCustomCertificatePathHelp": "Ruta a un archivo PKCS #12 que contiene un certificado y una clave privada para habilitar el soporte TLS en un dominio personalizado.",
@ -835,7 +821,6 @@
"LabelChannels": "Canales:", "LabelChannels": "Canales:",
"LabelCertificatePasswordHelp": "Si tu certificado requiere una contraseña, por favor, introdúcela aquí.", "LabelCertificatePasswordHelp": "Si tu certificado requiere una contraseña, por favor, introdúcela aquí.",
"LabelCertificatePassword": "Contraseña del certificado:", "LabelCertificatePassword": "Contraseña del certificado:",
"TabAlbumArtists": "Artistas del álbum",
"TabAdvanced": "Avanzado", "TabAdvanced": "Avanzado",
"TabAccess": "Acceso", "TabAccess": "Acceso",
"TV": "TV", "TV": "TV",
@ -918,7 +903,6 @@
"LabelAudioChannels": "Canales de audio:", "LabelAudioChannels": "Canales de audio:",
"LabelAudioBitrate": "Velocidad de bits de audio:", "LabelAudioBitrate": "Velocidad de bits de audio:",
"LabelAudioBitDepth": "Profundidad de bits de audio:", "LabelAudioBitDepth": "Profundidad de bits de audio:",
"LabelAudio": "Audio",
"LabelArtistsHelp": "Separar múltiples artistas por punto y coma.", "LabelArtistsHelp": "Separar múltiples artistas por punto y coma.",
"LabelArtists": "Artistas:", "LabelArtists": "Artistas:",
"LabelAppNameExample": "Ejemplo: Sickbeard, Sonarr", "LabelAppNameExample": "Ejemplo: Sickbeard, Sonarr",
@ -1048,7 +1032,6 @@
"HeaderMusicQuality": "Calidad de la música", "HeaderMusicQuality": "Calidad de la música",
"HeaderMoreLikeThis": "Más como esto", "HeaderMoreLikeThis": "Más como esto",
"HeaderMetadataSettings": "Configuración de metadatos", "HeaderMetadataSettings": "Configuración de metadatos",
"HeaderMediaInfo": "Info del medio",
"HeaderMediaFolders": "Carpetas de medios", "HeaderMediaFolders": "Carpetas de medios",
"HeaderMedia": "Medios", "HeaderMedia": "Medios",
"HeaderLoginFailure": "Falló el inicio de sesión", "HeaderLoginFailure": "Falló el inicio de sesión",
@ -1076,10 +1059,8 @@
"HeaderIdentification": "Identificación", "HeaderIdentification": "Identificación",
"HeaderHttpsSettings": "Opciones HTTPS", "HeaderHttpsSettings": "Opciones HTTPS",
"HeaderHttpHeaders": "Encabezados HTTP", "HeaderHttpHeaders": "Encabezados HTTP",
"HeaderHome": "Inicio",
"HeaderGuideProviders": "Proveedores de Guías de TV", "HeaderGuideProviders": "Proveedores de Guías de TV",
"HeaderFrequentlyPlayed": "Reproducido frecuentemente", "HeaderFrequentlyPlayed": "Reproducido frecuentemente",
"HeaderForgotPassword": "Olvidé mi contraseña",
"HeaderForKids": "Para niños", "HeaderForKids": "Para niños",
"HeaderFetcherSettings": "Configuración del recolector", "HeaderFetcherSettings": "Configuración del recolector",
"HeaderFetchImages": "Obtener imágenes:", "HeaderFetchImages": "Obtener imágenes:",
@ -1129,7 +1110,6 @@
"HeaderFavoriteBooks": "Libros favoritos", "HeaderFavoriteBooks": "Libros favoritos",
"HeaderExternalIds": "IDs externos:", "HeaderExternalIds": "IDs externos:",
"HeaderError": "Error", "HeaderError": "Error",
"HeaderEpisodes": "Episodios",
"HeaderEnabledFieldsHelp": "Desmarca un campo para bloquearlo y prevenir que sus datos sean cambiados.", "HeaderEnabledFieldsHelp": "Desmarca un campo para bloquearlo y prevenir que sus datos sean cambiados.",
"HeaderEnabledFields": "Campos habilitados", "HeaderEnabledFields": "Campos habilitados",
"HeaderEditImages": "Editar imágenes", "HeaderEditImages": "Editar imágenes",
@ -1163,12 +1143,10 @@
"HeaderCodecProfile": "Perfil de códec", "HeaderCodecProfile": "Perfil de códec",
"HeaderChapterImages": "Imágenes de los capítulos", "HeaderChapterImages": "Imágenes de los capítulos",
"HeaderChannelAccess": "Acceso a los canales", "HeaderChannelAccess": "Acceso a los canales",
"HeaderCastCrew": "Reparto y equipo",
"HeaderCastAndCrew": "Reparto y equipo", "HeaderCastAndCrew": "Reparto y equipo",
"HeaderCancelSeries": "Cancelar serie", "HeaderCancelSeries": "Cancelar serie",
"HeaderCancelRecording": "Cancelar grabación", "HeaderCancelRecording": "Cancelar grabación",
"HeaderBranding": "Establecer marca", "HeaderBranding": "Establecer marca",
"HeaderBooks": "Libros",
"HeaderBlockItemsWithNoRating": "Bloquear elementos sin clasificación o con información de clasificación desconocida:", "HeaderBlockItemsWithNoRating": "Bloquear elementos sin clasificación o con información de clasificación desconocida:",
"HeaderAudioSettings": "Configuración de audio", "HeaderAudioSettings": "Configuración de audio",
"HeaderAudioBooks": "Audiolibros", "HeaderAudioBooks": "Audiolibros",
@ -1182,11 +1160,9 @@
"HeaderAlert": "Alerta", "HeaderAlert": "Alerta",
"HeaderAdmin": "Administrador", "HeaderAdmin": "Administrador",
"HeaderAdditionalParts": "Partes adicionales", "HeaderAdditionalParts": "Partes adicionales",
"HeaderAddUser": "Agregar usuario",
"HeaderAddUpdateImage": "Agregar/Actualizar Imagen", "HeaderAddUpdateImage": "Agregar/Actualizar Imagen",
"HeaderAddToPlaylist": "Agregar a lista de reproducción", "HeaderAddToPlaylist": "Agregar a lista de reproducción",
"HeaderAddToCollection": "Agregar a colección", "HeaderAddToCollection": "Agregar a colección",
"HeaderAddScheduledTaskTrigger": "Agregar disparador",
"HeaderActivity": "Actividad", "HeaderActivity": "Actividad",
"HeaderActiveRecordings": "Grabaciones activas", "HeaderActiveRecordings": "Grabaciones activas",
"HeaderActiveDevices": "Dispositivos activos", "HeaderActiveDevices": "Dispositivos activos",
@ -1244,9 +1220,7 @@
"EnableDetailsBannerHelp": "Mostrar una imagen banner en la parte superior de la página de detalles del elemento.", "EnableDetailsBannerHelp": "Mostrar una imagen banner en la parte superior de la página de detalles del elemento.",
"EnableDetailsBanner": "Banner de detalles", "EnableDetailsBanner": "Banner de detalles",
"EnableThemeVideosHelp": "Reproducir videos temáticos en el fondo mientras se navega por la biblioteca.", "EnableThemeVideosHelp": "Reproducir videos temáticos en el fondo mientras se navega por la biblioteca.",
"EnableThemeVideos": "Videos temáticos",
"EnableThemeSongsHelp": "Reproducir canciones temáticas en el fondo mientras se navega por la biblioteca.", "EnableThemeSongsHelp": "Reproducir canciones temáticas en el fondo mientras se navega por la biblioteca.",
"EnableThemeSongs": "Canciones temáticas",
"EnableStreamLoopingHelp": "Habilita esta opción si las transmisiones en vivo contienen solo unos pocos segundos de datos y necesitan ser solicitadas continuamente. Habilitar esto cuando no es requerido puede causar problemas.", "EnableStreamLoopingHelp": "Habilita esta opción si las transmisiones en vivo contienen solo unos pocos segundos de datos y necesitan ser solicitadas continuamente. Habilitar esto cuando no es requerido puede causar problemas.",
"EnableStreamLooping": "Repetir automáticamente las transmisiones en vivo", "EnableStreamLooping": "Repetir automáticamente las transmisiones en vivo",
"EnablePhotosHelp": "Las imágenes serán detectadas y mostradas junto con otros archivos multimedia.", "EnablePhotosHelp": "Las imágenes serán detectadas y mostradas junto con otros archivos multimedia.",
@ -1342,7 +1316,6 @@
"ButtonUninstall": "Desinstalar", "ButtonUninstall": "Desinstalar",
"ButtonTrailer": "Trailer", "ButtonTrailer": "Trailer",
"ButtonTogglePlaylist": "Lista de reproducción", "ButtonTogglePlaylist": "Lista de reproducción",
"ButtonSubtitles": "Subtítulos",
"ButtonSubmit": "Enviar", "ButtonSubmit": "Enviar",
"ButtonSplit": "Dividir", "ButtonSplit": "Dividir",
"ButtonStop": "Detener", "ButtonStop": "Detener",
@ -1364,31 +1337,24 @@
"ButtonRename": "Renombrar", "ButtonRename": "Renombrar",
"ButtonRemove": "Remover", "ButtonRemove": "Remover",
"ButtonRefreshGuideData": "Actualizar datos de la guía", "ButtonRefreshGuideData": "Actualizar datos de la guía",
"ButtonRefresh": "Actualizar",
"ButtonQuickStartGuide": "Guía de inicio rápido", "ButtonQuickStartGuide": "Guía de inicio rápido",
"ButtonProfile": "Perfil", "ButtonProfile": "Perfil",
"ButtonPreviousTrack": "Pista anterior", "ButtonPreviousTrack": "Pista anterior",
"ButtonPlay": "Reproducir",
"ButtonPause": "Pausar", "ButtonPause": "Pausar",
"ButtonParentalControl": "Control parental", "ButtonParentalControl": "Control parental",
"ButtonOpen": "Abrir", "ButtonOpen": "Abrir",
"ButtonOk": "OK", "ButtonOk": "OK",
"ButtonOff": "Apagar",
"ButtonNextTrack": "Pista siguiente", "ButtonNextTrack": "Pista siguiente",
"ButtonNetwork": "Red", "ButtonNetwork": "Red",
"ButtonMore": "Más", "ButtonMore": "Más",
"ButtonManualLogin": "Inicio de sesión manual", "ButtonManualLogin": "Inicio de sesión manual",
"ButtonLibraryAccess": "Acceso a biblioteca(s)", "ButtonLibraryAccess": "Acceso a biblioteca(s)",
"ButtonInfo": "Info", "ButtonInfo": "Info",
"ButtonHome": "Inicio",
"ButtonGuide": "Guía", "ButtonGuide": "Guía",
"ButtonGotIt": "Hecho", "ButtonGotIt": "Hecho",
"ButtonFullscreen": "Pantalla completa", "ButtonFullscreen": "Pantalla completa",
"ButtonForgotPassword": "Olvidé mi contraseña", "ButtonForgotPassword": "Olvidé mi contraseña",
"ButtonFilter": "Filtro",
"ButtonEditOtherUserPreferences": "Editar el perfil, la imagen y las preferencias personales de este usuario.", "ButtonEditOtherUserPreferences": "Editar el perfil, la imagen y las preferencias personales de este usuario.",
"ButtonEditImages": "Editar imágenes",
"ButtonEdit": "Editar",
"ButtonChangeServer": "Cambiar servidor", "ButtonChangeServer": "Cambiar servidor",
"ButtonCancel": "Cancelar", "ButtonCancel": "Cancelar",
"ButtonBack": "Atrás", "ButtonBack": "Atrás",
@ -1475,5 +1441,6 @@
"LabelSubtitleVerticalPosition": "Posición vertical:", "LabelSubtitleVerticalPosition": "Posición vertical:",
"PreviousTrack": "Saltar al anterior", "PreviousTrack": "Saltar al anterior",
"MessageGetInstalledPluginsError": "Ocurrió un error buscando la lista de complementos instalados.", "MessageGetInstalledPluginsError": "Ocurrió un error buscando la lista de complementos instalados.",
"MessagePluginInstallError": "Ocurrió un error instalando el complemento." "MessagePluginInstallError": "Ocurrió un error instalando el complemento.",
"PlaybackRate": "Tasa de reproducción"
} }

View file

@ -7,9 +7,7 @@
"Browse": "مرور کردن", "Browse": "مرور کردن",
"ButtonAddUser": "افزودن کاربر", "ButtonAddUser": "افزودن کاربر",
"ButtonCancel": "لغو کردن", "ButtonCancel": "لغو کردن",
"ButtonFilter": "فیلتر",
"ButtonOk": "خوب", "ButtonOk": "خوب",
"ButtonPlay": "پخش",
"ButtonQuickStartGuide": "راهنمای شروع سریع", "ButtonQuickStartGuide": "راهنمای شروع سریع",
"ButtonResetPassword": "تنظیم مجدد رمز", "ButtonResetPassword": "تنظیم مجدد رمز",
"ButtonSignOut": "Sign out", "ButtonSignOut": "Sign out",
@ -20,7 +18,6 @@
"FolderTypeMusic": "موسیقی‌ها", "FolderTypeMusic": "موسیقی‌ها",
"FolderTypeMusicVideos": "موزیک ویدیوها", "FolderTypeMusicVideos": "موزیک ویدیوها",
"FolderTypeTvShows": "سریال‌های تلویزیونی", "FolderTypeTvShows": "سریال‌های تلویزیونی",
"HeaderAddUser": "اضافه کردن کاربر",
"HeaderContinueWatching": "ادامه تماشا", "HeaderContinueWatching": "ادامه تماشا",
"HeaderCustomDlnaProfiles": "پروفایل های سفارشی", "HeaderCustomDlnaProfiles": "پروفایل های سفارشی",
"HeaderDeviceAccess": "دسترسی دستگاه", "HeaderDeviceAccess": "دسترسی دستگاه",
@ -44,7 +41,6 @@
"LabelCurrentPassword": "رمز فعلی:", "LabelCurrentPassword": "رمز فعلی:",
"LabelCustomCertificatePath": "مسیر اختصاصی گواهینامه SSL:", "LabelCustomCertificatePath": "مسیر اختصاصی گواهینامه SSL:",
"LabelCustomCertificatePathHelp": "پچ به فایل PKCS #12 حاوی یک گواهینامه و کلید خصوصی است تا پشتیبانی از TLS را در یک دامنه شخصی فعال کند.", "LabelCustomCertificatePathHelp": "پچ به فایل PKCS #12 حاوی یک گواهینامه و کلید خصوصی است تا پشتیبانی از TLS را در یک دامنه شخصی فعال کند.",
"LabelDisplayMissingEpisodesWithinSeasons": "نمایش قسمت های ناموجود در بین فصل ها",
"LabelFinish": "پایان", "LabelFinish": "پایان",
"LabelLanguage": "زبان:", "LabelLanguage": "زبان:",
"LabelMaxParentalRating": "حداکثر امتیاز سنی مجاز والدین:", "LabelMaxParentalRating": "حداکثر امتیاز سنی مجاز والدین:",
@ -79,10 +75,7 @@
"ShowAdvancedSettings": "نمایش تنظیمات پیشرفته", "ShowAdvancedSettings": "نمایش تنظیمات پیشرفته",
"TabAccess": "دسترسی", "TabAccess": "دسترسی",
"TabAdvanced": "پیشرفته", "TabAdvanced": "پیشرفته",
"TabAlbumArtists": "هنرمندان آلبوم",
"TabEpisodes": "قسمت ها",
"TabLatest": "جدیدترین‌ها", "TabLatest": "جدیدترین‌ها",
"TabMusicVideos": "موزیک ویدیوها",
"TabNetworks": "شبکه ها", "TabNetworks": "شبکه ها",
"TabNotifications": "اعلان ها", "TabNotifications": "اعلان ها",
"TabProfile": "پروفایل", "TabProfile": "پروفایل",
@ -134,26 +127,21 @@
"ButtonRename": "تغییر نام", "ButtonRename": "تغییر نام",
"ButtonRemove": "حذف", "ButtonRemove": "حذف",
"ButtonRefreshGuideData": "به‌روز‌رسانی داده‌ی راهنما", "ButtonRefreshGuideData": "به‌روز‌رسانی داده‌ی راهنما",
"ButtonRefresh": "به‌روز‌رسانی",
"ButtonProfile": "نمایه", "ButtonProfile": "نمایه",
"ButtonNextTrack": "ترانه پسین", "ButtonNextTrack": "ترانه پسین",
"ButtonPreviousTrack": "ترانه پیشین", "ButtonPreviousTrack": "ترانه پیشین",
"ButtonPause": "مکث", "ButtonPause": "مکث",
"ButtonParentalControl": "رتبه بندی والدین", "ButtonParentalControl": "رتبه بندی والدین",
"ButtonOpen": "باز", "ButtonOpen": "باز",
"ButtonOff": "خاموش",
"ButtonNetwork": "شبکه", "ButtonNetwork": "شبکه",
"ButtonMore": "بیشتر", "ButtonMore": "بیشتر",
"ButtonManualLogin": "ورود دستی", "ButtonManualLogin": "ورود دستی",
"ButtonLibraryAccess": "دسترسی به کتابخانه", "ButtonLibraryAccess": "دسترسی به کتابخانه",
"ButtonInfo": "اطلاعات", "ButtonInfo": "اطلاعات",
"ButtonHome": "خانه",
"ButtonGuide": "راهنما", "ButtonGuide": "راهنما",
"ButtonGotIt": "متوجه شدم", "ButtonGotIt": "متوجه شدم",
"ButtonFullscreen": "تمام صفحه", "ButtonFullscreen": "تمام صفحه",
"ButtonForgotPassword": "فراموشی گذرواژه", "ButtonForgotPassword": "فراموشی گذرواژه",
"ButtonEditImages": "ویرایش عکس‌ها",
"ButtonEdit": "ویرایش",
"ButtonChangeServer": "تغییر سرور", "ButtonChangeServer": "تغییر سرور",
"ButtonBack": "بازگشت", "ButtonBack": "بازگشت",
"ButtonArrowRight": "راست", "ButtonArrowRight": "راست",
@ -196,8 +184,6 @@
"Episodes": "قسمت‌ها", "Episodes": "قسمت‌ها",
"EndsAtValue": "تمام شده در {0}", "EndsAtValue": "تمام شده در {0}",
"Ended": "تمام شده", "Ended": "تمام شده",
"EnableThemeVideos": "تم فیلم‌ها",
"EnableThemeSongs": "آهنگ‌های تم",
"EnableStreamLooping": "چرخش خودکار پخش‌های زنده", "EnableStreamLooping": "چرخش خودکار پخش‌های زنده",
"EnablePhotos": "نمایش عکس‌ها", "EnablePhotos": "نمایش عکس‌ها",
"EnableNextVideoInfoOverlay": "نمایش اطلاعات ودیوی بعدی حین پخش ویدیو", "EnableNextVideoInfoOverlay": "نمایش اطلاعات ودیوی بعدی حین پخش ویدیو",
@ -266,7 +252,6 @@
"ButtonWebsite": "وبسایت", "ButtonWebsite": "وبسایت",
"ButtonUninstall": "حذف نصب", "ButtonUninstall": "حذف نصب",
"ButtonTrailer": "تریلر", "ButtonTrailer": "تریلر",
"ButtonSubtitles": "زیرنویس‌ها",
"ButtonSubmit": "تایید", "ButtonSubmit": "تایید",
"ButtonSplit": "جدا کردن", "ButtonSplit": "جدا کردن",
"ButtonStop": "توقف", "ButtonStop": "توقف",
@ -305,7 +290,6 @@
"HeaderMusicQuality": "کیفیت آهنگ", "HeaderMusicQuality": "کیفیت آهنگ",
"HeaderMoreLikeThis": "موارد مشابه با این", "HeaderMoreLikeThis": "موارد مشابه با این",
"HeaderMetadataSettings": "تنظیمات ابرداده", "HeaderMetadataSettings": "تنظیمات ابرداده",
"HeaderMediaInfo": "اطلاعات رسانه",
"HeaderMediaFolders": "پوشه‌های رسانه", "HeaderMediaFolders": "پوشه‌های رسانه",
"HeaderMedia": "رسانه", "HeaderMedia": "رسانه",
"HeaderLoginFailure": "ورود ناموفق", "HeaderLoginFailure": "ورود ناموفق",
@ -328,10 +312,8 @@
"HeaderIdentificationCriteriaHelp": "حداقل یک مورد تعیین هویت وارد کنید.", "HeaderIdentificationCriteriaHelp": "حداقل یک مورد تعیین هویت وارد کنید.",
"HeaderIdentification": "تعیین هویت", "HeaderIdentification": "تعیین هویت",
"HeaderHttpHeaders": "سرفصل‌های HTTP", "HeaderHttpHeaders": "سرفصل‌های HTTP",
"HeaderHome": "خانه",
"HeaderGuideProviders": "ارائه دهنده داده راهنمای تلویزیونی", "HeaderGuideProviders": "ارائه دهنده داده راهنمای تلویزیونی",
"HeaderFrequentlyPlayed": "اغلب پخش شده", "HeaderFrequentlyPlayed": "اغلب پخش شده",
"HeaderForgotPassword": "فراموشی گذرواژه",
"HeaderForKids": "برای کودکان", "HeaderForKids": "برای کودکان",
"HeaderFetchImages": "دریافت عکس‌ها:", "HeaderFetchImages": "دریافت عکس‌ها:",
"HeaderFeatureAccess": "دسترسی‌های برجسته", "HeaderFeatureAccess": "دسترسی‌های برجسته",
@ -341,7 +323,6 @@
"HeaderFavoriteBooks": "کتاب‌های مورد علاقه", "HeaderFavoriteBooks": "کتاب‌های مورد علاقه",
"HeaderExternalIds": "ID های خارجی:", "HeaderExternalIds": "ID های خارجی:",
"HeaderError": "خطا", "HeaderError": "خطا",
"HeaderEpisodes": "قسمت‌ها",
"HeaderEnabledFieldsHelp": "یک فیلد را برای جلوگیری از تغییر در داده‌ی آن علامت بزنید تا قفل بشود.", "HeaderEnabledFieldsHelp": "یک فیلد را برای جلوگیری از تغییر در داده‌ی آن علامت بزنید تا قفل بشود.",
"HeaderEnabledFields": "فیلد‌های فعال شده", "HeaderEnabledFields": "فیلد‌های فعال شده",
"HeaderEditImages": "ویرایش عکس‌ها", "HeaderEditImages": "ویرایش عکس‌ها",
@ -362,11 +343,9 @@
"HeaderCodecProfile": "نمایه کدک", "HeaderCodecProfile": "نمایه کدک",
"HeaderChapterImages": "عکس‌های سکانس", "HeaderChapterImages": "عکس‌های سکانس",
"HeaderChannelAccess": "دسترسی به کانال", "HeaderChannelAccess": "دسترسی به کانال",
"HeaderCastCrew": "بازیگران و کارکنان",
"HeaderCastAndCrew": "بازیگران و کارکنان", "HeaderCastAndCrew": "بازیگران و کارکنان",
"HeaderCancelSeries": "لغو سریال", "HeaderCancelSeries": "لغو سریال",
"HeaderCancelRecording": "لغو ضبط", "HeaderCancelRecording": "لغو ضبط",
"HeaderBooks": "کتاب‌ها",
"HeaderBlockItemsWithNoRating": "موارد مسدود شده با نقص یا عدم وجود اطلاعات امتیاز:", "HeaderBlockItemsWithNoRating": "موارد مسدود شده با نقص یا عدم وجود اطلاعات امتیاز:",
"LabelSkipIfAudioTrackPresentHelp": "این گزینه را عدم انتخاب کنید تا اطمینان حاصل کنید که همه ویدیوها فارغ از زبان صوت، زیرنویس دارند.", "LabelSkipIfAudioTrackPresentHelp": "این گزینه را عدم انتخاب کنید تا اطمینان حاصل کنید که همه ویدیوها فارغ از زبان صوت، زیرنویس دارند.",
"LabelSkipIfAudioTrackPresent": "اگر صدای پیش‌فرض با زبان دانلودی یکسان است پرش کن", "LabelSkipIfAudioTrackPresent": "اگر صدای پیش‌فرض با زبان دانلودی یکسان است پرش کن",
@ -387,7 +366,6 @@
"ButtonAudioTracks": "آهنگ‌ها", "ButtonAudioTracks": "آهنگ‌ها",
"AlbumArtist": "هنرمند آلبوم", "AlbumArtist": "هنرمند آلبوم",
"Album": "آلبوم", "Album": "آلبوم",
"HeaderAddScheduledTaskTrigger": "افزودن فعال‌ساز",
"HeaderActivity": "فعالیت‌ها", "HeaderActivity": "فعالیت‌ها",
"HeaderActiveRecordings": "ضبط‌های فعال", "HeaderActiveRecordings": "ضبط‌های فعال",
"HeaderActiveDevices": "دستگاه‌های فعال", "HeaderActiveDevices": "دستگاه‌های فعال",
@ -517,7 +495,6 @@
"LabelImportOnlyFavoriteChannels": "محدود کردن کانال‌هایی که به عنوان مورد علاقه انتخاب شده‌اند", "LabelImportOnlyFavoriteChannels": "محدود کردن کانال‌هایی که به عنوان مورد علاقه انتخاب شده‌اند",
"LabelDateAdded": "تاریخ اضافه شده:", "LabelDateAdded": "تاریخ اضافه شده:",
"LabelCustomRating": "امتیازدهی سفارشی:", "LabelCustomRating": "امتیازدهی سفارشی:",
"LabelCustomDeviceDisplayName": "نام نمایشی:",
"LabelCustomCssHelp": "ظاهر سفارشی مورد نظر خود را در رابط وب اعمال کنید.", "LabelCustomCssHelp": "ظاهر سفارشی مورد نظر خود را در رابط وب اعمال کنید.",
"LabelCustomCss": "CSS سفارشی:", "LabelCustomCss": "CSS سفارشی:",
"LabelCriticRating": "امتیاز منتقدان:", "LabelCriticRating": "امتیاز منتقدان:",
@ -529,7 +506,6 @@
"LabelHomeNetworkQuality": "کیفیت شبکه خانگی:", "LabelHomeNetworkQuality": "کیفیت شبکه خانگی:",
"LabelHardwareAccelerationTypeHelp": "تسریع کننده سخت افزاری نیاز به پیکربندی اضافی دارد.", "LabelHardwareAccelerationTypeHelp": "تسریع کننده سخت افزاری نیاز به پیکربندی اضافی دارد.",
"LabelSupportedMediaTypes": "نوع‌ رسانه‌های پشتیبانی شده:", "LabelSupportedMediaTypes": "نوع‌ رسانه‌های پشتیبانی شده:",
"LabelSubtitles": "زیرنویس‌ها",
"LabelSubtitlePlaybackMode": "حالت زیرنویس:", "LabelSubtitlePlaybackMode": "حالت زیرنویس:",
"LabelSubtitleFormatHelp": "مثال: srt", "LabelSubtitleFormatHelp": "مثال: srt",
"LabelSubtitleDownloaders": "دانلود کننده زیرنویس:", "LabelSubtitleDownloaders": "دانلود کننده زیرنویس:",
@ -582,14 +558,12 @@
"OptionParentalRating": "رتبه بندی والدین", "OptionParentalRating": "رتبه بندی والدین",
"OptionOnInterval": "در یک فاصله", "OptionOnInterval": "در یک فاصله",
"BookLibraryHelp": "کتاب‌های صوتی و متنی پشتیبانی می‌شوند. {0} راهنمای نامگذاری کتاب {1} را مرور کنید.", "BookLibraryHelp": "کتاب‌های صوتی و متنی پشتیبانی می‌شوند. {0} راهنمای نامگذاری کتاب {1} را مرور کنید.",
"TabInfo": "اطلاعات",
"TabDirectPlay": "پخش مستقیم", "TabDirectPlay": "پخش مستقیم",
"TabDashboard": "داشبورد", "TabDashboard": "داشبورد",
"TabCodecs": "کدک‌ها", "TabCodecs": "کدک‌ها",
"TabCatalog": "فهرست", "TabCatalog": "فهرست",
"TV": "تلویزیون", "TV": "تلویزیون",
"Sunday": "یکشنبه", "Sunday": "یکشنبه",
"TabTrailers": "تریلرها",
"Suggestions": "پیشنهادها", "Suggestions": "پیشنهادها",
"Subtitles": "زیرنویس‌ها", "Subtitles": "زیرنویس‌ها",
"Studios": "استودیو‌ها", "Studios": "استودیو‌ها",
@ -608,7 +582,6 @@
"TabSettings": "تنظیمات", "TabSettings": "تنظیمات",
"TabServer": "سرور", "TabServer": "سرور",
"TabScheduledTasks": "وظایف زمان بندی شده", "TabScheduledTasks": "وظایف زمان بندی شده",
"TabResumeSettings": "ادامه",
"TabResponses": "پاسخ‌ها", "TabResponses": "پاسخ‌ها",
"TabPlugins": "افزونه‌ها", "TabPlugins": "افزونه‌ها",
"TabParentalControl": "رتبه بندی والدین", "TabParentalControl": "رتبه بندی والدین",
@ -768,7 +741,6 @@
"HeaderSelectTranscodingPath": "Select Transcoding Temporary Path", "HeaderSelectTranscodingPath": "Select Transcoding Temporary Path",
"HeaderSelectTranscodingPathHelp": "Browse or enter the path to use for transcoding temporary files. The folder must be writeable.", "HeaderSelectTranscodingPathHelp": "Browse or enter the path to use for transcoding temporary files. The folder must be writeable.",
"LabelArtistsHelp": "Separate multiple using ;", "LabelArtistsHelp": "Separate multiple using ;",
"LabelAudio": "Audio",
"LabelAudioBitDepth": "Audio bit depth:", "LabelAudioBitDepth": "Audio bit depth:",
"LabelAudioBitrate": "Audio bitrate:", "LabelAudioBitrate": "Audio bitrate:",
"LabelAudioChannels": "Audio channels:", "LabelAudioChannels": "Audio channels:",
@ -926,7 +898,6 @@
"OptionAllowVideoPlaybackTranscoding": "Allow video playback that requires transcoding", "OptionAllowVideoPlaybackTranscoding": "Allow video playback that requires transcoding",
"OptionArtist": "Artist", "OptionArtist": "Artist",
"OptionAuto": "Auto", "OptionAuto": "Auto",
"OptionAutomatic": "Auto",
"OptionAutomaticallyGroupSeries": "Automatically merge series that are spread across multiple folders", "OptionAutomaticallyGroupSeries": "Automatically merge series that are spread across multiple folders",
"OptionAutomaticallyGroupSeriesHelp": "If enabled, series that are spread across multiple folders within this library will be automatically merged into a single series.", "OptionAutomaticallyGroupSeriesHelp": "If enabled, series that are spread across multiple folders within this library will be automatically merged into a single series.",
"OptionBanner": "Banner", "OptionBanner": "Banner",
@ -1142,7 +1113,6 @@
"LabelPostProcessorArguments": "Post-processor command line arguments:", "LabelPostProcessorArguments": "Post-processor command line arguments:",
"LabelPostProcessorArgumentsHelp": "Use {path} as the path to the recording file.", "LabelPostProcessorArgumentsHelp": "Use {path} as the path to the recording file.",
"LabelPreferredDisplayLanguage": "Preferred display language:", "LabelPreferredDisplayLanguage": "Preferred display language:",
"LabelPreferredDisplayLanguageHelp": "Translating Jellyfin is an ongoing project.",
"LabelPreferredSubtitleLanguage": "Preferred subtitle language:", "LabelPreferredSubtitleLanguage": "Preferred subtitle language:",
"LabelProfileAudioCodecs": "Audio codecs:", "LabelProfileAudioCodecs": "Audio codecs:",
"LabelProfileCodecs": "Codecs:", "LabelProfileCodecs": "Codecs:",
@ -1227,8 +1197,6 @@
"LabelTime": "Time:", "LabelTime": "Time:",
"LabelTitle": "Title:", "LabelTitle": "Title:",
"LabelTrackNumber": "Track number:", "LabelTrackNumber": "Track number:",
"LabelTranscodingAudioCodec": "Audio codec:",
"LabelTranscodingContainer": "Container:",
"LabelTranscodePath": "Transcode path:", "LabelTranscodePath": "Transcode path:",
"LabelTranscodingTempPathHelp": "Specify a custom path for the transcode files served to clients. Leave blank to use the server default.", "LabelTranscodingTempPathHelp": "Specify a custom path for the transcode files served to clients. Leave blank to use the server default.",
"LabelTranscodes": "Transcodes:", "LabelTranscodes": "Transcodes:",
@ -1236,7 +1204,6 @@
"LabelTranscodingProgress": "Transcoding progress:", "LabelTranscodingProgress": "Transcoding progress:",
"LabelTranscodingThreadCount": "Transcoding thread count:", "LabelTranscodingThreadCount": "Transcoding thread count:",
"LabelTranscodingThreadCountHelp": "Select the maximum number of threads to use when transcoding. Reducing the thread count will lower CPU usage but may not convert fast enough for a smooth playback experience.", "LabelTranscodingThreadCountHelp": "Select the maximum number of threads to use when transcoding. Reducing the thread count will lower CPU usage but may not convert fast enough for a smooth playback experience.",
"LabelTranscodingVideoCodec": "Video codec:",
"LabelTriggerType": "Trigger Type:", "LabelTriggerType": "Trigger Type:",
"LabelTunerIpAddress": "Tuner IP Address:", "LabelTunerIpAddress": "Tuner IP Address:",
"LabelTunerType": "Tuner type:", "LabelTunerType": "Tuner type:",
@ -1326,7 +1293,6 @@
"MessagePlayAccessRestricted": "Playback of this content is currently restricted. Please contact your server administrator for more information.", "MessagePlayAccessRestricted": "Playback of this content is currently restricted. Please contact your server administrator for more information.",
"MessagePluginInstallDisclaimer": "Plugins built by Jellyfin community members are a great way to enhance your Jellyfin experience with additional features and benefits. Before installing, please be aware of the effects they may have on your Jellyfin Server, such as longer library scans, additional background processing, and decreased system stability.", "MessagePluginInstallDisclaimer": "Plugins built by Jellyfin community members are a great way to enhance your Jellyfin experience with additional features and benefits. Before installing, please be aware of the effects they may have on your Jellyfin Server, such as longer library scans, additional background processing, and decreased system stability.",
"MessageReenableUser": "See below to reenable", "MessageReenableUser": "See below to reenable",
"MessageSettingsSaved": "Settings saved.",
"MessageTheFollowingLocationWillBeRemovedFromLibrary": "The following media locations will be removed from your library:", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "The following media locations will be removed from your library:",
"MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please ensure it is running and try again.", "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please ensure it is running and try again.",
"MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders.", "MessageUnsetContentHelp": "Content will be displayed as plain folders. For best results use the metadata manager to set the content types of sub-folders.",

View file

@ -16,7 +16,6 @@
"LabelAudioLanguagePreference": "Äänen ensisijainen kieli:", "LabelAudioLanguagePreference": "Äänen ensisijainen kieli:",
"LabelCountry": "Maa:", "LabelCountry": "Maa:",
"LabelCurrentPassword": "Tämän hetkinen salsana:", "LabelCurrentPassword": "Tämän hetkinen salsana:",
"LabelDisplayMissingEpisodesWithinSeasons": "Näytä puuttuvat jaksot kausien sisällä",
"LabelFinish": "Valmis", "LabelFinish": "Valmis",
"LabelLanguage": "Kieli:", "LabelLanguage": "Kieli:",
"LabelMaxParentalRating": "Suurin sallittu ikäraja:", "LabelMaxParentalRating": "Suurin sallittu ikäraja:",
@ -101,32 +100,25 @@
"ButtonAudioTracks": "Ääniraidat", "ButtonAudioTracks": "Ääniraidat",
"ButtonBack": "Takaisin", "ButtonBack": "Takaisin",
"ButtonChangeServer": "Vaihda Palvelinta", "ButtonChangeServer": "Vaihda Palvelinta",
"ButtonEdit": "Muokkaa",
"ButtonEditImages": "Muokkaa kuvia",
"ButtonEditOtherUserPreferences": "Muokkaa tämän käyttäjän profiilia, kuvaa ja henkilökohtaisia asetuksia.", "ButtonEditOtherUserPreferences": "Muokkaa tämän käyttäjän profiilia, kuvaa ja henkilökohtaisia asetuksia.",
"ButtonFilter": "Suodata",
"ButtonForgotPassword": "Unohtuiko salasana", "ButtonForgotPassword": "Unohtuiko salasana",
"ButtonFullscreen": "Kokonäyttötila", "ButtonFullscreen": "Kokonäyttötila",
"ButtonGotIt": "Selvä", "ButtonGotIt": "Selvä",
"ButtonGuide": "Opas", "ButtonGuide": "Opas",
"ButtonHome": "Koti",
"ButtonInfo": "Tiedot", "ButtonInfo": "Tiedot",
"ButtonLibraryAccess": "Kiraston pääsy", "ButtonLibraryAccess": "Kiraston pääsy",
"ButtonManualLogin": "Manuaalinen kirjautuminen", "ButtonManualLogin": "Manuaalinen kirjautuminen",
"ButtonMore": "Lisää", "ButtonMore": "Lisää",
"ButtonNetwork": "Verkko", "ButtonNetwork": "Verkko",
"ButtonNextTrack": "Seuraava raita", "ButtonNextTrack": "Seuraava raita",
"ButtonOff": "Pois päältä",
"ButtonOk": "Ok", "ButtonOk": "Ok",
"ButtonOpen": "Avaa", "ButtonOpen": "Avaa",
"BurnSubtitlesHelp": "Määrittää mikäli palvelimen pitäisi polttaa tekstitykset suoraan videoon muunnoksen aikana riippuen tekstitysten formaatista. Tekstitysten polttamisen välttäminen parantaa palvelimen suorituskykyä. Valitse Automaattinen polttaaksesi sekä kuva- (esim. VOBSUB, PGS, SUB/IDX, jne.) että tekstipohjaiset (ASS/SSA) formaatit.", "BurnSubtitlesHelp": "Määrittää mikäli palvelimen pitäisi polttaa tekstitykset suoraan videoon muunnoksen aikana riippuen tekstitysten formaatista. Tekstitysten polttamisen välttäminen parantaa palvelimen suorituskykyä. Valitse Automaattinen polttaaksesi sekä kuva- (esim. VOBSUB, PGS, SUB/IDX, jne.) että tekstipohjaiset (ASS/SSA) formaatit.",
"ButtonParentalControl": "Lapsilukko", "ButtonParentalControl": "Lapsilukko",
"ButtonPause": "Tauko", "ButtonPause": "Tauko",
"ButtonPlay": "Toista",
"ButtonPreviousTrack": "Edellinen raita", "ButtonPreviousTrack": "Edellinen raita",
"ButtonProfile": "Profiili", "ButtonProfile": "Profiili",
"ButtonQuickStartGuide": "Pikaopas", "ButtonQuickStartGuide": "Pikaopas",
"ButtonRefresh": "Päivitä",
"ButtonRefreshGuideData": "Päivitä oppaan tiedot", "ButtonRefreshGuideData": "Päivitä oppaan tiedot",
"ButtonRemove": "Poista", "ButtonRemove": "Poista",
"ButtonRename": "Nimeä uudelleen", "ButtonRename": "Nimeä uudelleen",
@ -145,7 +137,6 @@
"ButtonStart": "Käynnistä", "ButtonStart": "Käynnistä",
"ButtonStop": "Pysäytä", "ButtonStop": "Pysäytä",
"ButtonSubmit": "Lähetä", "ButtonSubmit": "Lähetä",
"ButtonSubtitles": "Tekstitykset",
"ButtonTrailer": "Traileri", "ButtonTrailer": "Traileri",
"ButtonUninstall": "Poista asennus", "ButtonUninstall": "Poista asennus",
"ButtonWebsite": "Nettisivusto", "ButtonWebsite": "Nettisivusto",
@ -240,7 +231,6 @@
"EndsAtValue": "Päättyy {0}", "EndsAtValue": "Päättyy {0}",
"Ended": "Päättynyt", "Ended": "Päättynyt",
"EnableThemeSongsHelp": "Soita tunnussäveliä taustalla selatessasi kirjastoa.", "EnableThemeSongsHelp": "Soita tunnussäveliä taustalla selatessasi kirjastoa.",
"EnableThemeSongs": "Tunnuslaulut",
"EnableStreamLoopingHelp": "Laita tämä päälle, jos suoratoistot sisältävät vain muutaman sekuntin verran dataa jota tarvitsee pyytää jatkuvasti. Tämän päälle laittaminen ilman toiminnon tarvetta voi aiheuttaa ongelmia.", "EnableStreamLoopingHelp": "Laita tämä päälle, jos suoratoistot sisältävät vain muutaman sekuntin verran dataa jota tarvitsee pyytää jatkuvasti. Tämän päälle laittaminen ilman toiminnon tarvetta voi aiheuttaa ongelmia.",
"EnablePhotosHelp": "Kuvat tunnistetaan ja näytetään muiden media-tiedostojen ohessa.", "EnablePhotosHelp": "Kuvat tunnistetaan ja näytetään muiden media-tiedostojen ohessa.",
"EnablePhotos": "Näytä valokuvat", "EnablePhotos": "Näytä valokuvat",
@ -264,7 +254,6 @@
"ErrorAddingXmlTvFile": "XMLTV-tiedostoa käyttäessä tapahtui virhe. Varmista, että tiedosto on olemassa ja kokeile uudestaan.", "ErrorAddingXmlTvFile": "XMLTV-tiedostoa käyttäessä tapahtui virhe. Varmista, että tiedosto on olemassa ja kokeile uudestaan.",
"ErrorAddingTunerDevice": "Viritintä lisätessä ilmeni ongelma. Varmista, että se on kytketty oikein ja kokeile uudestaan.", "ErrorAddingTunerDevice": "Viritintä lisätessä ilmeni ongelma. Varmista, että se on kytketty oikein ja kokeile uudestaan.",
"EnableThemeVideosHelp": "Soita tunnusvideoita taustalla, selatessasi kirjastoa.", "EnableThemeVideosHelp": "Soita tunnusvideoita taustalla, selatessasi kirjastoa.",
"EnableThemeVideos": "Tunnusvideot",
"AlbumArtist": "Albumin Artisti", "AlbumArtist": "Albumin Artisti",
"Album": "Albumi", "Album": "Albumi",
"Played": "Toistetut", "Played": "Toistetut",
@ -382,10 +371,8 @@
"LabelDisplayMode": "Näyttötila:", "LabelDisplayMode": "Näyttötila:",
"LabelDateTimeLocale": "Päivämäärä ja aika:", "LabelDateTimeLocale": "Päivämäärä ja aika:",
"LabelCustomRating": "Mukautettu luokitus:", "LabelCustomRating": "Mukautettu luokitus:",
"LabelCustomDeviceDisplayName": "Näyttönimi:",
"LabelCustomCss": "Mukautettu CSS:", "LabelCustomCss": "Mukautettu CSS:",
"LabelCertificatePassword": "Sertifikaatin salasana:", "LabelCertificatePassword": "Sertifikaatin salasana:",
"LabelAudio": "Audio",
"LabelArtistsHelp": "Erota useita käyttämällä ;", "LabelArtistsHelp": "Erota useita käyttämällä ;",
"LabelAppNameExample": "Esimerkiksi: Sickbeard, Sonarr", "LabelAppNameExample": "Esimerkiksi: Sickbeard, Sonarr",
"LabelAppName": "Sovelluksen nimi", "LabelAppName": "Sovelluksen nimi",
@ -470,7 +457,6 @@
"OptionDateAdded": "Lisäyspäivä", "OptionDateAdded": "Lisäyspäivä",
"OptionDaily": "Päivittäinen", "OptionDaily": "Päivittäinen",
"OptionBluray": "Blu-ray", "OptionBluray": "Blu-ray",
"TabTrailers": "Trailerit",
"OptionBlockTvShows": "TV-sarjat", "OptionBlockTvShows": "TV-sarjat",
"OptionBlockTrailers": "Trailerit", "OptionBlockTrailers": "Trailerit",
"OptionBlockMusic": "Musiikki", "OptionBlockMusic": "Musiikki",
@ -478,7 +464,6 @@
"HeaderMoreLikeThis": "Lisää tällaista", "HeaderMoreLikeThis": "Lisää tällaista",
"HeaderMetadataSettings": "Metadata-asetukset", "HeaderMetadataSettings": "Metadata-asetukset",
"MoreMediaInfo": "Mediainfo", "MoreMediaInfo": "Mediainfo",
"HeaderMediaInfo": "Mediainfo",
"HeaderMediaFolders": "Mediakansiot", "HeaderMediaFolders": "Mediakansiot",
"HeaderMedia": "Media", "HeaderMedia": "Media",
"HeaderLibraryFolders": "Kirjaston kansiot", "HeaderLibraryFolders": "Kirjaston kansiot",
@ -564,7 +549,6 @@
"LabelTextBackgroundColor": "Tekstin taustaväri:", "LabelTextBackgroundColor": "Tekstin taustaväri:",
"LabelSupportedMediaTypes": "Tuetut mediatyypit:", "LabelSupportedMediaTypes": "Tuetut mediatyypit:",
"LabelTag": "Tunniste:", "LabelTag": "Tunniste:",
"LabelSubtitles": "Tekstitykset",
"LabelSubtitleFormatHelp": "Esimerkki: srt", "LabelSubtitleFormatHelp": "Esimerkki: srt",
"LabelStatus": "Status:", "LabelStatus": "Status:",
"LabelSource": "Lähde:", "LabelSource": "Lähde:",
@ -580,7 +564,6 @@
"LabelProtocolInfo": "Protokollan info:", "LabelProtocolInfo": "Protokollan info:",
"LabelProtocol": "Protokolla:", "LabelProtocol": "Protokolla:",
"LabelPreferredSubtitleLanguage": "Ensisijainen tekstityksen kieli:", "LabelPreferredSubtitleLanguage": "Ensisijainen tekstityksen kieli:",
"LabelPreferredDisplayLanguageHelp": "Jellyfinin kääntäminen on käynnissä oleva projekti.",
"LabelPlayerDimensions": "Soittimen mitat:", "LabelPlayerDimensions": "Soittimen mitat:",
"LabelPlayer": "Soitin:", "LabelPlayer": "Soitin:",
"LabelPlaylist": "Soittolista:", "LabelPlaylist": "Soittolista:",
@ -636,22 +619,17 @@
"TabSettings": "Asetukset", "TabSettings": "Asetukset",
"TabServer": "Palvelin", "TabServer": "Palvelin",
"TabScheduledTasks": "Ajastetut tehtävät", "TabScheduledTasks": "Ajastetut tehtävät",
"TabResumeSettings": "Jatka",
"TabResponses": "Vastaukset", "TabResponses": "Vastaukset",
"TabPlugins": "Liitännäiset", "TabPlugins": "Liitännäiset",
"TabNfoSettings": "NFO-asetukset", "TabNfoSettings": "NFO-asetukset",
"TabNetworks": "Verkot", "TabNetworks": "Verkot",
"TabMyPlugins": "Omat liittännäiseni", "TabMyPlugins": "Omat liittännäiseni",
"TabMusicVideos": "Musiikkivideot",
"TabMusic": "Musiikki", "TabMusic": "Musiikki",
"TabLogs": "Lokit", "TabLogs": "Lokit",
"TabLatest": "Uusimmat", "TabLatest": "Uusimmat",
"TabInfo": "Tiedot",
"TabEpisodes": "Jaksot",
"TabDirectPlay": "Suoratoisto", "TabDirectPlay": "Suoratoisto",
"TabDashboard": "Päänäkymä", "TabDashboard": "Päänäkymä",
"TabCatalog": "Luettelo", "TabCatalog": "Luettelo",
"TabAlbumArtists": "Albumin artistit",
"TabAdvanced": "Edistynyt", "TabAdvanced": "Edistynyt",
"TV": "TV", "TV": "TV",
"Sunday": "Sunnuntai", "Sunday": "Sunnuntai",
@ -703,7 +681,6 @@
"RecordingCancelled": "Tallennus peruttu.", "RecordingCancelled": "Tallennus peruttu.",
"RecordSeries": "Tallenna sarja", "RecordSeries": "Tallenna sarja",
"Record": "Tallenna", "Record": "Tallenna",
"OptionAutomatic": "Auto",
"OptionAuto": "Auto", "OptionAuto": "Auto",
"OptionAscending": "Nousevassa järjestyksessä", "OptionAscending": "Nousevassa järjestyksessä",
"OptionArtist": "Artisti", "OptionArtist": "Artisti",
@ -784,7 +761,6 @@
"MetadataManager": "Metadatan hallintatyökalu", "MetadataManager": "Metadatan hallintatyökalu",
"Metadata": "Metadata", "Metadata": "Metadata",
"MessageYouHaveVersionInstalled": "Sinulla on versio {0} asennettuna.", "MessageYouHaveVersionInstalled": "Sinulla on versio {0} asennettuna.",
"MessageSettingsSaved": "Asetukset tallennettu.",
"MessagePleaseWait": "Ole hyvä ja odota. Tämä voi kestää hetken.", "MessagePleaseWait": "Ole hyvä ja odota. Tämä voi kestää hetken.",
"MessageNothingHere": "Täällä ei ole mitään.", "MessageNothingHere": "Täällä ei ole mitään.",
"MessageNoPluginsInstalled": "Sinulla ei ole asennettuna yhtään liitännäistä.", "MessageNoPluginsInstalled": "Sinulla ei ole asennettuna yhtään liitännäistä.",
@ -863,10 +839,8 @@
"HeaderMusicQuality": "Musiikin laatu", "HeaderMusicQuality": "Musiikin laatu",
"HeaderLibraries": "Kirjastot", "HeaderLibraries": "Kirjastot",
"HeaderIdentification": "Tunnistautuminen", "HeaderIdentification": "Tunnistautuminen",
"HeaderForgotPassword": "Unohtuiko salasana",
"HeaderForKids": "Lapsille", "HeaderForKids": "Lapsille",
"HeaderError": "Virhe", "HeaderError": "Virhe",
"HeaderEpisodes": "Jaksot",
"HeaderEditImages": "Muokkaa kuvia", "HeaderEditImages": "Muokkaa kuvia",
"HeaderDevices": "Laitteet", "HeaderDevices": "Laitteet",
"HeaderDeleteItems": "Poista valitut", "HeaderDeleteItems": "Poista valitut",
@ -878,12 +852,10 @@
"HeaderAudioSettings": "Ääniasetukset", "HeaderAudioSettings": "Ääniasetukset",
"GroupBySeries": "Ryhmitä sarjan perusteella", "GroupBySeries": "Ryhmitä sarjan perusteella",
"Fullscreen": "Kokonäyttötila", "Fullscreen": "Kokonäyttötila",
"HeaderBooks": "Kirjat",
"HeaderAudioBooks": "Äänikirjat", "HeaderAudioBooks": "Äänikirjat",
"HeaderApiKeys": "API-avaimet", "HeaderApiKeys": "API-avaimet",
"HeaderApiKey": "API-avain", "HeaderApiKey": "API-avain",
"HeaderAdmin": "Ylläpitäjä", "HeaderAdmin": "Ylläpitäjä",
"HeaderAddUser": "Lisää käyttäjä",
"HeaderAddUpdateImage": "Lisää/Päivitä kuva", "HeaderAddUpdateImage": "Lisää/Päivitä kuva",
"HeaderAddToPlaylist": "Lisää soittolistaan", "HeaderAddToPlaylist": "Lisää soittolistaan",
"HeaderAddToCollection": "Lisää kokoelmaan", "HeaderAddToCollection": "Lisää kokoelmaan",
@ -1012,7 +984,6 @@
"LabelVideoBitrate": "Videon bitrate:", "LabelVideoBitrate": "Videon bitrate:",
"LabelWeb": "Web:", "LabelWeb": "Web:",
"LabelVideoCodec": "Videon codec:", "LabelVideoCodec": "Videon codec:",
"LabelTranscodingVideoCodec": "Video codec:",
"LabelSkipIfGraphicalSubsPresent": "Ohita, jos video sisältää upotetut tekstitykset", "LabelSkipIfGraphicalSubsPresent": "Ohita, jos video sisältää upotetut tekstitykset",
"LabelInternetQuality": "Verkkoyhteyden laatu:", "LabelInternetQuality": "Verkkoyhteyden laatu:",
"LabelEmbedAlbumArtDidl": "Upota albumin kuvamateriaali Didl:iin", "LabelEmbedAlbumArtDidl": "Upota albumin kuvamateriaali Didl:iin",
@ -1066,8 +1037,6 @@
"LabelAudioChannels": "Audiokanavia:", "LabelAudioChannels": "Audiokanavia:",
"LabelAudioBitrate": "Audion bitrate:", "LabelAudioBitrate": "Audion bitrate:",
"LabelAudioCodec": "Audio codec:", "LabelAudioCodec": "Audio codec:",
"LabelTranscodingContainer": "Säiliö:",
"LabelTranscodingAudioCodec": "Audio codec:",
"LabelSubtitleDownloaders": "Tekstitysten lataajat:", "LabelSubtitleDownloaders": "Tekstitysten lataajat:",
"LabelSpecialSeasonsDisplayName": "Erikoiskauden näyttönimi:", "LabelSpecialSeasonsDisplayName": "Erikoiskauden näyttönimi:",
"LabelSortTitle": "Lajitteluotsikko:", "LabelSortTitle": "Lajitteluotsikko:",
@ -1151,7 +1120,6 @@
"ErrorAddingListingsToSchedulesDirect": "Lineuppia Schedules Direct -käyttäjätunnuksellesi lisättäessä ilmeni virhe. Schedules Direct sallii vain rajallisen määrän lineuppeja yhdelle käyttäjätunnukselle. Mikäli haluat jatkaa, voit esimerkiksi kirjautua Schedules Direct -sivustolle ja poistaa muita listauksia käyttäjätunnukseltasi.", "ErrorAddingListingsToSchedulesDirect": "Lineuppia Schedules Direct -käyttäjätunnuksellesi lisättäessä ilmeni virhe. Schedules Direct sallii vain rajallisen määrän lineuppeja yhdelle käyttäjätunnukselle. Mikäli haluat jatkaa, voit esimerkiksi kirjautua Schedules Direct -sivustolle ja poistaa muita listauksia käyttäjätunnukseltasi.",
"EnableDecodingColorDepth10Vp9": "Salli 10-bittinen hardware dekoodaus (VP9)", "EnableDecodingColorDepth10Vp9": "Salli 10-bittinen hardware dekoodaus (VP9)",
"EnableDecodingColorDepth10Hevc": "Salli 10-bittinen hardware dekoodaus (HEVC)", "EnableDecodingColorDepth10Hevc": "Salli 10-bittinen hardware dekoodaus (HEVC)",
"HeaderCastCrew": "Näyttelijät ja henkilökunta",
"HeaderCastAndCrew": "Näyttelijät ja henkilökunta", "HeaderCastAndCrew": "Näyttelijät ja henkilökunta",
"HeaderCancelSeries": "Peruuta sarja", "HeaderCancelSeries": "Peruuta sarja",
"HeaderCancelRecording": "Peruuta tallennus", "HeaderCancelRecording": "Peruuta tallennus",
@ -1161,6 +1129,5 @@
"ApiKeysCaption": "Lista aktiivisista API-avaimista", "ApiKeysCaption": "Lista aktiivisista API-avaimista",
"HeaderApiKeysHelp": "Ulkoiset sovellukset tarvitsevat API-avaimen voidakseen toimia Jellyfin -palvelimen kanssa. Avaimet myönnetään joko kirjautumalla sisään Jellyfin -käyttäjätunnuksella tai myöntämällä sellainen sovellukselle manuaalisesti.", "HeaderApiKeysHelp": "Ulkoiset sovellukset tarvitsevat API-avaimen voidakseen toimia Jellyfin -palvelimen kanssa. Avaimet myönnetään joko kirjautumalla sisään Jellyfin -käyttäjätunnuksella tai myöntämällä sellainen sovellukselle manuaalisesti.",
"HeaderAdditionalParts": "Muut osat", "HeaderAdditionalParts": "Muut osat",
"HeaderAddScheduledTaskTrigger": "Lisää laukaisin",
"HeaderActiveRecordings": "Käynnissä olevat nauhoitukset" "HeaderActiveRecordings": "Käynnissä olevat nauhoitukset"
} }

View file

@ -12,7 +12,7 @@
"Disconnect": "Se déconnecter", "Disconnect": "Se déconnecter",
"Download": "Télécharger", "Download": "Télécharger",
"Edit": "Modifier", "Edit": "Modifier",
"EnableDisplayMirroring": "Activer l'affichage mirroir", "EnableDisplayMirroring": "Duplication d'écran",
"EndsAtValue": "Se termine à {0}", "EndsAtValue": "Se termine à {0}",
"File": "Fichier", "File": "Fichier",
"FolderTypeTvShows": "Séries TV", "FolderTypeTvShows": "Séries TV",
@ -40,7 +40,7 @@
"NewCollectionHelp": "Les collections vous permettent de créer des regroupements personnalisés de films et d'autres contenus de la bibliothèque.", "NewCollectionHelp": "Les collections vous permettent de créer des regroupements personnalisés de films et d'autres contenus de la bibliothèque.",
"NewCollectionNameExample": "Exemple: Collection Star Wars", "NewCollectionNameExample": "Exemple: Collection Star Wars",
"NoSubtitleSearchResultsFound": "Aucun résultat trouvé.", "NoSubtitleSearchResultsFound": "Aucun résultat trouvé.",
"OptionNew": "Nouveau...", "OptionNew": "Nouveau",
"OriginalAirDateValue": "Date de diffusion originale: {0}", "OriginalAirDateValue": "Date de diffusion originale: {0}",
"ParentalRating": "Classement parentale", "ParentalRating": "Classement parentale",
"Premiere": "Première", "Premiere": "Première",
@ -57,7 +57,7 @@
"SearchForSubtitles": "Rechercher des sous-titres", "SearchForSubtitles": "Rechercher des sous-titres",
"SeriesCancelled": "Série annulée.", "SeriesCancelled": "Série annulée.",
"SeriesRecordingScheduled": "Enregistrement en série programmé.", "SeriesRecordingScheduled": "Enregistrement en série programmé.",
"ServerUpdateNeeded": "Ce serveur Jellyfin doit être mis à jour. Pour télécharger la dernière version, veuillez visiter {0}", "ServerUpdateNeeded": "Ce serveur doit être mis à jour. Pour télécharger la dernière version, veuillez visiter {0}",
"Share": "Partager", "Share": "Partager",
"Subtitles": "Sous-titres", "Subtitles": "Sous-titres",
"Sunday": "Dimanche", "Sunday": "Dimanche",
@ -72,7 +72,7 @@
"WelcomeToProject": "Bienvenue dans Jellyfin !", "WelcomeToProject": "Bienvenue dans Jellyfin !",
"WizardCompleted": "C'est tout ce dont nous avons besoin pour l'instant. Jellyfin a commencé à collecter les informations de votre bibliothèque de médias. Jetez un oeil à quelques unes de nos applications, puis cliquez sur <b>Terminer</b> pour consulter le <b>Tableau de bord du serveur</b>.", "WizardCompleted": "C'est tout ce dont nous avons besoin pour l'instant. Jellyfin a commencé à collecter les informations de votre bibliothèque de médias. Jetez un oeil à quelques unes de nos applications, puis cliquez sur <b>Terminer</b> pour consulter le <b>Tableau de bord du serveur</b>.",
"Absolute": "Absolu", "Absolute": "Absolu",
"AccessRestrictedTryAgainLater": "L'accès est actuellement restreint. Veuillez réessayer plus tard.", "AccessRestrictedTryAgainLater": "Accès restreint. Veuillez réessayer plus tard.",
"Actor": "Acteur(trice)", "Actor": "Acteur(trice)",
"AddToPlayQueue": "Ajouter à la file d'attente", "AddToPlayQueue": "Ajouter à la file d'attente",
"AddedOnValue": "Ajouté le {0}", "AddedOnValue": "Ajouté le {0}",
@ -91,7 +91,7 @@
"AllowMediaConversionHelp": "Autoriser ou refuser l'accès à la fonctionnalité de conversion des médias.", "AllowMediaConversionHelp": "Autoriser ou refuser l'accès à la fonctionnalité de conversion des médias.",
"AllowOnTheFlySubtitleExtraction": "Autoriser l'extraction des sous-titres à la volée", "AllowOnTheFlySubtitleExtraction": "Autoriser l'extraction des sous-titres à la volée",
"AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux clients en format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil ne les prend pas en charge nativement.", "AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux clients en format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil ne les prend pas en charge nativement.",
"AllowRemoteAccess": "Autoriser les connexions distantes à ce serveur Jellyfin.", "AllowRemoteAccess": "Autoriser les connexions à distance sur ce serveur Jellyfin.",
"AllowRemoteAccessHelp": "Si l'option est désactivée, toutes les connexions distantes seront bloquées.", "AllowRemoteAccessHelp": "Si l'option est désactivée, toutes les connexions distantes seront bloquées.",
"Artists": "Artistes", "Artists": "Artistes",
"Books": "Livres", "Books": "Livres",
@ -108,11 +108,11 @@
"Songs": "Chansons", "Songs": "Chansons",
"Sync": "Synchroniser", "Sync": "Synchroniser",
"AllowedRemoteAddressesHelp": "Liste d'adresses IP ou d'IP/masque de sous-réseau séparées par des virgules qui seront autorisées à se connecter à distance. Si la liste est vide, toutes les adresses distantes seront autorisées.", "AllowedRemoteAddressesHelp": "Liste d'adresses IP ou d'IP/masque de sous-réseau séparées par des virgules qui seront autorisées à se connecter à distance. Si la liste est vide, toutes les adresses distantes seront autorisées.",
"AlwaysPlaySubtitles": "Toujours afficher les sous-titres", "AlwaysPlaySubtitles": "Toujours afficher",
"AlwaysPlaySubtitlesHelp": "Les sous-titres correspondant à la préférence linguistique seront chargés indépendamment de la langue de l'audio.", "AlwaysPlaySubtitlesHelp": "Les sous-titres correspondant à la préférence linguistique seront chargés sans tenir compte de la langue de l'audio.",
"AnyLanguage": "N'importe quelle langue", "AnyLanguage": "N'importe quelle langue",
"Anytime": "N'importe quand", "Anytime": "N'importe quand",
"AroundTime": "Aux environs de {0}", "AroundTime": "Environ",
"Art": "Illustration", "Art": "Illustration",
"AsManyAsPossible": "Autant que possible", "AsManyAsPossible": "Autant que possible",
"Ascending": "Croissant", "Ascending": "Croissant",
@ -141,24 +141,20 @@
"ButtonAudioTracks": "Pistes Audio", "ButtonAudioTracks": "Pistes Audio",
"ButtonBack": "Retour arrière", "ButtonBack": "Retour arrière",
"ButtonChangeServer": "Changer de serveur", "ButtonChangeServer": "Changer de serveur",
"ButtonEdit": "Modifier",
"ButtonEditImages": "Modifier les images",
"ButtonEditOtherUserPreferences": "Modifier ce profil utilisateur, son avatar et ses préférences personnelles.", "ButtonEditOtherUserPreferences": "Modifier ce profil utilisateur, son avatar et ses préférences personnelles.",
"ButtonFilter": "Filtre",
"ButtonForgotPassword": "Mot de passe oublié", "ButtonForgotPassword": "Mot de passe oublié",
"ButtonFullscreen": "Plein écran", "ButtonFullscreen": "Plein écran",
"ButtonGuide": "Guide", "ButtonGuide": "Guide",
"ButtonHome": "Accueil",
"ButtonInfo": "Informations", "ButtonInfo": "Informations",
"ButtonLibraryAccess": "Accès à la médiathèque", "ButtonLibraryAccess": "Accès à la médiathèque",
"ButtonManualLogin": "Connexion manuelle", "ButtonManualLogin": "Connexion manuelle",
"ButtonMore": "Plus", "ButtonMore": "Plus",
"ButtonNetwork": "Réseau", "ButtonNetwork": "Réseau",
"AspectRatio": "Format de visionnement", "AspectRatio": "Format de l'image",
"AskAdminToCreateLibrary": "Demander un administrateur de créer une médiathèque.", "AskAdminToCreateLibrary": "Demander un administrateur de créer une médiathèque.",
"Artist": "Artiste", "Artist": "Artiste",
"AllowFfmpegThrottlingHelp": "Quand un transcodage ou rémux se déplace après la position de relecture, suspendre le processus pour consommer moins de ressources. Ceci est le plus utile pour chercher moins. Désactiver s'il y a des problèmes de relecture.", "AllowFfmpegThrottlingHelp": "Quand un transcodage ou un remultiplexage a traité une période suffisamment longue depuis la position de lecture, le processus sera interrompu afin d'économiser des ressources. Ceci est utile principalement lors de lectures continues. À désactiver si vous éprouvez des problèmes de lecture.",
"AllowFfmpegThrottling": "Restreindre la vitesse de transcodage", "AllowFfmpegThrottling": "Limiter la vitesse de transcodage",
"AlbumArtist": "Artiste de l'Album", "AlbumArtist": "Artiste de l'Album",
"Album": "Album", "Album": "Album",
"AuthProviderHelp": "Sélectionner un fournisseur d'authentification pour authentifier le mot de passe de cet utilisateur.", "AuthProviderHelp": "Sélectionner un fournisseur d'authentification pour authentifier le mot de passe de cet utilisateur.",
@ -173,7 +169,7 @@
"DatePlayed": "Date écoutée", "DatePlayed": "Date écoutée",
"DateAdded": "Date d'ajout", "DateAdded": "Date d'ajout",
"CriticRating": "Évaluation critique", "CriticRating": "Évaluation critique",
"CopyStreamURLSuccess": "L'URL a été copié avec succès.", "CopyStreamURLSuccess": "URL copié avec succès.",
"CopyStreamURL": "Copier l'URL du stream", "CopyStreamURL": "Copier l'URL du stream",
"ContinueWatching": "Continuer à visionner", "ContinueWatching": "Continuer à visionner",
"Connect": "Connexion", "Connect": "Connexion",
@ -188,10 +184,9 @@
"Categories": "Catégories", "Categories": "Catégories",
"CancelSeries": "Annuler la série", "CancelSeries": "Annuler la série",
"CancelRecording": "Annuler l'enregistrement", "CancelRecording": "Annuler l'enregistrement",
"ButtonWebsite": "Site web", "ButtonWebsite": "Site Web",
"ButtonUninstall": "Désinstaller", "ButtonUninstall": "Désinstaller",
"ButtonTogglePlaylist": "Liste de lecture", "ButtonTogglePlaylist": "Liste de lecture",
"ButtonSubtitles": "Sous-titres",
"ButtonSubmit": "Soumettre", "ButtonSubmit": "Soumettre",
"ButtonStop": "Arrêt", "ButtonStop": "Arrêt",
"ButtonStart": "Démarrer", "ButtonStart": "Démarrer",
@ -209,15 +204,33 @@
"ButtonRename": "Renommer", "ButtonRename": "Renommer",
"ButtonRemove": "Enlever", "ButtonRemove": "Enlever",
"ButtonRefreshGuideData": "Rafraîchir les données de guide", "ButtonRefreshGuideData": "Rafraîchir les données de guide",
"ButtonRefresh": "Rafraîchir",
"ButtonProfile": "Profil", "ButtonProfile": "Profil",
"ButtonPreviousTrack": "Piste précédente", "ButtonPreviousTrack": "Piste précédente",
"ButtonPlay": "Lecture",
"ButtonPause": "Pause", "ButtonPause": "Pause",
"ButtonParentalControl": "Contrôle parentale", "ButtonParentalControl": "Contrôle parentale",
"ButtonOpen": "Ouvrir", "ButtonOpen": "Ouvrir",
"ButtonOk": "OK", "ButtonOk": "OK",
"ButtonNextTrack": "Prochaine piste", "ButtonNextTrack": "Prochaine piste",
"ButtonAddImage": "Ajouter l'image", "ButtonAddImage": "Ajouter l'image",
"BoxSet": "Coffret" "BoxSet": "Coffret",
"ChangingMetadataImageSettingsNewContent": "Les modifications aux paramètres de téléchargement de métadonnées et d'illustrations seront appliquées seulement au nouveau contenu de votre médiathèque. Vous devrez actualiser les métadonnées manuellement pour que les changements soient appliqués à l'ensemble de votre contenu.",
"ButtonTrailer": "Bande-annonce",
"ButtonSplit": "Couper",
"ButtonSelectView": "Sélectionner l'affichage",
"LabelSubtitleVerticalPosition": "Position verticale :",
"ClearQueue": "Effacer la file d'attente",
"DashboardServerName": "Serveur : {0}",
"DashboardVersionNumber": "Version : {0}",
"LabelVersionInstalled": "{0} installée",
"LabelVersion": "Version :",
"LabelValue": "Valeur:",
"LabelVideo": "Vidéo",
"DashboardArchitecture": "Architecture : {0}",
"DashboardOperatingSystem": "Système d'exploitation: {0}",
"ConfigureDateAdded": "Configure la façon dont la date d'ajout est déterminée dans le tableau de board dans les paramètres de la médiathèque",
"Composer": "Compositeur(trice)",
"CommunityRating": "Évaluation de la communauté",
"ColorTransfer": "Transfert de couleur",
"ColorSpace": "Espace colorimétrique",
"ColorPrimaries": "Primaires colorimétriques"
} }

Some files were not shown because too many files have changed in this diff Show more