diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2de383b639..abfdbeee9b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup node environment uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -57,9 +57,11 @@ jobs: steps: - name: Save PR context env: + PR_BRANCH: ${{ github.ref_name }} PR_NUMBER: ${{ github.event.number }} PR_SHA: ${{ github.event.pull_request.head.sha }} run: | + echo $PR_BRANCH > PR_branch echo $PR_NUMBER > PR_number echo $PR_SHA > PR_sha @@ -68,5 +70,6 @@ jobs: with: name: PR_context path: | + PR_branch PR_number PR_sha diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f0e5a075ca..0ca5f220a0 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,16 +19,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Initialize CodeQL - uses: github/codeql-action/init@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2 + uses: github/codeql-action/init@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 # v3.25.4 with: languages: javascript queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2 + uses: github/codeql-action/autobuild@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 # v3.25.4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8f596b4ae3cb3c588a5c46780b86dd53fef16c52 # v3.25.2 + uses: github/codeql-action/analyze@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 # v3.25.4 diff --git a/.github/workflows/commands.yml b/.github/workflows/commands.yml index ed0b44f48e..82bf06e61a 100644 --- a/.github/workflows/commands.yml +++ b/.github/workflows/commands.yml @@ -18,7 +18,7 @@ jobs: comment-id: ${{ github.event.comment.id }} reactions: '+1' - name: Checkout the latest code - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 with: token: ${{ secrets.JF_BOT_TOKEN }} fetch-depth: 0 diff --git a/.github/workflows/pr-suggestions.yml b/.github/workflows/pr-suggestions.yml index bb81dc19a9..4b71e8b41c 100644 --- a/.github/workflows/pr-suggestions.yml +++ b/.github/workflows/pr-suggestions.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 with: ref: ${{ github.event.pull_request.head.sha }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c88cc97032..f38a4d8a32 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,13 +8,40 @@ on: - completed jobs: + pr-context: + name: PR context + if: ${{ github.event.workflow_run.event == 'pull_request' }} + runs-on: ubuntu-latest + outputs: + branch: ${{ env.pr_branch }} + commit: ${{ env.pr_sha }} + pr_number: ${{ env.pr_number }} + + steps: + - name: Get PR context + uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4 + id: pr_context + with: + run_id: ${{ github.event.workflow_run.id }} + name: PR_context + + - name: Set PR context environment variables + if: ${{ steps.pr_context.conclusion == 'success' }} + run: | + echo "pr_branch=$(cat PR_branch)" >> $GITHUB_ENV + echo "pr_number=$(cat PR_number)" >> $GITHUB_ENV + echo "pr_sha=$(cat PR_sha)" >> $GITHUB_ENV + publish: permissions: contents: read deployments: write name: Deploy to Cloudflare Pages + if: ${{ always() }} runs-on: ubuntu-latest + needs: + - pr-context outputs: url: ${{ steps.cf.outputs.url }} @@ -33,32 +60,10 @@ jobs: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} projectName: jellyfin-web - branch: ${{ github.event.workflow_run.head_branch }} + branch: ${{ needs.pr-context.outputs.branch || github.ref_name }} directory: dist gitHubToken: ${{ secrets.GITHUB_TOKEN }} - pr-context: - name: PR context - if: ${{ always() && github.event.workflow_run.event == 'pull_request' }} - runs-on: ubuntu-latest - outputs: - commit: ${{ env.pr_sha }} - pr_number: ${{ env.pr_number }} - - steps: - - name: Get PR context - uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4 - id: pr_context - with: - run_id: ${{ github.event.workflow_run.id }} - name: PR_context - - - name: Set PR context environment variables - if: ${{ steps.pr_context.conclusion == 'success' }} - run: | - echo "pr_number=$(cat PR_number)" >> $GITHUB_ENV - echo "pr_sha=$(cat PR_sha)" >> $GITHUB_ENV - compose-comment: name: Compose comment if: ${{ always() }} @@ -68,7 +73,7 @@ jobs: - pr-context with: - branch: ${{ github.event.workflow_run.head_branch }} + branch: ${{ needs.pr-context.outputs.branch || github.ref_name }} commit: ${{ needs.pr-context.outputs.commit != '' && needs.pr-context.outputs.commit || github.event.workflow_run.head_sha }} preview_url: ${{ needs.publish.outputs.url }} build_workflow_run_id: ${{ github.event.workflow_run.id }} diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 531eb92a23..83a28f63d8 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup node environment uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -41,7 +41,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup node environment uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -62,7 +62,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup node environment uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -86,7 +86,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup node environment uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 @@ -107,7 +107,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 - name: Setup node environment uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 diff --git a/.github/workflows/update-sdk.yml b/.github/workflows/update-sdk.yml index 7f69cd5528..45e3749bdd 100644 --- a/.github/workflows/update-sdk.yml +++ b/.github/workflows/update-sdk.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 with: ref: master token: ${{ secrets.JF_BOT_TOKEN }} diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index e03662ab02..887c644822 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -86,6 +86,7 @@ - [GeorgeH005](https://github.com/GeorgeH005) - [JPUC1143](https://github.com/Jpuc1143) - [David Angel](https://github.com/davidangel) +- [Pithaya](https://github.com/Pithaya) ## Emby Contributors diff --git a/package-lock.json b/package-lock.json index 7d7fa0936b..f425fe2a1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jellyfin-web", - "version": "10.9.0", + "version": "10.10.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "jellyfin-web", - "version": "10.9.0", + "version": "10.10.0", "license": "GPL-2.0-or-later", "dependencies": { "@emotion/react": "11.11.4", @@ -18,7 +18,7 @@ "@fontsource/noto-sans-sc": "5.0.18", "@fontsource/noto-sans-tc": "5.0.18", "@jellyfin/libass-wasm": "4.2.1", - "@jellyfin/sdk": "0.0.0-unstable.202404101900", + "@jellyfin/sdk": "0.0.0-unstable.202405050501", "@loadable/component": "5.16.3", "@mui/icons-material": "5.15.11", "@mui/material": "5.15.11", @@ -3728,9 +3728,9 @@ "integrity": "sha512-oWK2yz8fFlMXkIuxUc9g/bqN2h56AB+8b6vF/Ikns6WZ/nmcGJ/5lcVaLI4csE83yWgmco4gHO3HyJDsM9EXcQ==" }, "node_modules/@jellyfin/sdk": { - "version": "0.0.0-unstable.202404101900", - "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202404101900.tgz", - "integrity": "sha512-/OQyJIfOMQf23eabSEOARYiHkUhwsHNQL9SenEYGuV1p9ikmIRivqHwwtbPSTC7IEO6qmq62rndfQpNpIuIjdw==", + "version": "0.0.0-unstable.202405050501", + "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202405050501.tgz", + "integrity": "sha512-d7TvTH3gGltNH7WrcuJsC+NiTV4HMCxKhzEeW1dGchA6aXRS1aEcnTqsR/ArONQDzlM6ac9Y+y9gfvJYJ6Bgyg==", "peerDependencies": { "axios": "^1.3.4" } @@ -25587,9 +25587,9 @@ "integrity": "sha512-oWK2yz8fFlMXkIuxUc9g/bqN2h56AB+8b6vF/Ikns6WZ/nmcGJ/5lcVaLI4csE83yWgmco4gHO3HyJDsM9EXcQ==" }, "@jellyfin/sdk": { - "version": "0.0.0-unstable.202404101900", - "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202404101900.tgz", - "integrity": "sha512-/OQyJIfOMQf23eabSEOARYiHkUhwsHNQL9SenEYGuV1p9ikmIRivqHwwtbPSTC7IEO6qmq62rndfQpNpIuIjdw==", + "version": "0.0.0-unstable.202405050501", + "resolved": "https://registry.npmjs.org/@jellyfin/sdk/-/sdk-0.0.0-unstable.202405050501.tgz", + "integrity": "sha512-d7TvTH3gGltNH7WrcuJsC+NiTV4HMCxKhzEeW1dGchA6aXRS1aEcnTqsR/ArONQDzlM6ac9Y+y9gfvJYJ6Bgyg==", "requires": {} }, "@jest/schemas": { diff --git a/package.json b/package.json index 795d5d32ea..e78c2a180d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jellyfin-web", - "version": "10.9.0", + "version": "10.10.0", "description": "Web interface for Jellyfin", "repository": "https://github.com/jellyfin/jellyfin-web", "license": "GPL-2.0-or-later", @@ -79,7 +79,7 @@ "@fontsource/noto-sans-sc": "5.0.18", "@fontsource/noto-sans-tc": "5.0.18", "@jellyfin/libass-wasm": "4.2.1", - "@jellyfin/sdk": "0.0.0-unstable.202404101900", + "@jellyfin/sdk": "0.0.0-unstable.202405050501", "@loadable/component": "5.16.3", "@mui/icons-material": "5.15.11", "@mui/material": "5.15.11", diff --git a/src/apps/experimental/AppOverrides.scss b/src/apps/experimental/AppOverrides.scss index 0ed30eeb61..a5f8312e8c 100644 --- a/src/apps/experimental/AppOverrides.scss +++ b/src/apps/experimental/AppOverrides.scss @@ -10,11 +10,6 @@ $mui-bp-xl: 1536px; position: relative; } -// Ensure the footer renders over the drawer -.appfooter { - z-index: 1201 !important; // mui drawer uses z-index 1200 -} - // Hide some items from the user "settings" page that are in the drawer #myPreferencesMenuPage { .lnkQuickConnectPreferences, diff --git a/src/apps/experimental/components/library/ItemsView.tsx b/src/apps/experimental/components/library/ItemsView.tsx index 93be9d1348..de9d0c6d6f 100644 --- a/src/apps/experimental/components/library/ItemsView.tsx +++ b/src/apps/experimental/components/library/ItemsView.tsx @@ -6,7 +6,7 @@ import React, { type FC, useCallback } from 'react'; import Box from '@mui/material/Box'; import classNames from 'classnames'; import { useLocalStorage } from 'hooks/useLocalStorage'; -import { useGetItem, useGetItemsViewByType } from 'hooks/useFetchItems'; +import { useGetItemsViewByType } from 'hooks/useFetchItems'; import { getDefaultLibraryViewSettings, getSettingsKey } from 'utils/items'; import { CardShape } from 'utils/card'; import Loading from 'components/loading/LoadingComponent'; @@ -28,6 +28,7 @@ import { LibraryTab } from 'types/libraryTab'; import { type LibraryViewSettings, type ParentId, ViewMode } from 'types/library'; import type { CardOptions } from 'types/cardOptions'; import type { ListOptions } from 'types/listOptions'; +import { useItem } from 'hooks/useItem'; interface ItemsViewProps { viewType: LibraryTab; @@ -79,7 +80,7 @@ const ItemsView: FC = ({ itemType, libraryViewSettings ); - const { data: item } = useGetItem(parentId); + const { data: item } = useItem(parentId || undefined); const getListOptions = useCallback(() => { const listOptions: ListOptions = { diff --git a/src/apps/experimental/routes/user/display/index.tsx b/src/apps/experimental/routes/user/display/index.tsx index f30b48f5bc..61b55bc02c 100644 --- a/src/apps/experimental/routes/user/display/index.tsx +++ b/src/apps/experimental/routes/user/display/index.tsx @@ -5,7 +5,6 @@ import React, { useCallback } from 'react'; import Page from 'components/Page'; import globalize from 'scripts/globalize'; -import theme from 'themes/theme'; import { DisplayPreferences } from './DisplayPreferences'; import { ItemDetailPreferences } from './ItemDetailPreferences'; import { LibraryPreferences } from './LibraryPreferences'; @@ -80,11 +79,7 @@ export default function UserDisplayPreferences() { diff --git a/src/components/appFooter/appFooter.scss b/src/components/appFooter/appFooter.scss index 1048a8e214..020a257369 100644 --- a/src/components/appFooter/appFooter.scss +++ b/src/components/appFooter/appFooter.scss @@ -2,7 +2,7 @@ position: fixed; left: 0; right: 0; - z-index: 10; + z-index: 1201 !important; // mui drawer uses z-index 1200 bottom: 0; transition: transform 180ms linear; contain: layout style; diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index acbe05c270..6d0c73afe0 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -4,6 +4,7 @@ * @module components/cardBuilder/cardBuilder */ +import { PersonKind } from '@jellyfin/sdk/lib/generated-client/models/person-kind'; import escapeHtml from 'escape-html'; import browser from 'scripts/browser'; @@ -698,8 +699,26 @@ function getCardFooterText(item, apiClient, options, footerClass, progressHtml, } } - if (options.showPersonRoleOrType && item.Role) { - lines.push(globalize.translate('PersonRole', escapeHtml(item.Role))); + if (options.showPersonRoleOrType && item.Type) { + if (item.Role) { + if ([ PersonKind.Actor, PersonKind.GuestStar ].includes(item.Type)) { + // List actor roles formatted like "as Character Name" + lines.push(globalize.translate('PersonRole', escapeHtml(item.Role))); + } else if (item.Role.toLowerCase() === item.Type.toLowerCase()) { + // Role and Type are the same so use the localized Type + lines.push(escapeHtml(globalize.translate(item.Type))); + } else if (item.Role.toLowerCase().includes(item.Type.toLowerCase())) { + // Avoid duplication if the Role includes the Type (i.e. Executive Producer) + lines.push(escapeHtml(item.Role)); + } else { + // Type and Role are unique so list both (i.e. Writer | Novel) + lines.push(escapeHtml(globalize.translate(item.Type))); + lines.push(escapeHtml(item.Role)); + } + } else { + // No Role so use the localized Type + lines.push(escapeHtml(globalize.translate(item.Type))); + } } } @@ -1285,8 +1304,7 @@ function updateUserData(card, userData) { if (!playedIndicator) { playedIndicator = document.createElement('div'); - playedIndicator.classList.add('playedIndicator'); - playedIndicator.classList.add('indicator'); + playedIndicator.classList.add('playedIndicator', 'indicator'); indicatorsElem = ensureIndicators(card, indicatorsElem); indicatorsElem.appendChild(playedIndicator); } @@ -1302,7 +1320,7 @@ function updateUserData(card, userData) { if (!countIndicator) { countIndicator = document.createElement('div'); - countIndicator.classList.add('countIndicator'); + countIndicator.classList.add('countIndicator', 'indicator'); indicatorsElem = ensureIndicators(card, indicatorsElem); indicatorsElem.appendChild(countIndicator); } diff --git a/src/components/dashboard/users/UserPasswordForm.tsx b/src/components/dashboard/users/UserPasswordForm.tsx index 3f0d70967d..9b7cac235e 100644 --- a/src/components/dashboard/users/UserPasswordForm.tsx +++ b/src/components/dashboard/users/UserPasswordForm.tsx @@ -165,7 +165,7 @@ const UserPasswordForm: FunctionComponent = ({ userId }: IProps) => { { - if (!item.Id || userExcludeItems.indexOf(item.Id) !== -1) { + if (!item.Id || userExcludeItems.includes(item.Id)) { return; } - if (!item.CollectionType || excludeViewTypes.indexOf(item.CollectionType) !== -1) { + if (item.CollectionType && excludeViewTypes.includes(item.CollectionType)) { return; } diff --git a/src/components/indicators/indicators.js b/src/components/indicators/indicators.js index ec21ae3e7f..8a6d53f012 100644 --- a/src/components/indicators/indicators.js +++ b/src/components/indicators/indicators.js @@ -78,7 +78,7 @@ export function getPlayedIndicatorHtml(item) { if (enablePlayedIndicator(item)) { const userData = item.UserData || {}; if (userData.UnplayedItemCount) { - return '
' + datetime.toLocaleString(userData.UnplayedItemCount) + '
'; + return '
' + formatCountIndicator(userData.UnplayedItemCount) + '
'; } if (userData.PlayedPercentage && userData.PlayedPercentage >= 100 || (userData.Played)) { @@ -93,12 +93,16 @@ export function getChildCountIndicatorHtml(item, options) { const minCount = options?.minCount ? options.minCount : 0; if (item.ChildCount && item.ChildCount > minCount) { - return '
' + datetime.toLocaleString(item.ChildCount) + '
'; + return '
' + formatCountIndicator(item.ChildCount) + '
'; } return ''; } +function formatCountIndicator(count) { + return count >= 100 ? '99+' : count.toString(); +} + export function getTimerIndicator(item) { let status; diff --git a/src/components/indicators/useIndicator.tsx b/src/components/indicators/useIndicator.tsx index a9ecc12bc8..7f16606359 100644 --- a/src/components/indicators/useIndicator.tsx +++ b/src/components/indicators/useIndicator.tsx @@ -60,6 +60,10 @@ const enablePlayedIndicator = (item: ItemDto) => { return itemHelper.canMarkPlayed(item); }; +const formatCountIndicator = (count: number) => { + return count >= 100 ? '99+' : count.toString(); +}; + const useIndicator = (item: ItemDto) => { const getMediaSourceIndicator = () => { const mediaSourceCount = item.MediaSourceCount ?? 0; @@ -135,7 +139,7 @@ const useIndicator = (item: ItemDto) => { if (childCount > 1) { return ( - {datetime.toLocaleString(item.ChildCount)} + {formatCountIndicator(childCount)} ); } @@ -149,7 +153,7 @@ const useIndicator = (item: ItemDto) => { if (userData.UnplayedItemCount) { return ( - {datetime.toLocaleString(userData.UnplayedItemCount)} + {formatCountIndicator(userData.UnplayedItemCount)} ); } diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index fd7d82b42e..263a557164 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -280,11 +280,11 @@ export function getCommands(options) { }); } - if (item.PlaylistItemId && options.playlistId) { + if (item.PlaylistItemId && options.playlistId && options.canEditPlaylist) { commands.push({ name: globalize.translate('RemoveFromPlaylist'), id: 'removefromplaylist', - icon: 'remove' + icon: 'playlist_remove' }); } @@ -292,7 +292,7 @@ export function getCommands(options) { commands.push({ name: globalize.translate('RemoveFromCollection'), id: 'removefromcollection', - icon: 'remove' + icon: 'playlist_remove' }); } @@ -696,6 +696,6 @@ export function show(options) { } export default { - getCommands: getCommands, - show: show + getCommands, + show }; diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.js b/src/components/libraryoptionseditor/libraryoptionseditor.js index c52e62f30f..91ae5945c9 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.js +++ b/src/components/libraryoptionseditor/libraryoptionseditor.js @@ -432,6 +432,12 @@ export function setContentType(parent, contentType) { parent.querySelector('.fldAllowEmbeddedSubtitlesContainer').classList.add('hide'); } + if (contentType === 'music') { + parent.querySelector('.lyricSettingsSection').classList.remove('hide'); + } else { + parent.querySelector('.lyricSettingsSection').classList.add('hide'); + } + parent.querySelector('.chkAutomaticallyAddToCollectionContainer').classList.toggle('hide', contentType !== 'movies' && contentType !== 'mixed'); return populateMetadataSettings(parent, contentType); @@ -536,6 +542,7 @@ export function getLibraryOptions(parent) { SkipSubtitlesIfEmbeddedSubtitlesPresent: parent.querySelector('#chkSkipIfGraphicalSubsPresent').checked, SkipSubtitlesIfAudioTrackMatches: parent.querySelector('#chkSkipIfAudioTrackPresent').checked, SaveSubtitlesWithMedia: parent.querySelector('#chkSaveSubtitlesLocally').checked, + SaveLyricsWithMedia: parent.querySelector('#chkSaveLyricsLocally').checked, RequirePerfectSubtitleMatch: parent.querySelector('#chkRequirePerfectMatch').checked, AutomaticallyAddToCollection: parent.querySelector('#chkAutomaticallyAddToCollection').checked, MetadataSavers: Array.prototype.map.call(Array.prototype.filter.call(parent.querySelectorAll('.chkMetadataSaver'), elem => { @@ -596,6 +603,7 @@ export function setLibraryOptions(parent, options) { parent.querySelector('#selectAllowEmbeddedSubtitles').value = options.AllowEmbeddedSubtitles; parent.querySelector('#chkSkipIfGraphicalSubsPresent').checked = options.SkipSubtitlesIfEmbeddedSubtitlesPresent; parent.querySelector('#chkSaveSubtitlesLocally').checked = options.SaveSubtitlesWithMedia; + parent.querySelector('#chkSaveLyricsLocally').checked = options.SaveLyricsWithMedia; parent.querySelector('#chkSkipIfAudioTrackPresent').checked = options.SkipSubtitlesIfAudioTrackMatches; parent.querySelector('#chkRequirePerfectMatch').checked = options.RequirePerfectSubtitleMatch; parent.querySelector('#chkAutomaticallyAddToCollection').checked = options.AutomaticallyAddToCollection; diff --git a/src/components/libraryoptionseditor/libraryoptionseditor.template.html b/src/components/libraryoptionseditor/libraryoptionseditor.template.html index 18c288cc6b..b1d358cc02 100644 --- a/src/components/libraryoptionseditor/libraryoptionseditor.template.html +++ b/src/components/libraryoptionseditor/libraryoptionseditor.template.html @@ -193,3 +193,15 @@
${SaveSubtitlesIntoMediaFoldersHelp}
+ +
+

${Lyrics}

+ +
+ +
${SaveLyricsIntoMediaFoldersHelp}
+
+
diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index d5e11b8468..df1a61c6a5 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -591,8 +591,7 @@ function setFieldVisibilities(context, item) { || item.Type === 'Genre' || item.Type === 'Studio' || item.Type === 'MusicGenre' - || item.Type === 'TvChannel' - || item.Type === 'Book') { + || item.Type === 'TvChannel') { hideElement('#peopleCollapsible', context); } else { showElement('#peopleCollapsible', context); diff --git a/src/components/metadataEditor/personEditor.template.html b/src/components/metadataEditor/personEditor.template.html index fd8982b9fe..b541a5c246 100644 --- a/src/components/metadataEditor/personEditor.template.html +++ b/src/components/metadataEditor/personEditor.template.html @@ -26,6 +26,18 @@ + + + + + + + + + + + + diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index 4d7d77a45e..b73ce0d888 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -43,8 +43,7 @@ let currentRuntimeTicks = 0; let isVisibilityAllowed = true; -let lyricPageActive = false; -let isAudio = false; +let isLyricPageActive = false; function getNowPlayingBarHtml() { let html = ''; @@ -86,7 +85,7 @@ function getNowPlayingBarHtml() { html += ``; - html += ``; + html += ``; html += ``; html += ``; @@ -220,7 +219,7 @@ function bindEvents(elem) { }); lyricButton.addEventListener('click', function() { - if (lyricPageActive) { + if (isLyricPageActive) { appRouter.back(); } else { appRouter.show('lyrics'); @@ -303,8 +302,8 @@ function getNowPlayingBar() { nowPlayingBarElement = parentContainer.querySelector('.nowPlayingBar'); if (layoutManager.mobile) { - hideButton(nowPlayingBarElement.querySelector('.btnShuffleQueue')); - hideButton(nowPlayingBarElement.querySelector('.nowPlayingBarCenter')); + nowPlayingBarElement.querySelector('.btnShuffleQueue').classList.add('hide'); + nowPlayingBarElement.querySelector('.nowPlayingBarCenter').classList.add('hide'); } if (browser.safari && browser.slow) { @@ -319,14 +318,6 @@ function getNowPlayingBar() { return nowPlayingBarElement; } -function showButton(button) { - button.classList.remove('hide'); -} - -function hideButton(button) { - button.classList.add('hide'); -} - function updatePlayPauseState(isPaused) { if (playPauseButtons) { playPauseButtons.forEach((button) => { @@ -378,7 +369,7 @@ function updatePlayerStateInternal(event, state, player) { updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playbackManager.getBufferedRanges(player)); updateNowPlayingInfo(state); - updateLyricButton(); + updateLyricButton(nowPlayingItem); } function updateRepeatModeDisplay(repeatMode) { @@ -453,11 +444,7 @@ function updatePlayerVolumeState(isMuted, volumeLevel) { showVolumeSlider = false; } - if (showMuteButton) { - showButton(muteButton); - } else { - hideButton(muteButton); - } + muteButton.classList.toggle('hide', !showMuteButton); // See bindEvents for why this is necessary if (volumeSlider) { @@ -469,20 +456,18 @@ function updatePlayerVolumeState(isMuted, volumeLevel) { } } -function updateLyricButton() { - if (!isEnabled) { - return; - } +function updateLyricButton(item) { + if (!isEnabled) return; - isAudio ? showButton(lyricButton) : hideButton(lyricButton); + const hasLyrics = !!item && item.Type === 'Audio' && item.HasLyrics; + lyricButton.classList.toggle('hide', !hasLyrics); setLyricButtonActiveStatus(); } function setLyricButtonActiveStatus() { - if (!isEnabled) { - return; - } - lyricButton.classList.toggle('buttonActive', lyricPageActive); + if (!isEnabled) return; + + lyricButton.classList.toggle('buttonActive', isLyricPageActive); } function seriesImageUrl(item, options) { @@ -628,8 +613,6 @@ function onPlaybackStart(e, state) { console.debug('nowplaying event: ' + e.type); const player = this; - isAudio = state.NowPlayingItem.Type === 'Audio'; - onStateChanged.call(player, e, state); } @@ -733,7 +716,7 @@ function onStateChanged(event, state) { } getNowPlayingBar(); - updateLyricButton(); + updateLyricButton(state.NowPlayingItem); updatePlayerStateInternal(event, state, player); } @@ -790,7 +773,7 @@ function refreshFromPlayer(player, type) { } function bindToPlayer(player) { - lyricPageActive = appRouter.currentRouteInfo.path.toLowerCase() === '/lyrics'; + isLyricPageActive = appRouter.currentRouteInfo.path.toLowerCase() === '/lyrics'; if (player === currentPlayer) { return; } @@ -823,7 +806,7 @@ Events.on(playbackManager, 'playerchange', function () { bindToPlayer(playbackManager.getCurrentPlayer()); document.addEventListener('viewbeforeshow', function (e) { - lyricPageActive = appRouter.currentRouteInfo.path.toLowerCase() === '/lyrics'; + isLyricPageActive = appRouter.currentRouteInfo.path.toLowerCase() === '/lyrics'; setLyricButtonActiveStatus(); if (!e.detail.options.enableMediaControl) { if (isVisibilityAllowed) { diff --git a/src/components/playback/displayMirrorManager.ts b/src/components/playback/displayMirrorManager.ts index f74b3e10fb..a8a7b1b7a1 100644 --- a/src/components/playback/displayMirrorManager.ts +++ b/src/components/playback/displayMirrorManager.ts @@ -1,38 +1,40 @@ -import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'; +import ServerConnections from 'components/ServerConnections'; +import { getItemQuery } from 'hooks/useItem'; +import { toApi } from 'utils/jellyfin-apiclient/compat'; +import { queryClient } from 'utils/query/queryClient'; import { playbackManager } from './playbackmanager'; -interface PlaybackInfo { - item: BaseItemDto; - context?: string; -} - -function mirrorItem(info: PlaybackInfo, player?: unknown) { - const { item } = info; - - playbackManager.displayContent({ - ItemName: item.Name, - ItemId: item.Id, - ItemType: item.Type, - Context: info.context - }, player); -} - -function mirrorIfEnabled(info: PlaybackInfo) { - if (info && playbackManager.enableDisplayMirroring()) { +async function mirrorIfEnabled(serverId: string, itemId: string) { + if (playbackManager.enableDisplayMirroring()) { const playerInfo = playbackManager.getPlayerInfo(); if (playerInfo && !playerInfo.isLocalPlayer && playerInfo.supportedCommands.indexOf('DisplayContent') !== -1) { - mirrorItem(info, playbackManager.getCurrentPlayer()); + const apiClient = ServerConnections.getApiClient(serverId); + const api = toApi(apiClient); + const userId = apiClient.getCurrentUserId(); + + try { + const item = await queryClient.fetchQuery(getItemQuery( + api, + userId, + itemId)); + + playbackManager.displayContent({ + ItemName: item.Name, + ItemId: item.Id, + ItemType: item.Type + }, playbackManager.getCurrentPlayer()); + } catch (err) { + console.error('[DisplayMirrorManager] failed to mirror item', err); + } } } } document.addEventListener('viewshow', e => { - const state = e.detail.state || {}; - const { item } = state; - - if (item?.ServerId) { - mirrorIfEnabled({ item }); + const { serverId, id } = e.detail?.params || {}; + if (serverId && id) { + void mirrorIfEnabled(serverId, id); } }); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index 02c5e7ece9..80b64a2ba9 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -18,6 +18,7 @@ import { PluginType } from '../../types/plugin.ts'; import { includesAny } from '../../utils/container.ts'; import { getItems } from '../../utils/jellyfin-apiclient/getItems.ts'; import { getItemBackdropImageUrl } from '../../utils/jellyfin-apiclient/backdropImage'; +import { MediaType } from '@jellyfin/sdk/lib/generated-client/models/media-type'; import { MediaError } from 'types/mediaError'; import { getMediaError } from 'utils/mediaError'; @@ -1789,42 +1790,85 @@ class PlaybackManager { }); } - function translateItemsForPlayback(items, options) { - if (!items.length) return Promise.resolve([]); + async function translateItemsForPlayback(items, options) { + if (!items.length) return []; - if (items.length > 1 && options && options.ids) { + sortItemsIfNeeded(items, options); + + const firstItem = items[0]; + const serverId = firstItem.ServerId; + const queryOptions = options.queryOptions || {}; + + const promise = getPlaybackPromise(firstItem, serverId, options, queryOptions, items); + + if (promise) { + const result = await promise; + return result ? result.Items : items; + } else { + return items; + } + } + + function sortItemsIfNeeded(items, options) { + if (items.length > 1 && options?.ids) { // Use the original request id array for sorting the result in the proper order items.sort(function (a, b) { return options.ids.indexOf(a.Id) - options.ids.indexOf(b.Id); }); } + } - const firstItem = items[0]; - let promise; + function getPlaybackPromise(firstItem, serverId, options, queryOptions, items) { + switch (firstItem.Type) { + case 'Program': + return getItemsForPlayback(serverId, { + Ids: firstItem.ChannelId + }); + case 'Playlist': + return getItemsForPlayback(serverId, { + ParentId: firstItem.Id, + SortBy: options.shuffle ? 'Random' : null + }); + case 'MusicArtist': + return getItemsForPlayback(serverId, mergePlaybackQueries({ + ArtistIds: firstItem.Id, + Filters: 'IsNotFolder', + Recursive: true, + SortBy: options.shuffle ? 'Random' : 'SortName', + MediaTypes: 'Audio' + }, queryOptions)); + case 'PhotoAlbum': + return getItemsForPlayback(serverId, mergePlaybackQueries({ + ParentId: firstItem.Id, + Filters: 'IsNotFolder', + // Setting this to true may cause some incorrect sorting + Recursive: false, + SortBy: options.shuffle ? 'Random' : 'SortName', + // Only include Photos because we do not handle mixed queues currently + MediaTypes: 'Photo', + Limit: UNLIMITED_ITEMS + }, queryOptions)); + case 'MusicGenre': + return getItemsForPlayback(serverId, mergePlaybackQueries({ + GenreIds: firstItem.Id, + Filters: 'IsNotFolder', + Recursive: true, + SortBy: options.shuffle ? 'Random' : 'SortName', + MediaTypes: 'Audio' + }, queryOptions)); + case 'Series': + case 'Season': + return getSeriesOrSeasonPlaybackPromise(firstItem, options, items); + case 'Episode': + return getEpisodePlaybackPromise(firstItem, options, items); + } - const serverId = firstItem.ServerId; + return getNonItemTypePromise(firstItem, serverId, options, queryOptions); + } - const queryOptions = options.queryOptions || {}; - - if (firstItem.Type === 'Program') { - promise = getItemsForPlayback(serverId, { - Ids: firstItem.ChannelId - }); - } else if (firstItem.Type === 'Playlist') { - promise = getItemsForPlayback(serverId, { - ParentId: firstItem.Id, - SortBy: options.shuffle ? 'Random' : null - }); - } else if (firstItem.Type === 'MusicArtist') { - promise = getItemsForPlayback(serverId, mergePlaybackQueries({ - ArtistIds: firstItem.Id, - Filters: 'IsNotFolder', - Recursive: true, - SortBy: options.shuffle ? 'Random' : 'SortName', - MediaTypes: 'Audio' - }, queryOptions)); - } else if (firstItem.MediaType === 'Photo') { - promise = getItemsForPlayback(serverId, mergePlaybackQueries({ + function getNonItemTypePromise(firstItem, serverId, options, queryOptions) { + if (firstItem.MediaType === 'Photo') { + return getItemsForPlayback(serverId, mergePlaybackQueries({ ParentId: firstItem.ParentId, Filters: 'IsNotFolder', // Setting this to true may cause some incorrect sorting @@ -1847,66 +1891,8 @@ class PlaybackManager { return Promise.resolve(result); }); - } else if (firstItem.Type === 'PhotoAlbum') { - promise = getItemsForPlayback(serverId, mergePlaybackQueries({ - ParentId: firstItem.Id, - Filters: 'IsNotFolder', - // Setting this to true may cause some incorrect sorting - Recursive: false, - SortBy: options.shuffle ? 'Random' : 'SortName', - // Only include Photos because we do not handle mixed queues currently - MediaTypes: 'Photo', - Limit: UNLIMITED_ITEMS - }, queryOptions)); - } else if (firstItem.Type === 'MusicGenre') { - promise = getItemsForPlayback(serverId, mergePlaybackQueries({ - GenreIds: firstItem.Id, - Filters: 'IsNotFolder', - Recursive: true, - SortBy: options.shuffle ? 'Random' : 'SortName', - MediaTypes: 'Audio' - }, queryOptions)); - } else if (firstItem.Type === 'Series' || firstItem.Type === 'Season') { - const apiClient = ServerConnections.getApiClient(firstItem.ServerId); - const isSeason = firstItem.Type === 'Season'; - - promise = apiClient.getEpisodes(firstItem.SeriesId || firstItem.Id, { - IsVirtualUnaired: false, - IsMissing: false, - SeasonId: isSeason ? firstItem.Id : undefined, - SortBy: options.shuffle ? 'Random' : undefined, - UserId: apiClient.getCurrentUserId(), - Fields: ['Chapters', 'Trickplay'] - }).then(function (episodesResult) { - const originalResults = episodesResult.Items; - - let foundItem = false; - - if (!options.shuffle) { - episodesResult.Items = episodesResult.Items.filter(function (e) { - if (foundItem) { - return true; - } - - if (!e.UserData.Played) { - foundItem = true; - return true; - } - - return false; - }); - } - - if (episodesResult.Items.length === 0) { - episodesResult.Items = originalResults; - } - - episodesResult.TotalRecordCount = episodesResult.Items.length; - - return episodesResult; - }); } else if (firstItem.IsFolder && firstItem.CollectionType === 'homevideos') { - promise = getItemsForPlayback(serverId, mergePlaybackQueries({ + return getItemsForPlayback(serverId, mergePlaybackQueries({ ParentId: firstItem.Id, Filters: 'IsNotFolder', Recursive: true, @@ -1922,7 +1908,8 @@ class PlaybackManager { } else if (firstItem.Type !== 'BoxSet') { sortBy = 'SortName'; } - promise = getItemsForPlayback(serverId, mergePlaybackQueries({ + + return getItemsForPlayback(serverId, mergePlaybackQueries({ ParentId: firstItem.Id, Filters: 'IsNotFolder', Recursive: true, @@ -1930,39 +1917,6 @@ class PlaybackManager { SortBy: sortBy, MediaTypes: 'Audio,Video' }, queryOptions)); - } else if (firstItem.Type === 'Episode' && items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) { - promise = new Promise(function (resolve, reject) { - const apiClient = ServerConnections.getApiClient(firstItem.ServerId); - - apiClient.getCurrentUser().then(function (user) { - if (!user.Configuration.EnableNextEpisodeAutoPlay || !firstItem.SeriesId) { - resolve(null); - return; - } - - apiClient.getEpisodes(firstItem.SeriesId, { - IsVirtualUnaired: false, - IsMissing: false, - UserId: apiClient.getCurrentUserId(), - Fields: ['Chapters', 'Trickplay'] - }).then(function (episodesResult) { - let foundItem = false; - episodesResult.Items = episodesResult.Items.filter(function (e) { - if (foundItem) { - return true; - } - if (e.Id === firstItem.Id) { - foundItem = true; - return true; - } - - return false; - }); - episodesResult.TotalRecordCount = episodesResult.Items.length; - resolve(episodesResult); - }, reject); - }); - }); } if (promise) { @@ -1972,9 +1926,95 @@ class PlaybackManager { } return result ? result.Items : items; }); - } else { - return Promise.resolve(items); } + + return null; + } + + async function getSeriesOrSeasonPlaybackPromise(firstItem, options, items) { + const apiClient = ServerConnections.getApiClient(firstItem.ServerId); + const startSeasonId = firstItem.Type === 'Season' ? items[options.startIndex || 0].Id : undefined; + + const episodesResult = await apiClient.getEpisodes(firstItem.SeriesId || firstItem.Id, { + IsVirtualUnaired: false, + IsMissing: false, + SeasonId: (startSeasonId && items.length === 1) ? startSeasonId : undefined, + SortBy: options.shuffle ? 'Random' : undefined, + UserId: apiClient.getCurrentUserId(), + Fields: ['Chapters', 'Trickplay'] + }); + + if (options.shuffle) { + episodesResult.StartIndex = 0; + } else { + episodesResult.StartIndex = undefined; + let seasonStartIndex; + for (const [index, e] of episodesResult.Items.entries()) { + if (startSeasonId) { + if (e.SeasonId == startSeasonId) { + if (seasonStartIndex === undefined) { + seasonStartIndex = index; + } + } else { + continue; + } + } + if (!e.UserData.Played) { + episodesResult.StartIndex = index; + break; + } + } + episodesResult.StartIndex = episodesResult.StartIndex || seasonStartIndex || 0; + } + + // TODO: fix calling code to read episodesResult.StartIndex instead when set. + options.startIndex = episodesResult.StartIndex; + + episodesResult.TotalRecordCount = episodesResult.Items.length; + + return episodesResult; + } + + function getEpisodePlaybackPromise(firstItem, options, items) { + if (items.length === 1 && getPlayer(firstItem, options).supportsProgress !== false) { + return getEpisodes(firstItem, options); + } else { + return null; + } + } + + function getEpisodes(firstItem, options) { + return new Promise(function (resolve, reject) { + const apiClient = ServerConnections.getApiClient(firstItem.ServerId); + + if (!firstItem.SeriesId) { + resolve(null); + return; + } + + apiClient.getEpisodes(firstItem.SeriesId, { + IsVirtualUnaired: false, + IsMissing: false, + UserId: apiClient.getCurrentUserId(), + Fields: ['Chapters', 'Trickplay'] + }).then(function (episodesResult) { + resolve(filterEpisodes(episodesResult, firstItem, options)); + }, reject); + }); + } + + function filterEpisodes(episodesResult, firstItem, options) { + for (const [index, e] of episodesResult.Items.entries()) { + if (e.Id === firstItem.Id) { + episodesResult.StartIndex = index; + break; + } + } + + // TODO: fix calling code to read episodesResult.StartIndex instead when set. + options.startIndex = episodesResult.StartIndex; + episodesResult.TotalRecordCount = episodesResult.Items.length; + return episodesResult; } self.translateItemsForPlayback = translateItemsForPlayback; @@ -2252,35 +2292,42 @@ class PlaybackManager { playOptions.isFirstItem = true; } - return runInterceptors(item, playOptions).then(function () { - if (playOptions.fullscreen) { - loading.show(); - } + const apiClient = ServerConnections.getApiClient(item.ServerId); - // TODO: This should be the media type requested, not the original media type - const mediaType = item.MediaType; + // TODO: This should be the media type requested, not the original media type + const mediaType = item.MediaType; - const onBitrateDetectionFailure = function () { - return playAfterBitrateDetect(getSavedMaxStreamingBitrate(ServerConnections.getApiClient(item.ServerId), mediaType), item, playOptions, onPlaybackStartedFn, prevSource); - }; - - if (!isServerItem(item) || itemHelper.isLocalItem(item)) { - return onBitrateDetectionFailure(); - } - - const apiClient = ServerConnections.getApiClient(item.ServerId); - apiClient.getEndpointInfo().then(function (endpointInfo) { - if ((mediaType === 'Video' || mediaType === 'Audio') && appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType)) { - return apiClient.detectBitrate().then(function (bitrate) { - appSettings.maxStreamingBitrate(endpointInfo.IsInNetwork, mediaType, bitrate); - - return playAfterBitrateDetect(bitrate, item, playOptions, onPlaybackStartedFn, prevSource); - }, onBitrateDetectionFailure); - } else { - onBitrateDetectionFailure(); + return runInterceptors(item, playOptions) + .then(() => { + if (playOptions.fullscreen) { + loading.show(); } - }, onBitrateDetectionFailure); - }, onInterceptorRejection); + + if (!isServerItem(item) || itemHelper.isLocalItem(item)) { + return Promise.reject('skip bitrate detection'); + } + + return apiClient.getEndpointInfo().then((endpointInfo) => { + if ((mediaType === 'Video' || mediaType === 'Audio') && appSettings.enableAutomaticBitrateDetection(endpointInfo.IsInNetwork, mediaType)) { + return apiClient.detectBitrate().then((bitrate) => { + appSettings.maxStreamingBitrate(endpointInfo.IsInNetwork, mediaType, bitrate); + return bitrate; + }); + } + + return Promise.reject('skip bitrate detection'); + }); + }) + .catch(() => getSavedMaxStreamingBitrate(apiClient, mediaType)) + .then((bitrate) => { + return playAfterBitrateDetect(bitrate, item, playOptions, onPlaybackStartedFn, prevSource); + }) + .catch(onInterceptorRejection) + .finally(() => { + if (playOptions.fullscreen) { + loading.hide(); + } + }); } function cancelPlayback() { @@ -2294,8 +2341,21 @@ class PlaybackManager { Events.trigger(self, 'playbackcancelled'); } - function onInterceptorRejection() { + function onInterceptorRejection(e) { cancelPlayback(); + + let displayErrorCode = 'ErrorDefault'; + + if (e instanceof Response) { + if (e.status >= 500) { + displayErrorCode = `PlaybackError.${MediaError.SERVER_ERROR}`; + } else if (e.status >= 400) { + displayErrorCode = `PlaybackError.${MediaError.NO_MEDIA_ERROR}`; + } + } + + showPlaybackInfoErrorMessage(self, displayErrorCode); + return Promise.reject(); } @@ -2789,7 +2849,7 @@ class PlaybackManager { } else { if (item.AlbumId != null) { return apiClient.getItem(apiClient.getCurrentUserId(), item.AlbumId).then(function(result) { - mediaSource.albumLUFS = result.LUFS; + mediaSource.albumNormalizationGain = result.NormalizationGain; return mediaSource; }); } @@ -3320,7 +3380,13 @@ class PlaybackManager { if (errorOccurred) { showPlaybackInfoErrorMessage(self, 'PlaybackError' + displayErrorCode); } else if (nextItem) { - self.nextTrack(); + const apiClient = ServerConnections.getApiClient(nextItem.item.ServerId); + + apiClient.getCurrentUser().then(function (user) { + if (user.Configuration.EnableNextEpisodeAutoPlay || nextMediaType !== MediaType.Video) { + self.nextTrack(); + } + }); } } diff --git a/src/components/playbackSettings/playbackSettings.js b/src/components/playbackSettings/playbackSettings.js index 254389a9f6..6717c66613 100644 --- a/src/components/playbackSettings/playbackSettings.js +++ b/src/components/playbackSettings/playbackSettings.js @@ -173,6 +173,8 @@ function loadForm(context, user, userSettings, systemInfo, apiClient) { context.querySelector('.chkPlayDefaultAudioTrack').checked = user.Configuration.PlayDefaultAudioTrack || false; context.querySelector('.chkPreferFmp4HlsContainer').checked = userSettings.preferFmp4HlsContainer(); + context.querySelector('.chkEnableDts').checked = appSettings.enableDts(); + context.querySelector('.chkEnableTrueHd').checked = appSettings.enableTrueHd(); context.querySelector('.chkEnableCinemaMode').checked = userSettings.enableCinemaMode(); context.querySelector('#selectAudioNormalization').value = userSettings.selectAudioNormalization(); context.querySelector('.chkEnableNextVideoOverlay').checked = userSettings.enableNextVideoInfoOverlay(); @@ -216,6 +218,9 @@ function saveUser(context, user, userSettingsInstance, apiClient) { appSettings.maxVideoWidth(context.querySelector('.selectMaxVideoWidth').value); appSettings.limitSupportedVideoResolution(context.querySelector('.chkLimitSupportedVideoResolution').checked); + appSettings.enableDts(context.querySelector('.chkEnableDts').checked); + appSettings.enableTrueHd(context.querySelector('.chkEnableTrueHd').checked); + setMaxBitrateFromField(context.querySelector('.selectVideoInNetworkQuality'), true, 'Video'); setMaxBitrateFromField(context.querySelector('.selectVideoInternetQuality'), false, 'Video'); setMaxBitrateFromField(context.querySelector('.selectMusicInternetQuality'), false, 'Audio'); diff --git a/src/components/playbackSettings/playbackSettings.template.html b/src/components/playbackSettings/playbackSettings.template.html index 6dc860260f..eb416687d7 100644 --- a/src/components/playbackSettings/playbackSettings.template.html +++ b/src/components/playbackSettings/playbackSettings.template.html @@ -159,6 +159,28 @@ +
+

+ ${HeaderVideoAdvanced} +

+ +
+ +
${EnableDtsHelp}
+
+ +
+ +
${EnableTrueHdHelp}
+
+
+ diff --git a/src/components/playlisteditor/playlisteditor.ts b/src/components/playlisteditor/playlisteditor.ts index 4335fa17ec..46100472c2 100644 --- a/src/components/playlisteditor/playlisteditor.ts +++ b/src/components/playlisteditor/playlisteditor.ts @@ -4,6 +4,7 @@ import { getItemsApi } from '@jellyfin/sdk/lib/utils/api/items-api'; import { getPlaylistsApi } from '@jellyfin/sdk/lib/utils/api/playlists-api'; import escapeHtml from 'escape-html'; +import toast from 'components/toast/toast'; import dom from 'scripts/dom'; import globalize from 'scripts/globalize'; import { currentSettings as userSettings } from 'scripts/settings/userSettings'; @@ -52,12 +53,14 @@ function onSubmit(this: HTMLElement, e: Event) { addToPlaylist(panel, playlistId) .catch(err => { console.error('[PlaylistEditor] Failed to add to playlist %s', playlistId, err); + toast(globalize.translate('PlaylistError.AddFailed')); }) .finally(loading.hide); } else { createPlaylist(panel) .catch(err => { console.error('[PlaylistEditor] Failed to create playlist', err); + toast(globalize.translate('PlaylistError.CreateFailed')); }) .finally(loading.hide); } @@ -73,13 +76,16 @@ function createPlaylist(dlg: DialogElement) { const apiClient = ServerConnections.getApiClient(currentServerId); const api = toApi(apiClient); - const itemIds = dlg.querySelector('.fldSelectedItemIds')?.value || ''; + const itemIds = dlg.querySelector('.fldSelectedItemIds')?.value || undefined; return getPlaylistsApi(api) .createPlaylist({ - name: dlg.querySelector('#txtNewPlaylistName')?.value, - ids: itemIds.split(','), - userId: apiClient.getCurrentUserId() + createPlaylistDto: { + Name: dlg.querySelector('#txtNewPlaylistName')?.value, + IsPublic: dlg.querySelector('#chkPlaylistPublic')?.checked, + Ids: itemIds?.split(','), + UserId: apiClient.getCurrentUserId() + } }) .then(result => { dlg.submitted = true; @@ -147,6 +153,32 @@ function populatePlaylists(editorOptions: PlaylistEditorOptions, panel: DialogEl recursive: true }) .then(({ data }) => { + return Promise.all((data.Items || []).map(item => { + const playlist = { + item, + permissions: undefined + }; + + if (!item.Id) return playlist; + + return getPlaylistsApi(api) + .getPlaylistUser({ + playlistId: item.Id, + userId: apiClient.getCurrentUserId() + }) + .then(({ data: permissions }) => ({ + ...playlist, + permissions + })) + .catch(err => { + // If a user doesn't have access, then the request will 404 and throw + console.info('[PlaylistEditor] Failed to fetch playlist permissions', err); + + return playlist; + }); + })); + }) + .then(playlists => { let html = ''; if ((editorOptions.enableAddToPlayQueue !== false && playbackManager.isPlaying()) || SyncPlay?.Manager.isSyncPlayEnabled()) { @@ -155,8 +187,10 @@ function populatePlaylists(editorOptions: PlaylistEditorOptions, panel: DialogEl html += ``; - html += data.Items?.map(i => { - return ``; + html += playlists.map(({ item, permissions }) => { + if (!permissions?.CanEdit) return ''; + + return ``; }); select.innerHTML = html; @@ -195,6 +229,17 @@ function getEditorHtml(items: string[]) { html += ``; html += ''; + html += ` +
+ +
+ ${globalize.translate('PlaylistPublicDescription')} +
+
`; + // newPlaylistInfo html += ''; diff --git a/src/components/router/appRouter.js b/src/components/router/appRouter.js index de6b3c6871..3b07a5571c 100644 --- a/src/components/router/appRouter.js +++ b/src/components/router/appRouter.js @@ -1,3 +1,4 @@ +import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; import { Action, createHashHistory } from 'history'; import { appHost } from '../apphost'; @@ -9,8 +10,11 @@ import loading from '../loading/loading'; import viewManager from '../viewManager/viewManager'; import ServerConnections from '../ServerConnections'; import alert from '../alert'; -import { ConnectionState } from '../../utils/jellyfin-apiclient/ConnectionState.ts'; -import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type'; + +import { queryClient } from 'utils/query/queryClient'; +import { getItemQuery } from 'hooks/useItem'; +import { toApi } from 'utils/jellyfin-apiclient/compat'; +import { ConnectionState } from 'utils/jellyfin-apiclient/ConnectionState.ts'; export const history = createHashHistory(); @@ -183,18 +187,26 @@ class AppRouter { showItem(item, serverId, options) { // TODO: Refactor this so it only gets items, not strings. - if (typeof (item) === 'string') { + if (typeof item === 'string') { const apiClient = serverId ? ServerConnections.getApiClient(serverId) : ServerConnections.currentApiClient(); - apiClient.getItem(apiClient.getCurrentUserId(), item).then((itemObject) => { - this.showItem(itemObject, options); - }); + const api = toApi(apiClient); + const userId = apiClient.getCurrentUserId(); + + queryClient + .fetchQuery(getItemQuery(api, userId, item)) + .then(itemObject => { + this.showItem(itemObject, options); + }) + .catch(err => { + console.error('[AppRouter] Failed to fetch item', err); + }); } else { if (arguments.length === 2) { options = arguments[1]; } const url = this.getRouteUrl(item, options); - this.show(url, { item }); + this.show(url); } } diff --git a/src/components/shortcuts.js b/src/components/shortcuts.js index cadb8cc20e..91f96f9d9b 100644 --- a/src/components/shortcuts.js +++ b/src/components/shortcuts.js @@ -2,6 +2,7 @@ * Module shortcuts. * @module components/shortcuts */ +import { getPlaylistsApi } from '@jellyfin/sdk/lib/utils/api/playlists-api'; import { playbackManager } from './playback/playbackmanager'; import inputManager from '../scripts/inputManager'; @@ -12,6 +13,7 @@ import recordingHelper from './recordingcreator/recordinghelper'; import ServerConnections from './ServerConnections'; import toast from './toast/toast'; import * as userSettings from '../scripts/settings/userSettings'; +import { toApi } from 'utils/jellyfin-apiclient/compat'; function playAllFromHere(card, serverId, queue) { const parent = card.parentNode; @@ -100,7 +102,7 @@ function notifyRefreshNeeded(childElement, itemsContainer) { } } -function showContextMenu(card, options) { +function showContextMenu(card, options = {}) { getItem(card).then(item => { const playlistId = card.getAttribute('data-playlistid'); const collectionId = card.getAttribute('data-collectionid'); @@ -110,28 +112,56 @@ function showContextMenu(card, options) { item.PlaylistItemId = elem ? elem.getAttribute('data-playlistitemid') : null; } - import('./itemContextMenu').then((itemContextMenu) => { - ServerConnections.getApiClient(item.ServerId).getCurrentUser().then(user => { - itemContextMenu.show(Object.assign({ - item: item, + const apiClient = ServerConnections.getApiClient(item.ServerId); + const api = toApi(apiClient); + + Promise.all([ + // Import the item menu component + import('./itemContextMenu'), + // Fetch the current user + apiClient.getCurrentUser(), + // Fetch playlist perms if item is a child of a playlist + playlistId ? + getPlaylistsApi(api) + .getPlaylistUser({ + playlistId, + userId: apiClient.getCurrentUserId() + }) + .then(({ data }) => data) + .catch(err => { + // If a user doesn't have access, then the request will 404 and throw + console.info('[Shortcuts] Failed to fetch playlist permissions', err); + return { CanEdit: false }; + }) : + // Not a playlist item + Promise.resolve({ CanEdit: false }) + ]) + .then(([ + itemContextMenu, + user, + playlistPerms + ]) => { + return itemContextMenu.show({ + item, play: true, queue: true, - playAllFromHere: !item.IsFolder, + playAllFromHere: item.Type === 'Season' || !item.IsFolder, queueAllFromHere: !item.IsFolder, - playlistId: playlistId, - collectionId: collectionId, - user: user - }, options || {})) - .then(result => { - if (result.command === 'playallfromhere' || result.command === 'queueallfromhere') { - executeAction(card, options.positionTo, result.command); - } else if (result.updated || result.deleted) { - notifyRefreshNeeded(card, options.itemsContainer); - } - }) - .catch(() => { /* no-op */ }); - }); - }); + playlistId, + canEditPlaylist: !!playlistPerms.CanEdit, + collectionId, + user, + ...options + }); + }) + .then(result => { + if (result.command === 'playallfromhere' || result.command === 'queueallfromhere') { + executeAction(card, options.positionTo, result.command); + } else if (result.updated || result.deleted) { + notifyRefreshNeeded(card, options.itemsContainer); + } + }) + .catch(() => { /* no-op */ }); }); } @@ -406,8 +436,8 @@ export function getShortcutAttributesHtml(item, serverId) { } export default { - on: on, - off: off, - onClick: onClick, - getShortcutAttributesHtml: getShortcutAttributesHtml + on, + off, + onClick, + getShortcutAttributesHtml }; diff --git a/src/components/themeMediaPlayer.js b/src/components/themeMediaPlayer.js index bad76612ce..87d86b7a4b 100644 --- a/src/components/themeMediaPlayer.js +++ b/src/components/themeMediaPlayer.js @@ -1,6 +1,14 @@ +import { MediaType } from '@jellyfin/sdk/lib/generated-client/models/media-type'; +import { getLibraryApi } from '@jellyfin/sdk/lib/utils/api/library-api'; + +import { getItemQuery } from 'hooks/useItem'; +import { currentSettings as userSettings } from 'scripts/settings/userSettings'; +import { ItemKind } from 'types/base/models/item-kind'; +import Events from 'utils/events.ts'; +import { toApi } from 'utils/jellyfin-apiclient/compat'; +import { queryClient } from 'utils/query/queryClient'; + import { playbackManager } from './playback/playbackmanager'; -import * as userSettings from '../scripts/settings/userSettings'; -import Events from '../utils/events.ts'; import ServerConnections from './ServerConnections'; let currentOwnerId; @@ -50,44 +58,61 @@ function stopIfPlaying() { } function enabled(mediaType) { - if (mediaType === 'Video') { + if (mediaType === MediaType.Video) { return userSettings.enableThemeVideos(); } return userSettings.enableThemeSongs(); } -const excludeTypes = ['CollectionFolder', 'UserView', 'Program', 'SeriesTimer', 'Person', 'TvChannel', 'Channel']; +const excludeTypes = [ + ItemKind.CollectionFolder, + ItemKind.UserView, + ItemKind.Person, + ItemKind.Program, + ItemKind.TvChannel, + ItemKind.Channel, + ItemKind.SeriesTimer +]; -function loadThemeMedia(item) { - if (item.CollectionType) { - stopIfPlaying(); - return; - } +async function loadThemeMedia(serverId, itemId) { + const apiClient = ServerConnections.getApiClient(serverId); + const api = toApi(apiClient); + const userId = apiClient.getCurrentUserId(); - if (excludeTypes.indexOf(item.Type) !== -1) { - stopIfPlaying(); - return; - } + try { + const item = await queryClient.fetchQuery(getItemQuery( + api, + userId, + itemId)); - const apiClient = ServerConnections.getApiClient(item.ServerId); - apiClient.getThemeMedia(apiClient.getCurrentUserId(), item.Id, true).then(function (themeMediaResult) { - const result = userSettings.enableThemeVideos() && themeMediaResult.ThemeVideosResult.Items.length ? themeMediaResult.ThemeVideosResult : themeMediaResult.ThemeSongsResult; - - const ownerId = result.OwnerId; - - if (ownerId !== currentOwnerId) { - playThemeMedia(result.Items, ownerId); + if (item.CollectionType) { + stopIfPlaying(); + return; } - }); + + if (excludeTypes.includes(item.Type)) { + stopIfPlaying(); + return; + } + + const { data: themeMedia } = await getLibraryApi(api) + .getThemeMedia({ userId, itemId: item.Id, inheritFromParent: true }); + + const result = userSettings.enableThemeVideos() && themeMedia.ThemeVideosResult?.Items?.length ? themeMedia.ThemeVideosResult : themeMedia.ThemeSongsResult; + + if (result.OwnerId !== currentOwnerId) { + playThemeMedia(result.Items, result.OwnerId); + } + } catch (err) { + console.error('[ThemeMediaPlayer] failed to load theme media', err); + } } -document.addEventListener('viewshow', function (e) { - const state = e.detail.state || {}; - const item = state.item; - - if (item?.ServerId) { - loadThemeMedia(item); +document.addEventListener('viewshow', e => { + const { serverId, id } = e.detail?.params || {}; + if (serverId && id) { + void loadThemeMedia(serverId, id); return; } @@ -100,7 +125,7 @@ document.addEventListener('viewshow', function (e) { } }, true); -Events.on(playbackManager, 'playbackstart', function (e, player) { +Events.on(playbackManager, 'playbackstart', (_e, player) => { const item = playbackManager.currentItem(player); // User played something manually if (currentThemeIds.indexOf(item.Id) == -1) { diff --git a/src/controllers/dashboard/general.html b/src/controllers/dashboard/general.html index 62f92d097c..c1cb04a9e1 100644 --- a/src/controllers/dashboard/general.html +++ b/src/controllers/dashboard/general.html @@ -83,7 +83,11 @@

${HeaderPerformance}

- + +
${LibraryScanFanoutConcurrencyHelp}
+
+
+
${LabelParallelImageEncodingLimitHelp}
diff --git a/src/controllers/dashboard/general.js b/src/controllers/dashboard/general.js index ee495259cf..d62cfbd16f 100644 --- a/src/controllers/dashboard/general.js +++ b/src/controllers/dashboard/general.js @@ -19,6 +19,7 @@ function loadPage(page, config, languageOptions, systemInfo) { $('#selectLocalizationLanguage', page).html(languageOptions.map(function (language) { return ''; })).val(config.UICulture); + page.querySelector('#txtLibraryScanFanoutConcurrency').value = config.LibraryScanFanoutConcurrency || ''; page.querySelector('#txtParallelImageEncodingLimit').value = config.ParallelImageEncodingLimit || ''; loading.hide(); @@ -35,6 +36,7 @@ function onSubmit() { config.MetadataPath = $('#txtMetadataPath', form).val(); config.MetadataNetworkPath = $('#txtMetadataNetworkPath', form).val(); config.QuickConnectAvailable = form.querySelector('#chkQuickConnectAvailable').checked; + config.LibraryScanFanoutConcurrency = parseInt(form.querySelector('#txtLibraryScanFanoutConcurrency').value || '0', 10); config.ParallelImageEncodingLimit = parseInt(form.querySelector('#txtParallelImageEncodingLimit').value || '0', 10); ApiClient.updateServerConfiguration(config).then(function() { diff --git a/src/controllers/itemDetails/index.html b/src/controllers/itemDetails/index.html index 935ac44ea4..cd5439a10f 100644 --- a/src/controllers/itemDetails/index.html +++ b/src/controllers/itemDetails/index.html @@ -175,14 +175,14 @@

${HeaderAdditionalParts}

-
+

-
+
@@ -194,21 +194,21 @@

-
+

${HeaderCastAndCrew}

-
+

${HeaderGuestCast}

-
+
@@ -220,28 +220,28 @@

${SpecialFeatures}

-
+

${MusicVideos}

-
+

${HeaderScenes}

-
+

${HeaderMoreLikeThis}

-
+
diff --git a/src/controllers/itemDetails/index.js b/src/controllers/itemDetails/index.js index f5cf971eba..71aebc57a4 100644 --- a/src/controllers/itemDetails/index.js +++ b/src/controllers/itemDetails/index.js @@ -1,3 +1,4 @@ +import { PersonKind } from '@jellyfin/sdk/lib/generated-client/models/person-kind'; import { intervalToDuration } from 'date-fns'; import DOMPurify from 'dompurify'; import escapeHtml from 'escape-html'; @@ -822,8 +823,18 @@ function setInitialCollapsibleState(page, item, apiClient, context, user) { page.querySelector('#specialsCollapsible').classList.add('hide'); } - renderCast(page, item); - renderGuestCast(page, item); + const cast = []; + const guestCast = []; + (item.People || []).forEach(p => { + if (p.Type === PersonKind.GuestStar) { + guestCast.push(p); + } else { + cast.push(p); + } + }); + + renderCast(page, item, cast); + renderGuestCast(page, item, guestCast); if (item.PartCount && item.PartCount > 1) { page.querySelector('#additionalPartsCollapsible').classList.remove('hide'); @@ -1803,11 +1814,7 @@ function renderSpecials(page, item, user) { }); } -function renderCast(page, item) { - const people = (item.People || []).filter(function (p) { - return p.Type === 'Actor'; - }); - +function renderCast(page, item, people) { if (!people.length) { page.querySelector('#castCollapsible').classList.add('hide'); return; @@ -1827,9 +1834,7 @@ function renderCast(page, item) { }); } -function renderGuestCast(page, item) { - const people = (item.People || []).filter(p => p.Type === 'GuestStar'); - +function renderGuestCast(page, item, people) { if (!people.length) { page.querySelector('#guestCastCollapsible').classList.add('hide'); return; diff --git a/src/elements/emby-itemscontainer/ItemsContainer.tsx b/src/elements/emby-itemscontainer/ItemsContainer.tsx index 779e718271..abde788a5c 100644 --- a/src/elements/emby-itemscontainer/ItemsContainer.tsx +++ b/src/elements/emby-itemscontainer/ItemsContainer.tsx @@ -1,6 +1,8 @@ -import type { - LibraryUpdateInfo +import { + MediaType, + type LibraryUpdateInfo } from '@jellyfin/sdk/lib/generated-client'; +import { ApiClient } from 'jellyfin-apiclient'; import React, { type FC, useCallback, useEffect, useRef } from 'react'; import classNames from 'classnames'; import Box from '@mui/material/Box'; @@ -20,6 +22,7 @@ import MultiSelect from 'components/multiSelect/multiSelect'; import loading from 'components/loading/loading'; import focusManager from 'components/focusManager'; import type { ParentId } from 'types/library'; +import type { PlaybackStopInfo } from 'types/playbackStopInfo'; function disableEvent(e: MouseEvent) { e.preventDefault(); @@ -221,7 +224,7 @@ const ItemsContainer: FC = ({ ); const onLibraryChanged = useCallback( - (_e: Event, apiClient, data: LibraryUpdateInfo) => { + (_e: Event, _apiClient: ApiClient, data: LibraryUpdateInfo) => { if (eventsToMonitor.includes('seriestimers') || eventsToMonitor.includes('timers')) { // yes this is an assumption return; @@ -253,12 +256,12 @@ const ItemsContainer: FC = ({ ); const onPlaybackStopped = useCallback( - (_e: Event, apiClient, stopInfo) => { + (_e: Event, stopInfo: PlaybackStopInfo) => { const state = stopInfo.state; if ( state.NowPlayingItem - && state.NowPlayingItem.MediaType === 'Video' + && state.NowPlayingItem.MediaType === MediaType.Video ) { if (eventsToMonitor.includes('videoplayback')) { notifyRefreshNeeded(true); @@ -266,8 +269,8 @@ const ItemsContainer: FC = ({ } } else if ( state.NowPlayingItem - && state.NowPlayingItem.MediaType === 'Audio' - && eventsToMonitor.includes('videoplayback') + && state.NowPlayingItem.MediaType === MediaType.Audio + && eventsToMonitor.includes('audioplayback') ) { notifyRefreshNeeded(true); return; diff --git a/src/elements/emby-scroller/emby-scroller.scss b/src/elements/emby-scroller/emby-scroller.scss index ad2fdf54cf..47d6bdd609 100644 --- a/src/elements/emby-scroller/emby-scroller.scss +++ b/src/elements/emby-scroller/emby-scroller.scss @@ -26,3 +26,13 @@ margin-left: 1.2em; } } + +.no-padding { + [dir="ltr"] & { + padding-left: 0; + } + + [dir="rtl"] & { + padding-right: 0; + } +} diff --git a/src/hooks/useFetchItems.ts b/src/hooks/useFetchItems.ts index 2d4f23f1a9..710b8863a6 100644 --- a/src/hooks/useFetchItems.ts +++ b/src/hooks/useFetchItems.ts @@ -28,36 +28,6 @@ import { LibraryViewSettings, ParentId } from 'types/library'; import { LibraryTab } from 'types/libraryTab'; import { Section, SectionApiMethod, SectionType } from 'types/sections'; -const fetchGetItem = async ( - currentApi: JellyfinApiContext, - parentId: ParentId, - options?: AxiosRequestConfig -) => { - const { api, user } = currentApi; - if (api && user?.Id && parentId) { - const response = await getUserLibraryApi(api).getItem( - { - userId: user.Id, - itemId: parentId - }, - { - signal: options?.signal - } - ); - return response.data; - } -}; - -export const useGetItem = (parentId: ParentId) => { - const currentApi = useApi(); - const isLivetv = parentId === 'livetv'; - return useQuery({ - queryKey: ['Item', parentId], - queryFn: ({ signal }) => fetchGetItem(currentApi, parentId, { signal }), - enabled: !!parentId && !isLivetv - }); -}; - const fetchGetItems = async ( currentApi: JellyfinApiContext, parametersOptions: ItemsApiGetItemsRequest, diff --git a/src/hooks/useItem.ts b/src/hooks/useItem.ts new file mode 100644 index 0000000000..ab72e1928f --- /dev/null +++ b/src/hooks/useItem.ts @@ -0,0 +1,41 @@ +import type { Api } from '@jellyfin/sdk/lib/api'; +import { getUserLibraryApi } from '@jellyfin/sdk/lib/utils/api/user-library-api'; +import { useQuery } from '@tanstack/react-query'; +import type { AxiosRequestConfig } from 'axios'; + +import { queryOptions } from 'utils/query/queryOptions'; + +import { useApi } from './useApi'; + +const fetchItem = async ( + api?: Api, + userId?: string, + itemId?: string, + options?: AxiosRequestConfig +) => { + if (!api) throw new Error('No API instance available'); + if (!itemId) throw new Error('No item ID provided'); + + const response = await getUserLibraryApi(api) + .getItem({ userId, itemId }, options); + return response.data; +}; + +export const getItemQuery = ( + api?: Api, + userId?: string, + itemId?: string +) => queryOptions({ + queryKey: [ 'User', userId, 'Items', itemId ], + queryFn: ({ signal }) => fetchItem(api, userId, itemId, { signal }), + staleTime: 1000, // 1 second + enabled: !!api && !!userId && !!itemId +}); + +export const useItem = ( + itemId?: string +) => { + const apiContext = useApi(); + const { api, user } = apiContext; + return useQuery(getItemQuery(api, user?.Id, itemId)); +}; diff --git a/src/hooks/useLegacyRouterSync.ts b/src/hooks/useLegacyRouterSync.ts index fe28df0905..c1af8fa310 100644 --- a/src/hooks/useLegacyRouterSync.ts +++ b/src/hooks/useLegacyRouterSync.ts @@ -2,8 +2,6 @@ import { Update } from 'history'; import { useLayoutEffect, useState } from 'react'; import type { History, Router } from '@remix-run/router'; -const normalizePath = (pathname: string) => pathname.replace(/^!/, ''); - interface UseLegacyRouterSyncProps { router: Router; history: History; @@ -20,8 +18,18 @@ export function useLegacyRouterSync({ router, history }: UseLegacyRouterSyncProp * implementation, so we need to remove the leading `!` from the pathname. React Router already removes the * hash for us. */ - if (update.location.pathname.startsWith('!')) { - history.replace(normalizePath(update.location.pathname), update.location.state); + if (update.location.pathname.startsWith('/!/')) { + history.replace( + { ...update.location, pathname: update.location.pathname.replace(/^\/!/, '') }, + update.location.state); + } else if (update.location.pathname.startsWith('/!')) { + history.replace( + { ...update.location, pathname: update.location.pathname.replace(/^\/!/, '/') }, + update.location.state); + } else if (update.location.pathname.startsWith('!')) { + history.replace( + { ...update.location, pathname: update.location.pathname.replace(/^!/, '') }, + update.location.state); } else if (!isSynced) { await router.navigate(update.location, { replace: true }); } diff --git a/src/index.html b/src/index.html index e406f11343..c445c30928 100644 --- a/src/index.html +++ b/src/index.html @@ -12,11 +12,6 @@ - - - - - @@ -116,6 +111,7 @@ z-index: 1; width: 0.8em; padding-left: env(safe-area-inset-left); + caret-color: transparent; } [dir="ltr"] .mainDrawerHandle { diff --git a/src/index.jsx b/src/index.jsx index 3d65bae640..362a62cfbe 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -193,21 +193,10 @@ async function onAppReady() { } } + // Apply custom CSS const apiClient = ServerConnections.currentApiClient(); if (apiClient) { - const updateStyle = (css) => { - let style = document.querySelector('#cssBranding'); - if (!style) { - // Inject the branding css as a dom element in body so it will take - // precedence over other stylesheets - style = document.createElement('style'); - style.id = 'cssBranding'; - document.body.appendChild(style); - } - style.textContent = css; - }; - - const style = fetch(apiClient.getUrl('Branding/Css')) + const brandingCss = fetch(apiClient.getUrl('Branding/Css')) .then(function(response) { if (!response.ok) { throw new Error(response.status + ' ' + response.statusText); @@ -219,41 +208,33 @@ async function onAppReady() { }); const handleStyleChange = async () => { - if (currentSettings.disableCustomCss()) { - updateStyle(''); - } else { - updateStyle(await style); + let style = document.querySelector('#cssBranding'); + if (!style) { + // Inject the branding css as a dom element in body so it will take + // precedence over other stylesheets + style = document.createElement('style'); + style.id = 'cssBranding'; + document.body.appendChild(style); } - const localCss = currentSettings.customCss(); - let localStyle = document.querySelector('#localCssBranding'); - if (localCss) { - if (!localStyle) { - // Inject the branding css as a dom element in body so it will take - // precedence over other stylesheets - localStyle = document.createElement('style'); - localStyle.id = 'localCssBranding'; - document.body.appendChild(localStyle); - } - localStyle.textContent = localCss; - } else if (localStyle) { - localStyle.textContent = ''; - } + const css = []; + // Only add branding CSS when enabled + if (!currentSettings.disableCustomCss()) css.push(await brandingCss); + // Always add user CSS + css.push(currentSettings.customCss()); + + style.textContent = css.join('\n'); }; - const handleUserChange = () => { - handleStyleChange(); - }; - - Events.on(ServerConnections, 'localusersignedin', handleUserChange); - Events.on(ServerConnections, 'localusersignedout', handleUserChange); + Events.on(ServerConnections, 'localusersignedin', handleStyleChange); + Events.on(ServerConnections, 'localusersignedout', handleStyleChange); Events.on(currentSettings, 'change', (e, prop) => { if (prop == 'disableCustomCss' || prop == 'customCss') { handleStyleChange(); } }); - style.then(updateStyle); + handleStyleChange(); } } diff --git a/src/plugins/htmlAudioPlayer/plugin.js b/src/plugins/htmlAudioPlayer/plugin.js index 1399003ad9..ee226ebcc2 100644 --- a/src/plugins/htmlAudioPlayer/plugin.js +++ b/src/plugins/htmlAudioPlayer/plugin.js @@ -113,18 +113,22 @@ class HtmlAudioPlayer { let val = options.url; console.debug('playing url: ' + val); import('../../scripts/settings/userSettings').then((userSettings) => { - if (userSettings.selectAudioNormalization() == 'TrackGain' && options.item.LUFS != null) { - const dbGain = -18 - options.item.LUFS; - self.gainNode.gain.value = Math.pow(10, (dbGain / 20)); - console.debug('[HtmlAudioPlayer] Using track gain'); - } else if (userSettings.selectAudioNormalization() == 'AlbumGain' && options.mediaSource.albumLUFS != null) { - const dbGain = -18 - options.mediaSource.albumLUFS; - self.gainNode.gain.value = Math.pow(10, (dbGain / 20)); - console.debug('[HtmlAudioPlayer] Using album gain'); + let normalizationGain; + if (userSettings.selectAudioNormalization() == 'TrackGain') { + normalizationGain = options.item.NormalizationGain + ?? options.mediaSource.albumNormalizationGain; + } else if (userSettings.selectAudioNormalization() == 'AlbumGain') { + normalizationGain = + options.mediaSource.albumNormalizationGain + ?? options.item.NormalizationGain; + } + + if (normalizationGain) { + self.gainNode.gain.value = Math.pow(10, normalizationGain / 20); } else { self.gainNode.gain.value = 1; } - console.debug('gain:' + self.gainNode.gain.value); + console.debug('gain: ' + self.gainNode.gain.value); }).catch((err) => { console.error('Failed to add/change gainNode', err); }); diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index 5f882a2383..f26e89cc92 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -1250,14 +1250,14 @@ export class HtmlVideoPlayer { */ renderSsaAss(videoElement, track, item) { const supportedFonts = ['application/vnd.ms-opentype', 'application/x-truetype-font', 'font/otf', 'font/ttf', 'font/woff', 'font/woff2']; - const avaliableFonts = []; + const availableFonts = []; const attachments = this._currentPlayOptions.mediaSource.MediaAttachments || []; const apiClient = ServerConnections.getApiClient(item); attachments.forEach(i => { // we only require font files and ignore embedded media attachments like covers as there are cases where ffmpeg fails to extract those if (supportedFonts.includes(i.MimeType)) { // embedded font url - avaliableFonts.push(apiClient.getUrl(i.DeliveryUrl)); + availableFonts.push(apiClient.getUrl(i.DeliveryUrl)); } }); const fallbackFontList = apiClient.getUrl('/FallbackFont/Fonts', { @@ -1268,7 +1268,7 @@ export class HtmlVideoPlayer { const options = { video: videoElement, subUrl: getTextTrackUrl(track, item), - fonts: avaliableFonts, + fonts: availableFonts, workerUrl: `${appRouter.baseUrl()}/libraries/subtitles-octopus-worker.js`, legacyWorkerUrl: `${appRouter.baseUrl()}/libraries/subtitles-octopus-worker-legacy.js`, onError() { @@ -1307,10 +1307,10 @@ export class HtmlVideoPlayer { if (config.EnableFallbackFont) { apiClient.getJSON(fallbackFontList).then((fontFiles = []) => { fontFiles.forEach(font => { - const fontUrl = apiClient.getUrl(`/FallbackFont/Fonts/${font.Name}`, { + const fontUrl = apiClient.getUrl(`/FallbackFont/Fonts/${encodeURIComponent(font.Name)}`, { api_key: apiClient.accessToken() }); - avaliableFonts.push(fontUrl); + availableFonts.push(fontUrl); }); this.#currentAssRenderer = new SubtitlesOctopus(options); }); diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index 33e07e4f0c..542b535f88 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -94,6 +94,25 @@ function supportsAc3(videoTestElement) { return videoTestElement.canPlayType('audio/mp4; codecs="ac-3"').replace(/no/, ''); } +/** + * Checks if the device supports DTS (DCA). + * @param {HTMLVideoElement} videoTestElement The video test element + * @returns {boolean|null} _true_ if the device supports DTS (DCA). _false_ if the device doesn't support DTS (DCA). _null_ if support status is unknown. + */ +function canPlayDts(videoTestElement) { + // DTS audio is not supported by Samsung TV 2018+ (Tizen 4.0+) and LG TV 2020-2022 (webOS 5.0, 6.0 and 22) models + if (browser.tizenVersion >= 4 || (browser.web0sVersion >= 5 && browser.web0sVersion < 23)) { + return false; + } + + if (videoTestElement.canPlayType('video/mp4; codecs="dts-"').replace(/no/, '') + || videoTestElement.canPlayType('video/mp4; codecs="dts+"').replace(/no/, '')) { + return true; + } + + return null; +} + function supportsEac3(videoTestElement) { if (browser.tizen || browser.web0s) { return true; @@ -121,6 +140,15 @@ function supportsAc3InHls(videoTestElement) { return false; } +function supportsMp3InHls(videoTestElement) { + if (videoTestElement.canPlayType) { + return videoTestElement.canPlayType('application/x-mpegurl; codecs="avc1.64001E, mp4a.40.34"').replace(/no/, '') + || videoTestElement.canPlayType('application/vnd.apple.mpegURL; codecs="avc1.64001E, mp4a.40.34"').replace(/no/, ''); + } + + return false; +} + function canPlayAudioFormat(format) { let typeString; @@ -460,6 +488,7 @@ export default function (options) { } const canPlayAacVideoAudio = videoTestElement.canPlayType('video/mp4; codecs="avc1.640029, mp4a.40.2"').replace(/no/, ''); + const canPlayMp3VideoAudioInHls = supportsMp3InHls(videoTestElement); const canPlayAc3VideoAudio = supportsAc3(videoTestElement); const canPlayEac3VideoAudio = supportsEac3(videoTestElement); const canPlayAc3VideoAudioInHls = supportsAc3InHls(videoTestElement); @@ -474,12 +503,15 @@ export default function (options) { if (supportsMp3VideoAudio) { videoAudioCodecs.push('mp3'); + } - // PS4 fails to load HLS with mp3 audio - if (!browser.ps4) { - hlsInTsVideoAudioCodecs.push('mp3'); - } + // Safari supports mp3 with HLS, but only in mpegts container, and the supportsMp3VideoAudio will return false. + if (browser.safari || (supportsMp3VideoAudio && !browser.ps4)) { + hlsInTsVideoAudioCodecs.push('mp3'); + } + // Most browsers won't support mp3 with HLS, so this is usually false, but just in case. + if (canPlayMp3VideoAudioInHls) { hlsInFmp4VideoAudioCodecs.push('mp3'); } @@ -515,14 +547,9 @@ export default function (options) { hlsInFmp4VideoAudioCodecs.push('mp2'); } - let supportsDts = options.supportsDts; + let supportsDts = appSettings.enableDts() || options.supportsDts; if (supportsDts == null) { - supportsDts = browser.tizen || browser.web0sVersion || videoTestElement.canPlayType('video/mp4; codecs="dts-"').replace(/no/, '') || videoTestElement.canPlayType('video/mp4; codecs="dts+"').replace(/no/, ''); - - // DTS audio is not supported by Samsung TV 2018+ (Tizen 4.0+) and LG TV 2020-2022 (webOS 5.0, 6.0 and 22) models - if (browser.tizenVersion >= 4 || (browser.web0sVersion >= 5 && browser.web0sVersion < 23)) { - supportsDts = false; - } + supportsDts = canPlayDts(videoTestElement); } if (supportsDts) { @@ -535,7 +562,7 @@ export default function (options) { videoAudioCodecs.push('pcm_s24le'); } - if (options.supportsTrueHd) { + if (appSettings.enableTrueHd() || options.supportsTrueHd) { videoAudioCodecs.push('truehd'); } diff --git a/src/scripts/playlistViewer.js b/src/scripts/playlistViewer.js index 16844ee8c8..512a15281b 100644 --- a/src/scripts/playlistViewer.js +++ b/src/scripts/playlistViewer.js @@ -1,48 +1,74 @@ -import listView from '../components/listview/listview'; +import { getPlaylistsApi } from '@jellyfin/sdk/lib/utils/api/playlists-api'; -function getFetchPlaylistItemsFn(itemId) { +import ServerConnections from 'components/ServerConnections'; +import listView from 'components/listview/listview'; +import { toApi } from 'utils/jellyfin-apiclient/compat'; + +function getFetchPlaylistItemsFn(apiClient, itemId) { return function () { const query = { Fields: 'PrimaryImageAspectRatio', EnableImageTypes: 'Primary,Backdrop,Banner,Thumb', - UserId: ApiClient.getCurrentUserId() + UserId: apiClient.getCurrentUserId() }; - return ApiClient.getJSON(ApiClient.getUrl(`Playlists/${itemId}/Items`, query)); + return apiClient.getJSON(apiClient.getUrl(`Playlists/${itemId}/Items`, query)); }; } -function getItemsHtmlFn(itemId) { +function getItemsHtmlFn(playlistId, isEditable = false) { return function (items) { return listView.getListViewHtml({ - items: items, + items, showIndex: false, - showRemoveFromPlaylist: true, playFromHere: true, action: 'playallfromhere', smallIcon: true, - dragHandle: true, - playlistId: itemId + dragHandle: isEditable, + playlistId }); }; } -function init(page, item) { +async function init(page, item) { + const apiClient = ServerConnections.getApiClient(item.ServerId); + const api = toApi(apiClient); + + let isEditable = false; + const { data } = await getPlaylistsApi(api) + .getPlaylistUser({ + playlistId: item.Id, + userId: apiClient.getCurrentUserId() + }) + .catch(err => { + // If a user doesn't have access, then the request will 404 and throw + console.info('[PlaylistViewer] Failed to fetch playlist permissions', err); + return { data: {} }; + }); + isEditable = !!data.CanEdit; + const elem = page.querySelector('#childrenContent .itemsContainer'); elem.classList.add('vertical-list'); elem.classList.remove('vertical-wrap'); - elem.enableDragReordering(true); - elem.fetchData = getFetchPlaylistItemsFn(item.Id); - elem.getItemsHtml = getItemsHtmlFn(item.Id); + elem.enableDragReordering(isEditable); + elem.fetchData = getFetchPlaylistItemsFn(apiClient, item.Id); + elem.getItemsHtml = getItemsHtmlFn(item.Id, isEditable); +} + +function refresh(page) { + page.querySelector('#childrenContent').classList.add('verticalSection-extrabottompadding'); + page.querySelector('#childrenContent .itemsContainer').refreshItems(); } function render(page, item) { if (!page.playlistInit) { page.playlistInit = true; - init(page, item); + init(page, item) + .finally(() => { + refresh(page); + }); + } else { + refresh(page); } - - page.querySelector('#childrenContent').classList.add('verticalSection-extrabottompadding'); - page.querySelector('#childrenContent .itemsContainer').refreshItems(); } const PlaylistViewer = { diff --git a/src/scripts/settings/appSettings.js b/src/scripts/settings/appSettings.js index 4d96c1eed6..83d4d6879c 100644 --- a/src/scripts/settings/appSettings.js +++ b/src/scripts/settings/appSettings.js @@ -132,6 +132,32 @@ class AppSettings { return toBoolean(this.get('limitSupportedVideoResolution'), false); } + /** + * Get or set 'Enable DTS' state. + * @param {boolean|undefined} val - Flag to enable 'Enable DTS' or undefined. + * @return {boolean} 'Enable DTS' state. + */ + enableDts(val) { + if (val !== undefined) { + return this.set('enableDts', val.toString()); + } + + return toBoolean(this.get('enableDts'), false); + } + + /** + * Get or set 'Enable TrueHD' state. + * @param {boolean|undefined} val - Flag to enable 'Enable TrueHD' or undefined. + * @return {boolean} 'Enable TrueHD' state. + */ + enableTrueHd(val) { + if (val !== undefined) { + return this.set('enableTrueHd', val.toString()); + } + + return toBoolean(this.get('enableTrueHd'), false); + } + set(name, value, userId) { const currentValue = this.get(name, userId); localStorage.setItem(this.#getKey(name, userId), value); diff --git a/src/strings/ar.json b/src/strings/ar.json index 96ef73e722..b8d9cabd13 100644 --- a/src/strings/ar.json +++ b/src/strings/ar.json @@ -197,7 +197,7 @@ "HeaderSelectTranscodingPathHelp": "تصفح أو أدخل المسار الذي ترغب أن يُستخدم لملفات التشفير البيني. يجب أن يكون هذا المجلد قابل للكتابة فيه.", "HeaderSendMessage": "أرسل رسالة", "HeaderServerSettings": "إعدادات الخادم", - "HeaderSetupLibrary": "ضبط مكتبة المحتوى الخاصة بك", + "HeaderSetupLibrary": "ضبط مكاتب المحتوى الخاصة بك", "HeaderSortBy": "ترتيب حسب", "HeaderSortOrder": "تسلسل الترتيب", "HeaderSpecialEpisodeInfo": "معلومات الحلقة الخاصة", @@ -255,7 +255,7 @@ "LabelCollection": "المجموعة", "LabelCommunityRating": "تقييم الجمهور", "LabelContentType": "نوع المحتوى", - "LabelCountry": "البلد", + "LabelCountry": "البلد/المنطقة", "LabelCurrentPassword": "كلمة السر الحالية", "LabelCustomCertificatePath": "مسار شهادة SSL المخصص", "LabelCustomCertificatePathHelp": "مسار ملف PKCS # 12 يحتوي على شهادة ومفتاح خاص لتمكين دعم TLS على مجال مخصص.", @@ -527,7 +527,7 @@ "MessagePasswordResetForUsers": "تم إعادة تعيين كلمات المرور للمستخدمين التاليين. يمكنهم الآن تسجيل الدخول باستخدام رموز الـPIN التي تم استخدامها لإعادة الضبط.", "MessagePleaseEnsureInternetMetadata": "الرجاء التأكد من أن إمكانية إنزال واصفات البيانات من الإنترنت ممكنة.", "MessagePluginConfigurationRequiresLocalAccess": "لضبط هذا البرنامج المساعد ، يرجى تسجيل الدخول إلى الخادم المحلي الخاص بك مباشرة.", - "MessagePluginInstallDisclaimer": "تحذير: تنصيب الملحقات التي بناها أعضاء مجتمع Jellyfin هي طريقة رائعة لتحسين متعة استخدام Jellyfin عن طريق أضافة مزايا وخدمات الجديدة. ولكن تنصيب ملحقات من مصادر ثالثة تحمل بعظ الخطورة.\nقبل تثبيت الملحقات، نرجو أخذ العلم بالآثار التي قد تلحقها بخادم Jellyfin الخاص بك، مثل أوقات أطولة لتمشيط مكتبتك، والعمليات الخلفية الإضافية وتقليل استقرار نظامك.", + "MessagePluginInstallDisclaimer": "تحذير: تنصيب مكونات إضافية من مصادر طرف ثالث تحمل بعض المخاطر. قد تتضمن بعض البرمجيات الضارة، وقد تتغير في أي وقت. فقط قم بتنصيب المكونات الإضافية من مصدر تثق به، يرجى أخذ العلم بالآثار المحتملة التي قد تلحقها، مثل أوقات أطول لتمشيط مكتبتك، والعمليات الخلفية الإضافية.", "MessageReenableUser": "أنظر أدناه لإعادة التفعيل", "MessageTheFollowingLocationWillBeRemovedFromLibrary": "مكان الوسائط التالي سيزال من مكتبة Jellyfin الخاصة بك", "MessageUnableToConnectToServer": "لم نستطع الاتصال إلى الخادم المختار في الوقت الحالي. الرجاء التأكد من أنه يعمل ثم المحاولة مرة أخرى.", @@ -1085,7 +1085,7 @@ "Record": "سجل", "RecentlyWatched": "شاهدت مؤخرا", "Rate": "معدل", - "QuickConnectAuthorizeSuccess": "تمت الموافقة على الطلب", + "QuickConnectAuthorizeSuccess": "تمت المصادقة على الجهاز بنجاح!", "QuickConnectAuthorizeCode": "أدخل الرمز {0} لتسجيل الدخول", "QuickConnectActivationSuccessful": "تم التفعيل بنجاح", "Quality": "الجودة", @@ -1553,7 +1553,7 @@ "LabelColorPrimaries": "الألوان الأساسية", "HeaderSyncPlayPlaybackSettings": "التشغيل", "HeaderNewRepository": "مستودع جديد", - "DirectPlayHelp": "الملف المصدر متوافق تمامًا مع هذا العميل ، وتستقبل الجلسة الملف بدون تعديلات.", + "DirectPlayHelp": "الملف المصدر متوافق تمامًا مع هذا العميل والجلسة تستقبل الملف بدون تعديلات.", "LabelDashboardTheme": "قالب لوحة تحكم الخادم", "LabelTonemappingParamHelp": "ضبط خوارزمية تعيين النغمة.‌ القيم الموصى بها والافتراضية هي NaN. اتركه فارغًا بشكل عام.", "LabelTonemappingParam": "معلمة تعيين النغمة", @@ -1564,7 +1564,7 @@ "LabelAutomaticallyAddToCollection": "إضافة إلى المجموعة تلقائيا", "Console": "وحدة التحكم", "Casual": "غير رسمي", - "AllowTonemappingHelp": "يمكن أن يؤدي تعيين النغمة إلى تحويل النطاق الديناميكي لمقاطع الفيديو من HDR إلى SDR مع الحفاظ على تفاصيل الصورة والألوان. هذه بينات مهمة جدًا لتمثيل المشهد الأصلي بشكل وفي للمقطع ألأصلي. حاليًا يعمل هذا ألاعداد فقط مع مقاطع فيديو HDR10 أو HLG. يتطلب هذا ألأعداد وقت تشغيل OpenCL أو CUDA.", + "AllowTonemappingHelp": "يمكن أن يؤدي تعيين النغمة إلى تحويل النطاق الديناميكي لمقاطع الفيديو من HDR إلى SDR مع الحفاظ على تفاصيل الصورة والألوان. هذه بينات مهمة جدًا لتمثيل المشهد الأصلي بشكل وفي للمقطع ألأصلي. حاليًا يعمل هذا ألاعداد فقط مع مقاطع فيديو HDR10 أو HLG. يتطلب هذا ألأعداد وقت تشغيل GPGPU.", "RefFramesNotSupported": "الإطارات المرجعية غير مدعومة", "InterlacedVideoNotSupported": "الفيديو المتشابك غير مدعوم", "AnamorphicVideoNotSupported": "لا يتم دعم الفيديو ذي الصورة المشوهة", @@ -1663,9 +1663,9 @@ "MediaInfoVideoRangeType": "نوع نطاق الفيديو", "LabelVideoRangeType": "نوع نطاق الفيديو", "VideoRangeTypeNotSupported": "نوع نطاق الفيديو غير مدعوم", - "LabelVppTonemappingContrastHelp": "تطبيق كسب التباين في تعيين نغمة VPP. القيم الموصى بها والافتراضية هي 1.2 و 1.", + "LabelVppTonemappingContrastHelp": "تطبيق كسب التباين في تعيين نغمة VPP. القيم الموصى بها والافتراضية هي 1.", "LabelVppTonemappingContrast": "كسب تباين تعيين نغمة VPP", - "LabelVppTonemappingBrightnessHelp": "تطبيق كسب السطوع في تعيين نغمة VPP. كل من القيم الموصى بها والافتراضية هي 0.", + "LabelVppTonemappingBrightnessHelp": "تطبيق كسب السطوع في تعيين نغمة VPP. القيم الموصى بها والافتراضية هي 0.", "LabelVppTonemappingBrightness": "كسب سطوع رسم الخرائط VPP نغمة", "ScreenResolution": "تعيين مسار الترجمة على أساس البند السابق", "RememberSubtitleSelectionsHelp": "تعيين مسار الترجمة على أساس البند السابق.", @@ -1715,14 +1715,60 @@ "LogLevel.None": "لا شيئ", "MenuOpen": "أفتح القائمة", "AllowSegmentDeletion": "ألغاء القسم", - "AllowSegmentDeletionHelp": "ألغي الأقسام القديمة بعد أن يتم أرسالها للعميل. هذا يساهم بمنع أن يتم تخزين الملف ألذي تم أعادة ترميزه. ستعمل هذه الميزة فقط عندما يتم كبح الترميز. قم بأيقاف هذا الأعداد في حال واجهت مشاكل بتشغيل ألصوت أو ألفديو.", + "AllowSegmentDeletionHelp": "ألغي الأقسام القديمة بعد أن يتم تحميلها من قبل العميل. هذا يساهم بمنع أن يتم تخزين الملف ألذي تم أعادة ترميزه بالكامل. قم بأيقاف هذا الأعداد في حال واجهت مشاكل بتشغيل الصوت أو الفيديو.", "LabelThrottleDelaySeconds": "أكبح بعد", "LabelThrottleDelaySecondsHelp": "ألزمن بالثواني الذي سيتم بعده كبح أعادة الترميز. يجب أن يكون الزمن طويلاً بكفاية ليحافظ العميل على مخزون صحي. يجب أن يكون كفح أعادة الترميز مفعلاً ليعمل هذا ألاعاداد.", "LabelSegmentKeepSeconds": "الممدة للأحتفاظ على الشرائح", "LabelEnableAudioVbrHelp": "معدل البِت المتغير ينتج على جودة أفضل مقارنة بمعدل البت المتوسط، ولكن في بعض الحالات النادرة قد يسبب مشاكل في التخزين المؤقت والتوافق.", - "LabelSegmentKeepSecondsHelp": "الزمن بالثواني الذي يجب الاحتفاظ به للشرائح قبل أن يتم الكتابة فوقها. يجب أن يكون أكبر من \"بعد الخنق\". يعمل هذا ألأعداد فقط إذا كان حذف الشرائح مفعلًا.", + "LabelSegmentKeepSecondsHelp": "الزمن بالثواني الذي يجب الاحتفاظ به للشرائح بعد أن يتم تحميلها من قبل العميل. يعمل هذا ألأعداد فقط إذا كان حذف الشرائح مفعلًا.", "AiTranslated": "مترجمة من قبل ذكاء اسطناعي", "SelectAudioNormalizationHelp": "كسب الالبوم-تعديل الصوت لكل مسار لكي يعملون بنفس مستوى- كسب الالبوم- تعديل مستوى الصوت لكل المسارات في البوم واحد مع ابقاء على النطاق الديناميكي للألبوم.", "ButtonEditUser": "تعديل مستخدم", - "AllowSubtitleManagement": "اسمح لهذا المستخدم تعديل الترجمات" + "AllowSubtitleManagement": "اسمح لهذا المستخدم تعديل الترجمات", + "HeaderDeleteSeries": "حذف مسلسل", + "DeleteEntireSeries": "حذف {0} حلقات", + "DeleteSeries": "حذف المسلسل", + "HeaderEpisodesStatus": "حالة الحلقات", + "LabelSelectAudioNormalization": "تطبيع الصوت", + "DeleteEpisode": "حذف الحلقة", + "EnableLibrary": "إتاحة المكتبة", + "LabelSyncPlayNoGroups": "لا توجد مجموعات متاحة", + "DeleteName": "حذف {0}", + "LabelServerVersion": "نسخة الخادم", + "LabelWebVersion": "نسخة الويب", + "LabelBuildVersion": "نسخة الإصدار", + "SavePassword": "حفظ كلمة المرور", + "SubtitleBlack": "أسود", + "SubtitleWhite": "أبيض", + "UserMenu": "قائمة المستخدم", + "LabelScanBehavior": "سلوك المسح", + "PriorityHigh": "عالي", + "PriorityBelowNormal": "تحت الطبيعي", + "PriorityNormal": "طبيعي", + "PriorityAboveNormal": "فوق الطبيعي", + "LabelProcessPriority": "أولوية المعالجة", + "PriorityIdle": "خامل", + "PlaybackError.PLAYER_ERROR": "التشغيل فشل لخطأ في مشغل الوسائط.", + "Studio": "الأستيديو", + "SubtitleYellow": "أصفر", + "PlaybackError.NETWORK_ERROR": "التشغيل فشل لخطأ في الشبكة.", + "UnknownError": "حدث خطأ غير معلوم.", + "Select": "اختيار", + "SubtitleRed": "أحمر", + "PasswordRequiredForAdmin": "يجب توفر كلمة مرور لحسابات المسؤول.", + "SecondarySubtitles": "الترجمات الثانوية", + "PlaybackError.NO_MEDIA_ERROR": "غير قايل لإيجاد مصدر موثق للوسائط لللتشغيل.", + "PlaybackError.SERVER_ERROR": "التشغيل فشل لخطأ في الخادم.", + "PlaybackError.MEDIA_NOT_SUPPORTED": "التشغيل فشل لأن الوسائط غير مدعومة من هذا العميل.", + "PlaybackError.NotAllowed": "تشغيل هذه الوسائط غير مسموح.", + "LabelJpegQuality": "جودة JPEG", + "SubtitleGreen": "أخضر", + "SearchResultsEmpty": "نأسف! لا يوجد نتاج لـ \"{0}\"", + "SubtitleLightGray": "رمادي فاتح", + "Short": "قصير", + "SubtitleGray": "رمادي", + "SubtitleBlue": "أزرق", + "AllowContentWithTagsHelp": "اعرض الوسائط التي تحتوي على الأقل واحدة من الاصناف المحددة.", + "AirPlay": "ايربلاي", + "Author": "الكاتب" } diff --git a/src/strings/ca.json b/src/strings/ca.json index b5ef25cc8c..7f3d8cc35a 100644 --- a/src/strings/ca.json +++ b/src/strings/ca.json @@ -749,7 +749,7 @@ "DashboardArchitecture": "Arquitectura: {0}", "DailyAt": "Diariament a {0}", "ClearQueue": "Esborra la cua", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "ButtonPlayer": "Reproductor", "ButtonCast": "Transmetre a dispositiu", "ApiKeysCaption": "Llista de les claus API activades actualment", @@ -864,7 +864,7 @@ "HeaderSelectFallbackFontPath": "Seleccioneu la ruta de la carpeta de fonts", "Yesterday": "Ahir", "Yes": "Si", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "XmlTvPathHelp": "Una ruta a un arxiu XMLTV. Jellyfin llegirà aquesta imatge i comprovar periòdicament si hi ha actualitzacions. Vostè és responsable de crear i actualitzar l'arxiu.", "XmlDocumentAttributeListHelp": "Aquests atributs s'apliquen a l'element arrel de cada resposta XML.", "Writers": "Escriptors", @@ -1335,7 +1335,7 @@ "LabelAudioChannels": "Canals d'àudio", "LabelAudioBitrate": "Taxa de bits d'àudio", "LabelAudioBitDepth": "Profunditat de bits d'àudio", - "LabelAppNameExample": "Exemple: Sickbeard, Sonarr", + "LabelAppNameExample": "Un nom llegible per persones per identificar les claus de l'API. Aquesta configuració no afectarà la funcionalitat.", "LabelAppName": "Nom de l'aplicació", "LabelAllowHWTranscoding": "Permetre la transcodificació de maquinari", "LabelAllowedRemoteAddressesMode": "La manera de filtre d'adreces IP remota", @@ -1863,5 +1863,25 @@ "DeleteLyrics": "Esborrar lletres", "HeaderNoLyrics": "No s'ha trobat cap lletra", "Lyrics": "Lletres", - "ViewLyrics": "Veure lletres" + "ViewLyrics": "Veure lletres", + "SavePassword": "Desar contrasenya", + "EnableDts": "Habilitar DTS (DCA)", + "PlaylistError.AddFailed": "S'ha produït un error en afegir a la llista de reproducció", + "PlaylistError.CreateFailed": "S'ha produït un error en crear la llista de reproducció", + "HeaderVideoAdvanced": "Vídeo Avançat", + "Author": "Autor", + "Colorist": "Colorista", + "CoverArtist": "Artista de portada", + "Creator": "Creador", + "Editor": "Editor", + "EnableDtsHelp": "Habiliteu-lo només si el vostre dispositiu és compatible amb DTS o està connectat a un receptor d'àudio compatible, en cas contrari, pot provocar un error de reproducció.", + "EnableTrueHd": "Habilitar TrueHD", + "EnableTrueHdHelp": "Habiliteu-lo només si el vostre dispositiu és compatible amb TrueHD o està connectat a un receptor d'àudio compatible, en cas contrari, pot provocar un error de reproducció.", + "Illustrator": "Il·lustrador", + "Translator": "Traductor", + "PlaylistPublic": "Permetre accés públic", + "PlaylistPublicDescription": "Permetre que qualsevol usuari registrat vegi aquesta llista de reproducció.", + "HeaderLyricDownloads": "Descàrregues de lletres", + "SaveLyricsIntoMediaFolders": "Desa la lletra a les carpetes multimèdia", + "SaveLyricsIntoMediaFoldersHelp": "Emmagatzemar les lletres al costat dels fitxers d'àudio permetrà gestionar-les més fàcilment." } diff --git a/src/strings/cs.json b/src/strings/cs.json index 7cf4c497cd..72778deb57 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -303,7 +303,7 @@ "HeaderSendMessage": "Poslat zprávu", "HeaderSeriesOptions": "Nastavení seriálu", "HeaderServerSettings": "Nastavení serveru", - "HeaderSetupLibrary": "Nastavení Vašich knihoven médií", + "HeaderSetupLibrary": "Nastavit knihovny médií", "HeaderSortBy": "Třídit dle", "HeaderSortOrder": "Pořadí třídění", "HeaderSpecialEpisodeInfo": "Infromace o speciální epizodě", @@ -362,7 +362,7 @@ "LabelAlbumArtists": "Alba umělce", "LabelAllowHWTranscoding": "Povolit hardwarové překódování", "LabelAppName": "Název aplikace", - "LabelAppNameExample": "Příklad: Sickbeard, Sonarr", + "LabelAppNameExample": "Čitelný název pro identifikaci klíčů k API. Toto nastavení nemá vliv na funkčnost.", "LabelArtists": "Umělci", "LabelArtistsHelp": "Více interpretů se odděluje pomocí středníku.", "LabelAudioLanguagePreference": "Preferovaný jazyk zvuku", @@ -1267,7 +1267,7 @@ "PathNotFound": "Cesta nebyla nalezena. Zkontrolujte, zda je platná a zkuste to znovu.", "WeeklyAt": "V {0} v {1}", "LastSeen": "Naposledy zobrazené {0}", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "LabelLibraryPageSizeHelp": "Počet položek k zobrazení na stránce knihovny. Nastavte na 0 pro vypnutí stránkování.", "LabelLibraryPageSize": "Velikost stránky knihovny", "LabelDeinterlaceMethod": "Metoda odstranění prokládání", @@ -1371,7 +1371,7 @@ "LabelIconMaxResHelp": "Maximální rozlišení ikon daných vlastností 'upnp:icon'.", "LabelAlbumArtMaxResHelp": "Maximální rozlišení obrázku v souboru dané vlastností 'upnp:albumArtURI'.", "Other": "Ostatní", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "UseDoubleRateDeinterlacingHelp": "Toto nastavení při odstranění prokládání zdvojnásobuje snímkovou frekvenci, aby výsledné video vypadalo stejně plynule, jako při přehrávání prokládaného obsahu v televizi.", "UseDoubleRateDeinterlacing": "Zdvojnásobit snímkovou frekvenci při odstranění prokládání", "LabelTonemappingParamHelp": "Pro ladění algoritmu mapování tónů. Doporučená a výchozí hodnota je NaN. Obecně je pole ponecháváno prázdné.", @@ -1719,7 +1719,7 @@ "Short": "Krátký film", "HeaderPerformance": "Výkon", "LabelParallelImageEncodingLimit": "Počet paralelních kódování obrázků", - "LabelParallelImageEncodingLimitHelp": "Maximální počet kódování obrázků, které mohou běžet zároveň. Nastavením na 0 bude limit nastaven dle parametrů systému.", + "LabelParallelImageEncodingLimitHelp": "Maximální počet kódování obrázků, které mohou běžet zároveň. Nastavením na 0 bude limit nastaven dle počtu jader CPU.", "LabelEnableAudioVbr": "Povolit kódování zvuku VBR", "LabelEnableAudioVbrHelp": "Proměnlivý bitový tok (VBR) nabízí lepší poměr mezi kvalitou a průměrným bitovým tokem, ale někdy může způsobit dodatečné načítání či problémy s kompatibilitou.", "Select": "Vybrat", @@ -1867,5 +1867,30 @@ "HeaderDeleteLyrics": "Odstranit texty písní", "HeaderNoLyrics": "Žádné texty písní nebyly nalezeny", "Lyrics": "Texty písní", - "ViewLyrics": "Zobrazit texty písní" + "ViewLyrics": "Zobrazit texty písní", + "SavePassword": "Uložit heslo", + "PlaylistError.AddFailed": "Přidání do seznamu skladeb se nezdařilo", + "PlaylistError.CreateFailed": "Tvorba seznamu skladeb se nezdařila", + "EnableDts": "Povolit DTS (DCA)", + "EnableDtsHelp": "Povolte pouze pokud zařízení podporuje DTS nebo je připojeno ke kompatibilnímu AV receiveru, jinak by mohlo dojít k potížím s přehráváním.", + "EnableTrueHd": "Povolit TrueHD", + "EnableTrueHdHelp": "Povolte pouze pokud zařízení podporuje TrueHD nebo je připojeno ke kompatibilnímu AV receiveru, jinak by mohlo dojít k potížím s přehráváním.", + "HeaderVideoAdvanced": "Pokročilé video", + "PlaylistPublic": "Povolit veřejný přístup", + "PlaylistPublicDescription": "Tento seznam skladeb bude možné zobrazit i nepřihlášeným uživatelům.", + "HeaderLyricDownloads": "Stažení textů písní", + "SaveLyricsIntoMediaFolders": "Uložit texty písní do složek s médii", + "SaveLyricsIntoMediaFoldersHelp": "Uložení textů písní spolu se zvukovými souboru je snazší pro správu.", + "Author": "Autor", + "Colorist": "Kolorista", + "CoverArtist": "Obálka", + "Creator": "Tvůrce", + "Editor": "Editor", + "Illustrator": "Ilustrátor", + "Inker": "Inker", + "Letterer": "Lettrista", + "Penciller": "Výtvarník", + "Translator": "Překladatel", + "LibraryScanFanoutConcurrencyHelp": "Maximální počet souběžných úloh skenování knihovny. Nastavením na 0 bude počet dán počtem jader CPU. UPOZORNĚNÍ: Příliš vyskoý počet může způsobit problémy se síťovými souborými systémy. V takovém případě počet snižte.", + "LibraryScanFanoutConcurrency": "Maximální počet souběžných skenování knihovny" } diff --git a/src/strings/de.json b/src/strings/de.json index 055fb5c8cb..1d0a55c36b 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -1366,7 +1366,7 @@ "Poster": "Poster", "Photo": "Foto", "Other": "Sonstiges", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "UseDoubleRateDeinterlacingHelp": "Diese Einstellung verwendet die Halbbildrate beim Deinterlacing, oft auch als Bob-Deinterlacing bezeichnet. Dabei wird die Bildrate des Videos verdoppelt, um eine vollständige Bewegung wie beim Betrachten eines Interlaced-Video auf einem Fernseher zu erzielen.", "UseDoubleRateDeinterlacing": "Verdoppelung der Bildfrequenz beim Deinterlacing", "LabelIconMaxResHelp": "Maximale Auflösung der Icons, die über die Eigenschaft 'upnp:icon' bereitgestellt wird.", @@ -1867,5 +1867,6 @@ "ErrorDeletingLyrics": "Es trat ein Fehler beim Löschen der Songtexte vom Server auf. Bitte stelle sicher, dass Jellyfin die notwendigen Zugriffsrechte besitzt.", "HeaderDeleteLyrics": "Songtexte löschen", "HeaderNoLyrics": "Keine Songtexte gefunden", - "ViewLyrics": "Songtexte ansehen" + "ViewLyrics": "Songtexte ansehen", + "Author": "Autor" } diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index 30b7b4bc2b..fc8d253ed2 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -1196,7 +1196,7 @@ "HeaderSpecialEpisodeInfo": "Special Episode Info", "HeaderSortOrder": "Sort Order", "HeaderSortBy": "Sort By", - "HeaderSetupLibrary": "Setup your media libraries", + "HeaderSetupLibrary": "Set up your media libraries", "HeaderServerSettings": "Server Settings", "HeaderSeriesStatus": "Programmes Status", "HeaderSeriesOptions": "Programmes Options", @@ -1249,7 +1249,7 @@ "NoCreatedLibraries": "Seems like you haven't created any libraries yet. {0}Would you like to create one now?{1}", "AskAdminToCreateLibrary": "Ask an administrator to create a library.", "PlaybackErrorNoCompatibleStream": "This client isn't compatible with the media and the server isn't sending a compatible media format.", - "AllowFfmpegThrottlingHelp": "When a transcode or remux gets far enough ahead from the current playback position, pause the process so it will consume less resources. This is most useful when watching without seeking often. Turn this off if you experience playback issues.", + "AllowFfmpegThrottlingHelp": "When a transcode or remux gets far enough ahead from the current playback position, pause the process so it will consume fewer resources. This is most useful when watching without seeking often. Turn this off if you experience playback issues.", "AllowFfmpegThrottling": "Throttle Transcodes", "OnApplicationStartup": "On application startup", "EveryXHours": "Every {0} hours", @@ -1860,5 +1860,13 @@ "PlaybackError.SERVER_ERROR": "Playback failed due to a server error.", "PlaybackError.NotAllowed": "Playback of this media is not allowed.", "PlaybackError.RateLimitExceeded": "This media cannot be played at this time due to rate limits.", - "Lyric": "Lyric" + "Lyric": "Lyric", + "SavePassword": "Save Password", + "ViewLyrics": "View lyrics", + "ConfirmDeleteLyrics": "Deleting these lyrics will delete them from both the file system and your media library. Are you sure you wish to continue?", + "DeleteLyrics": "Delete lyrics", + "ErrorDeletingLyrics": "There was an error deleting the lyrics from the server. Please check that Jellyfin has write access to the media folder and try again.", + "HeaderDeleteLyrics": "Delete Lyrics", + "HeaderNoLyrics": "No lyrics found", + "Lyrics": "Lyrics" } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index 3ff8c973ee..f4ecc81c35 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -27,7 +27,7 @@ "AllowContentWithTagsHelp": "Only show media with at least one of the specified tags.", "AllowSubtitleManagement": "Allow this user to edit subtitles", "AllowFfmpegThrottling": "Throttle Transcodes", - "AllowFfmpegThrottlingHelp": "When a transcode or remux gets far enough ahead from the current playback position, pause the process so it will consume less resources. This is most useful when watching without seeking often. Turn this off if you experience playback issues.", + "AllowFfmpegThrottlingHelp": "When a transcode or remux gets far enough ahead from the current playback position, pause the process so it will consume fewer resources. This is most useful when watching without seeking often. Turn this off if you experience playback issues.", "AllowSegmentDeletion": "Delete segments", "AllowSegmentDeletionHelp": "Delete old segments after they have been downloaded by the client. This prevents having to store the entire transcoded file on disk. Turn this off if you experience playback issues.", "LabelThrottleDelaySeconds": "Throttle after", @@ -57,6 +57,7 @@ "AsManyAsPossible": "As many as possible", "AspectRatio": "Aspect Ratio", "Audio": "Audio", + "Author": "Author", "Authorize": "Authorize", "AuthProviderHelp": "Select an authentication provider to be used to authenticate this user's password.", "Auto": "Auto", @@ -131,7 +132,7 @@ "ButtonUninstall": "Uninstall", "ButtonUseQuickConnect": "Use Quick Connect", "ButtonWebsite": "Website", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "CancelRecording": "Cancel recording", "CancelSeries": "Cancel series", "Casual": "Casual", @@ -151,6 +152,7 @@ "ClearQueue": "Clear queue", "ClientSettings": "Client Settings", "Collections": "Collections", + "Colorist": "Colorist", "ColorPrimaries": "Color primaries", "ColorSpace": "Color space", "ColorTransfer": "Color transfer", @@ -174,6 +176,8 @@ "CopyFailed": "Could not copy", "CopyStreamURL": "Copy Stream URL", "CopyStreamURLSuccess": "URL copied successfully.", + "CoverArtist": "Cover artist", + "Creator": "Creator", "CriticRating": "Critics rating", "Cursive": "Cursive", "DailyAt": "Daily at {0}", @@ -232,6 +236,7 @@ "DrmChannelsNotImported": "Channels with DRM will not be imported.", "DropShadow": "Drop Shadow", "Edit": "Edit", + "Editor": "Editor", "EditImages": "Edit images", "EditMetadata": "Edit metadata", "EditSubtitles": "Edit subtitles", @@ -246,6 +251,8 @@ "EnableDetailsBanner": "Details Banner", "EnableDetailsBannerHelp": "Display a banner image at the top of the item details page.", "EnableDisplayMirroring": "Display mirroring", + "EnableDts": "Enable DTS (DCA)", + "EnableDtsHelp": "Only enable if your device supports DTS or is connected to a compatible audio receiver, otherwise it may cause playback failure.", "EnableExternalVideoPlayers": "External video players", "EnableExternalVideoPlayersHelp": "An external player menu will be shown when starting video playback.", "EnableFasterAnimations": "Faster animations", @@ -267,6 +274,8 @@ "EnableThemeSongsHelp": "Play the theme songs in background while browsing the library.", "EnableThemeVideosHelp": "Play theme videos in the background while browsing the library.", "EnableTonemapping": "Enable Tone mapping", + "EnableTrueHd": "Enable TrueHD", + "EnableTrueHdHelp": "Only enable if your device supports TrueHD or is connected to a compatible audio receiver, otherwise it may cause playback failure.", "EncoderPresetHelp": "Pick a faster value to improve performance, or a slower value to improve quality.", "Ended": "Ended", "EndsAtValue": "Ends at {0}", @@ -417,6 +426,7 @@ "HeaderLibrarySettings": "Library Settings", "HeaderLiveTvTunerSetup": "Live TV Tuner Setup", "HeaderLoginFailure": "Login Failure", + "HeaderLyricDownloads": "Lyric Downloads", "HeaderMedia": "Media", "HeaderMediaFolders": "Media Folders", "HeaderMetadataSettings": "Metadata Settings", @@ -474,7 +484,7 @@ "HeaderSeriesOptions": "Series Options", "HeaderSeriesStatus": "Series Status", "HeaderServerAddressSettings": "Server Address Settings", - "HeaderSetupLibrary": "Setup your media libraries", + "HeaderSetupLibrary": "Set up your media libraries", "HeaderSortBy": "Sort By", "HeaderSortOrder": "Sort Order", "HeaderSpecialEpisodeInfo": "Special Episode Info", @@ -501,6 +511,7 @@ "HeaderUploadSubtitle": "Upload Subtitle", "HeaderUser": "User", "HeaderUsers": "Users", + "HeaderVideoAdvanced": "Video Advanced", "HeaderVideoQuality": "Video Quality", "HeaderVideos": "Videos", "HeaderVideoType": "Video Type", @@ -516,9 +527,11 @@ "Identify": "Identify", "IgnoreDts": "Ignore DTS (decoding timestamp)", "IgnoreDtsHelp": "Disabling this option may resolve some issues, e.g. missing audio on channels with separate audio and video streams.", + "Illustrator": "Illustrator", "Image": "Image", "Images": "Images", "ImportFavoriteChannelsHelp": "Only channels that are marked as favorite on the tuner device will be imported.", + "Inker": "Inker", "InstallingPackage": "Installing {0} (version {1})", "InstantMix": "Instant mix", "ItemCount": "{0} items", @@ -544,7 +557,7 @@ "LabelAllowedRemoteAddressesMode": "Remote IP address filter mode", "LabelAllowHWTranscoding": "Allow hardware transcoding", "LabelAppName": "App name", - "LabelAppNameExample": "Example: Sickbeard, Sonarr", + "LabelAppNameExample": "A human readable name for identifying API keys. This setting will not affect functionality.", "LabelArtists": "Artists", "LabelArtistsHelp": "Separate multiple artists with a semicolon.", "LabelAudioBitDepth": "Audio bit depth", @@ -759,7 +772,7 @@ "LabelOriginalTitle": "Original title", "LabelOverview": "Overview", "LabelParallelImageEncodingLimit": "Parallel image encoding limit", - "LabelParallelImageEncodingLimitHelp": "Maximum amount of image encodings that are allowed to run in parallel. Setting this to 0 will choose a limit based on your system specs.", + "LabelParallelImageEncodingLimitHelp": "Maximum number of image encodings that are allowed to run in parallel. Setting this to 0 will choose a limit based on your systems core count.", "LabelParentalRating": "Parental rating", "LabelParentNumber": "Parent number", "LabelPassword": "Password", @@ -944,7 +957,10 @@ "LatestFromLibrary": "Recently Added in {0}", "LearnHowYouCanContribute": "Learn how you can contribute.", "LeaveBlankToNotSetAPassword": "You can leave this field blank to set no password.", + "Letterer": "Letterer", "LibraryAccessHelp": "Select the libraries to share with this user. Administrators will be able to edit all folders using the metadata manager.", + "LibraryScanFanoutConcurrency": "Parallel library scan tasks limit", + "LibraryScanFanoutConcurrencyHelp": "Maximum number of parallel tasks during library scans. Setting this to 0 will choose a limit based on your systems core count. WARNING: Setting this number too high may cause issues with network file systems; if you encounter problems lower this number.", "LimitSupportedVideoResolution": "Limit maximum supported video resolution", "LimitSupportedVideoResolutionHelp": "Use 'Maximum Allowed Video Transcoding Resolution' as maximum supported video resolution.", "List": "List", @@ -1230,6 +1246,7 @@ "PasswordResetProviderHelp": "Pick a password reset provider to be used when this user requests a password reset.", "PasswordSaved": "Password saved.", "PathNotFound": "The path could not be found. Please ensure the path is valid and try again.", + "Penciller": "Penciler", "People": "People", "PerfectMatch": "Perfect match", "Person": "Person", @@ -1257,6 +1274,10 @@ "PlayCount": "Play count", "Played": "Played", "PlayFromBeginning": "Play from beginning", + "PlaylistError.AddFailed": "Error adding to playlist", + "PlaylistError.CreateFailed": "Error creating playlist", + "PlaylistPublic": "Allow public access", + "PlaylistPublicDescription": "Allow this playlist to be viewed by any logged in user.", "Playlists": "Playlists", "PlayNext": "Play next", "PlayNextEpisodeAutomatically": "Play next episode automatically", @@ -1347,6 +1368,9 @@ "Saturday": "Saturday", "Save": "Save", "SaveChanges": "Save changes", + "SaveLyricsIntoMediaFolders": "Save lyrics into media folders", + "SaveLyricsIntoMediaFoldersHelp": "Storing lyrics next to audio files will allow them to be more easily managed.", + "SavePassword": "Save Password", "SaveRecordingNFO": "Save recording EPG metadata in NFO", "SaveRecordingNFOHelp": "Save metadata from EPG listings provider along side media.", "SaveRecordingImages": "Save recording EPG images", @@ -1472,6 +1496,7 @@ "TrackCount": "{0} tracks", "Trailers": "Trailers", "Transcoding": "Transcoding", + "Translator": "Translator", "Tuesday": "Tuesday", "TV": "TV", "TvLibraryHelp": "Review the {0}TV naming guide{1}.", @@ -1542,7 +1567,7 @@ "XmlTvNewsCategoriesHelp": "Programs with these categories will be displayed as news programs. Separate multiple with '|'.", "XmlTvPathHelp": "A path to a XMLTV file. Jellyfin will read this file and periodically check it for updates. You are responsible for creating and updating the file.", "XmlTvSportsCategoriesHelp": "Programs with these categories will be displayed as sports programs. Separate multiple with '|'.", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "Yes": "Yes", "Yesterday": "Yesterday", "HeaderSelectFallbackFontPath": "Select Fallback Font Folder Path", diff --git a/src/strings/es.json b/src/strings/es.json index 06d8d795cc..87b2ca3531 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -171,7 +171,7 @@ "GuestStar": "Estrella invitada", "Guide": "Guía", "GuideProviderSelectListings": "Seleccionar listados", - "H264CrfHelp": "El 'Factor de Velocidad Constante' (CRF) es el ajuste de calidad predeterminado para los codificadores x264 y x265. 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 sanos están entre 18 y 28. El valor predeterminado para x264 es 23, y para x265 es 28, por lo que puede utilizar esto como punto de partida.", + "H264CrfHelp": "El 'Factor de Velocidad Constante' (CRF) es el ajuste de calidad predeterminado para los codificadores de software x264 y x265. 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 sanos están entre 18 y 28. El valor predeterminado para x264 es 23, y para x265 es 28, por lo que puede utilizar esto como punto de partida. Los codificadores de hardware no usan estos ajustes.", "EncoderPresetHelp": "Elige un valor más rápido para mejorar el rendimiento o un valor más lento para mejorar la calidad.", "HDPrograms": "Programas en HD", "HardwareAccelerationWarning": "Activar la aceleración por hardware puede producir inestabilidades en algunos entornos. Asegúrate de que tu sistema operativo y tus controladores de vídeo están actualizados. Si tienes dificultades para reproducir los vídeos después de activar esto, tendrás que volver a poner este ajuste en None.", @@ -311,7 +311,7 @@ "HeaderSendMessage": "Enviar mensaje", "HeaderSeriesOptions": "Opciones de series", "HeaderServerSettings": "Ajustes del servidor", - "HeaderSetupLibrary": "Configure sus bibliotecas de medios", + "HeaderSetupLibrary": "Configure su biblioteca multimedia", "HeaderSortBy": "Ordenar por", "HeaderSortOrder": "Orden", "HeaderSpecialEpisodeInfo": "Información del episodio especial", @@ -374,7 +374,7 @@ "LabelAllowedRemoteAddresses": "Filtro de dirección IP remota", "LabelAllowedRemoteAddressesMode": "Modo de filtro de dirección IP remota", "LabelAppName": "Nombre de la aplicación", - "LabelAppNameExample": "Ejemplo: Sickbeard, Sonarr", + "LabelAppNameExample": "Un nombre leible por humanos para identificar llaves de API. Esta opcion no afectara funcionalidad. Ejemplo: Sickbeard, Sonarr", "LabelArtists": "Artistas", "LabelArtistsHelp": "Separar múltiples artistas utilizando punto y coma.", "LabelAudioLanguagePreference": "Idioma de audio preferido", @@ -1275,7 +1275,7 @@ "LabelLibraryPageSize": "Tamaño de la página de la biblioteca", "LabelLibraryPageSizeHelp": "Establece la cantidad de ítems a mostrar en una página de la biblioteca. Ponlo en 0 para desactivar la paginación.", "UnsupportedPlayback": "Jellyfin no puede desencriptar contenido protegido por DRM aunque intentará reproducirlo de todas formas. Algunos archivos pueden aparecer completamente negros debido a encriptación u otras características no soportadas, como títulos interactivos.", - "Yadif": "YADIF", + "Yadif": "Otro filtro de desentrelazado YADIF", "ButtonTogglePlaylist": "Lista de reproducción", "Filter": "Filtro", "New": "Nuevo", @@ -1363,7 +1363,7 @@ "Restart": "Reiniciar", "ResetPassword": "Reiniciar Contraseña", "Profile": "Perfil", - "Bwdif": "BWDIF", + "Bwdif": "Filtro de Desentrelazado de Bob Weaver", "UseDoubleRateDeinterlacing": "Duplicar el número de cuadros por segundo al desentrelazar", "Photo": "Fotografía", "MusicVideos": "Vídeos musicales", @@ -1708,7 +1708,7 @@ "PreferEmbeddedExtrasTitlesOverFileNames": "Prefiere títulos incrustados sobre nombres de archivo para extras", "LabelDummyChapterCountHelp": "Número máximo de imágenes de capítulos que se extraerán para cada archivo multimedia.", "LabelEnableAudioVbrHelp": "La tasa de bits variable ofrece una mejor relación entre calidad y tasa de bits promedio, pero en algunos casos raros puede causar problemas de almacenamiento de búfer y compatibilidad.", - "LabelParallelImageEncodingLimitHelp": "Cantidad máxima de codificaciones de imágenes que pueden ejecutarse en paralelo. Establecer esto en 0 elegirá un límite basado en las especificaciones de su sistema.", + "LabelParallelImageEncodingLimitHelp": "Cantidad máxima de codificaciones de imágenes que pueden ejecutarse en paralelo. Establecer esto en 0 elegirá un límite basado en la cantidad de nucleos (CPU) en su sistema.", "ResolutionMatchSource": "Coincidir fuente", "SubtitleMagenta": "Magenta", "SubtitleWhite": "Blanco", @@ -1801,7 +1801,7 @@ "LabelServerVersion": "Versión del servidor", "AllowMjpegEncoding": "Permitir codificación en formato MJPEG (utilizado durante la generación de trickplay)", "Trickplay": "Trickplay", - "LabelTrickplayAccel": "Habilitar aceleración por hardware", + "LabelTrickplayAccel": "Habilitar descodificación por hardware", "LabelScanBehavior": "Comportamiento de Escaneo", "ConfirmDeleteSeries": "Eliminar esta serie eliminará TODOS {0} episodios tanto del sistema de archivos como de tu biblioteca de medios. ¿Estás seguro de que deseas continuar?", "DeleteEntireSeries": "Eliminar {0} Episodios", @@ -1827,8 +1827,69 @@ "PlaybackError.SERVER_ERROR": "La reproducción falló por un error del servidor.", "PlaybackError.NotAllowed": "La reproducción de este medio no está permitida.", "PlaybackError.RateLimitExceeded": "Este medio no puede reproducirse en este momento debído a límites.", - "EnableLibrary": "Activar la librería", - "EnableLibraryHelp": "Desactivando la biblioteca hará que no sea visible para ningún usuario.", - "ConfirmDeleteLyrics": "Borrando estas letras también las borrará tanto del sistema de ficheros como de tu librería de medios. ¿Estás seguro de que deseas continuar?", - "DeleteLyrics": "Borrar letras" + "EnableLibrary": "Activar la biblioteca", + "EnableLibraryHelp": "Desactivar la biblioteca hará que no sea visible para ningún usuario.", + "ConfirmDeleteLyrics": "Borrando estas letras también las borrará tanto del sistema de ficheros como de tu biblioteca de medios. ¿Estás seguro de que deseas continuar?", + "DeleteLyrics": "Borrar letras", + "HeaderNoLyrics": "No se han encontrado letras", + "ErrorDeletingLyrics": "Ha ocurrido un error al borrar las letras del servidor. Por favor asegúrate que Jellyfin tiene permisos de escritura para la carpeta de medios e inténtalo otra vez.", + "HeaderDeleteLyrics": "Borrar letras", + "Lyrics": "Letras", + "LabelTrickplayAccelEncodingHelp": "Actualmente solo disponible en QSV y VAAPI, esta opción no tiene ningún efecto en otros métodos de aceleración por hardware.", + "LabelProcessPriorityHelp": "Configurar esto más bajo o alto determinará cómo la CPU priorizará el proceso de generación de ffmpeg para trickplay en relación con otros procesos. Si notas bajadas de rendimiento mientras las imágenes de trickplay se generan pero no quieres parar su generación por completo, intenta reducir tanto esto como el número de hilos.", + "EncodingFormatHelp": "Selecciona la codificación de vídeo a la que Jellyfin debe transcodificar. Jellyfin usará codificación por software cuando la aceleración por hardware para el formato seleccionado no esté disponible. La codificación H264 siempre estará habilitada.", + "NonBlockingScan": "No bloqueante - encola la generación, después devuelve", + "BlockingScan": "Bloqueante - encola la generación, el escaneo se bloquea hasta que termine", + "LabelTrickplayAccelEncoding": "Habilitar la codificación MJPEG por hardware", + "PriorityHigh": "Alto", + "LabelScanBehaviorHelp": "El comportamiento por defecto es no bloqueante, que añadirá los medios a la biblioteca antes de que la generación trickplay se complete. El comportamiento bloqueante se asegurará de que los archivos de trickplay hayan sido generados antes de que los medios se añadan a la biblioteca, pero hará los escaneos significativamente más largos.", + "PriorityBelowNormal": "Más bajo de lo normal", + "LabelProcessPriority": "Prioridad de procesos", + "PriorityIdle": "Libre", + "LabelImageInterval": "Intervalo de imágenes", + "LabelAllowContentWithTags": "Permitir items con etiquetas", + "ViewLyrics": "Ver letras", + "PriorityAboveNormal": "Superior a lo normal", + "PriorityNormal": "Normal", + "SavePassword": "Guardar contraseña", + "LabelTileWidth": "Anchura de pieza", + "LabelTileHeight": "Altura de pieza", + "LabelTileHeightHelp": "Máximo número de imágenes por pieza en la dirección Y.", + "LabelJpegQuality": "Calidad JPEG", + "ExtractTrickplayImagesHelp": "Las imágenes de trickplay son similares a las de los capítulos, excepto por que se distribuyen a lo largo del contenido y se usan para mostrarse como una previsualización mientras te mueves por el vídeo.", + "LabelImageIntervalHelp": "Intervalo de tiempo (ms) entre cada nueva imagen de trickplay.", + "LabelWidthResolutions": "Resoluciones de anchura", + "LabelQscale": "Qscale", + "LabelJpegQualityHelp": "La calidad de compresión JPEG para las imágenes de trickplay.", + "LabelExtractTrickplayDuringLibraryScan": "Extraer imágenes para trickplay durante el escaneo de la biblioteca", + "LabelTileWidthHelp": "Máximo número de imágenes por pieza en la dirección X.", + "LabelQscaleHelp": "La escala de calidad de imágenes de la salida de ffmpeg, siendo 2 la mayor calidad y 31 la peor.", + "LabelTrickplayThreads": "Hilos FFmpeg", + "LabelTrickplayThreadsHelp": "El número de hilos para pasar al argumento '-threads' de ffmpeg.", + "LabelWidthResolutionsHelp": "Lista separada por comas de las anchuras (px) en las que se generarán las imágenes de trickplay. Todas las imágenes se generarán proporcionalmente a la fuente, así que una anchura de 320 en un vídeo 16:9 acabará sobre 320x180.", + "OptionExtractTrickplayImage": "Habilitar la extracción de imágenes de trickplay", + "LabelExtractTrickplayDuringLibraryScanHelp": "Generar imágenes de trickplay cuando los vídeos se importan durante el escaneo de la biblioteca. De lo contrario se extraerán durante la tarea programada de extracción de imágenes de trickplay. Si la generación es no bloqueante esto no afectará al tiempo que la biblioteca tarda en escanearse.", + "Author": "Autor", + "LibraryScanFanoutConcurrencyHelp": "Numero maximo de tareas de escaneos en librerias paralelas. Marcar esta opcion en 0 escogera un limite basado en la cantidad de nucleos (CPU) en sus sistema. ADVERTENCIA: Marcar este numero demasiado alto puede causar problemas con sistemas de archivos de red; si encuentra problemas baje este numero.", + "LibraryScanFanoutConcurrency": "Limite de escaneos de tareas en librerias paralelas", + "Penciller": "Lapicista", + "PlaylistError.CreateFailed": "Error creando lista de reproduccion", + "PlaylistError.AddFailed": "Error agregando a lista de reproduccion", + "SaveLyricsIntoMediaFoldersHelp": "Almacenar letras junto a archivos de audio les permitira ser administradas mas facilmente.", + "Colorist": "Colorista", + "CoverArtist": "Caratula de Artista", + "Creator": "Creador", + "Editor": "Editor", + "Illustrator": "Ilustrador", + "Letterer": "Rotulador", + "Translator": "Traductor", + "EnableTrueHdHelp": "Solo habilitar si su dispositivo soporta TrueHD o esta conectado a receptor de audio compatible, de otra manera puede causar fallos de reproduccion.", + "EnableDts": "Habilitar DTS (DCA)", + "EnableDtsHelp": "Solo habilitar si su dispositivo soporta DTS o esta conectado a un receptor de audio compatible, de otra forma puede causar fallos de reproduccion.", + "EnableTrueHd": "Habilitar TrueHD", + "PlaylistPublic": "Permitir acceso publico", + "PlaylistPublicDescription": "Permitir que esta lista de reproduccion sea vista por cualquier usuario que este logueado.", + "HeaderLyricDownloads": "Descarga de letras", + "HeaderVideoAdvanced": "Video Avanzado", + "SaveLyricsIntoMediaFolders": "Guardar letras en carpeta de media" } diff --git a/src/strings/fa.json b/src/strings/fa.json index 11fa9eab51..551be4c5c2 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -1605,7 +1605,7 @@ "EnableAudioNormalization": "معمول سازی صوت", "AllowCollectionManagement": "به این کاربر اجازه مدیریت مجموعه را بده", "AllowSegmentDeletion": "تکه ها را پاک کن", - "AllowSegmentDeletionHelp": "پاک کردن تکه های قدیمی را بعد از فرستادن به کلاینت. این کار از ذخیره کل فایل transcode شده بر روی هارد جلوگیری می‌ کند. این تنها زمانی کار می کند که throttling فعال باشد. درصورت مشکل در هنگام پخش این ویژگی را غیرفعال کنید.", + "AllowSegmentDeletionHelp": "پاک کردن تکه های قدیمی بعد از دریافت کلاینت. این کار از ذخیره کل فایل transcode شده بر روی هارد جلوگیری می‌ کند. این تنها زمانی کار می کند که throttling فعال باشد. درصورت مشکل در هنگام پخش این ویژگی را غیرفعال کنید.", "LogLevel.Error": "خطا", "LogLevel.Critical": "بحرانی", "LogLevel.None": "هیچکدام", @@ -1625,5 +1625,8 @@ "LogLevel.Information": "اطلاعات", "LogoScreensaver": "محافظ صفحه لوگو", "Localization": "محلی‌سازی", - "HeaderGuestCast": "بازیگران مهمان" + "HeaderGuestCast": "بازیگران مهمان", + "AirPlay": "پخش هوا", + "AllowContentWithTagsHelp": "فقط رسانه های دارای حداقل یکی از برچسب های مشخص شده را نشان بده.", + "AllowSubtitleManagement": "به این کاربر اجازه ویرایش زیرنویس بده" } diff --git a/src/strings/fi.json b/src/strings/fi.json index a84f21897c..6427a8f1c9 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -1856,5 +1856,23 @@ "ExtractTrickplayImagesHelp": "Trickplay-kuvat ovat samankaltaisia kuin kappalekuvat, paitsi että ne ovat koko sisällön pituudelta ja niitä käytetään esikatseluna videota selattaessa.", "NonBlockingScan": "Ei-blokkaava - asettaa generoinnin jonoon ja palaa", "BlockingScan": "Blokkaava - asettaa generoinnin jonoon ja estää skannauksen ennen kuin se on valmis", - "LabelExtractTrickplayDuringLibraryScan": "Luo trickplay-kuvat kirjaston skannauksen yhteydessä" + "LabelExtractTrickplayDuringLibraryScan": "Luo trickplay-kuvat kirjaston skannauksen yhteydessä", + "PlaylistError.AddFailed": "Virhe soittolistaan lisättäessä", + "PlaylistError.CreateFailed": "Virhe soittolistaa luodessa", + "LibraryScanFanoutConcurrency": "Rinnakkaisten kirjastopäivityksien raja", + "Lyrics": "Sanoitukset", + "SavePassword": "Tallenna salasana", + "Author": "Tekijä", + "Colorist": "Koloristi", + "CoverArtist": "Kansitaiteilija", + "Creator": "Luoja", + "Illustrator": "Kuvittaja", + "Translator": "Kääntäjä", + "DeleteLyrics": "Poista sanoitukset", + "HeaderDeleteLyrics": "Poista sanoitukset", + "HeaderNoLyrics": "Sanoituksia ei löydy", + "ViewLyrics": "Näytä sanoitukset", + "HeaderLyricDownloads": "Sanoitusten lataaminen", + "SaveLyricsIntoMediaFolders": "Tallenna sanoitukset mediakansioon", + "PlaylistPublic": "Salli julkinen pääsy" } diff --git a/src/strings/fr.json b/src/strings/fr.json index 5d04a7bbea..8bd579765f 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -426,7 +426,7 @@ "LabelAllowedRemoteAddresses": "Filtre d'adresse IP distante", "LabelAllowedRemoteAddressesMode": "Type de filtre des adresses IP distantes", "LabelAppName": "Nom de l'application", - "LabelAppNameExample": "Exemple : Sickbeard, Sonarr", + "LabelAppNameExample": "Nom humainement lisible pour identifier les clés d'API. Ce paramètre n'affecte pas les fonctionnalités.", "LabelArtists": "Artistes", "LabelArtistsHelp": "Séparer les artistes par un point-virgule.", "LabelAudioLanguagePreference": "Langue audio préférée", @@ -1245,7 +1245,7 @@ "LabelDroppedFrames": "Images perdues", "LabelCorruptedFrames": "Images corrompues", "AskAdminToCreateLibrary": "Demander à un administrateur de créer une médiathèque.", - "AllowFfmpegThrottlingHelp": "Quand le transcodage ou le remultiplexage est suffisamment en avant de la position de lecture, le processus se mettra en pause afin d’économiser des ressources. Ceci est particulièrement utile lors d’une lecture continue. À désactiver en cas de problèmes de lecture.", + "AllowFfmpegThrottlingHelp": "Quand le transcodage ou le remultiplexage est suffisamment en avance sur la lecture, le processus se mettra en pause afin d’économiser des ressources. Ceci est particulièrement utile lors d’une lecture continue. À désactiver en cas de problèmes de lecture.", "AllowFfmpegThrottling": "Adapter la vitesse du transcodage", "NoCreatedLibraries": "Il semble que vous n'ayez pas encore créé de bibliothèques. {0}Voulez-vous en créer une maintenant ?{1}", "PlaybackErrorNoCompatibleStream": "Ce client n'est pas compatible avec le média et le serveur n'envoie pas de format compatible.", @@ -1272,7 +1272,7 @@ "ListPaging": "{0}-{1} de {2}", "WriteAccessRequired": "Jellyfin a besoin d'un accès en écriture à ce dossier. Merci de vérifier les permissions de ce-dernier puis de réessayer.", "PathNotFound": "Le chemin d'accès n'a pas pu être trouvé. Merci de vérifier qu'il est valide et de réessayer.", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "LabelDeinterlaceMethod": "Méthode de désentrelacement", "DeinterlaceMethodHelp": "Sélectionner la méthode de désentrelacement à utiliser lors du transcodage de contenu entrelacé. Lorsque l'accélération matérielle supportant le désentrelacement matériel est activée, le désentrelaceur matériel sera utilisé à la place de ce paramètre.", "LabelLibraryPageSize": "Taille des pages de la médiathèque", @@ -1377,7 +1377,7 @@ "Other": "Autre", "PosterCard": "Affiche sur carte", "UseDoubleRateDeinterlacing": "Multiplier par deux la fréquence d'images lors du désentrelacement", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "UseDoubleRateDeinterlacingHelp": "Ce réglage utilise la fréquence de trame lors du désentrelacement, souvent appelé désentrelacement \"bob\", qui double la fréquence d'images de la vidéo pour fournir un mouvement fluide comme en regardant une vidéo entrelacée sur un téléviseur.", "LabelTonemappingDesat": "Désaturation tonale", "TonemappingRangeHelp": "Définir la gamme de couleurs de sortie. Choisir 'Auto' pour utiliser la même gamme de couleurs qu'en entrée.", @@ -1615,7 +1615,7 @@ "SelectAll": "Tout sélectionner", "ButtonExitApp": "Quitter l'application", "Clip": "Clip", - "ThemeVideo": "Thème Vidéo", + "ThemeVideo": "Thème vidéo", "ThemeSong": "Thème musical", "Sample": "Échantillon", "Scene": "Scène", @@ -1676,7 +1676,7 @@ "RememberSubtitleSelections": "Définir la piste de sous-titre en fonction de l'élément précédent", "RememberAudioSelectionsHelp": "Choisir la piste audio la plus proche de la dernière vidéo.", "RememberAudioSelections": "Définir la piste audio en fonction de l'élément précédent", - "IgnoreDtsHelp": "Désactiver cette option peut résoudre certains problèmes, par exemple une piste audio manquante sur les chaines TV avec flux audio et vidéo séparés.", + "IgnoreDtsHelp": "Désactiver cette option peut résoudre certains problèmes, par exemple une piste audio manquante sur les chaînes avec flux audio et vidéo séparés.", "OptionDateShowAdded": "Date d'ajout de la série", "OptionDateEpisodeAdded": "Date d'ajout de l'épisode", "IgnoreDts": "Ignorer le DTS (horodatage de décodage)", @@ -1719,7 +1719,7 @@ "Short": "Court-métrage", "HeaderPerformance": "Performance", "LabelParallelImageEncodingLimit": "Limite de parallélisation de l'encodage d'image", - "LabelParallelImageEncodingLimitHelp": "Nombre maximal d’encodages d’image autorisés à s’exécuter en parallèle. Si vous définissez cette valeur sur 0, vous choisirez une limite en fonction des spécifications de votre système.", + "LabelParallelImageEncodingLimitHelp": "Nombre maximal d’encodages d’image autorisés à s’exécuter en parallèle. Si vous définissez cette valeur sur 0, la limite sera choisie en fonction du nombre de cœurs de votre système.", "LabelEnableAudioVbr": "Activer l’encodage audio VBR", "LabelEnableAudioVbrHelp": "Le débit binaire variable offre une qualité supérieure à la moyenne mais peut, dans de rares cas, causer des problèmes de mise en mémoire tampon et de compatibilité.", "LabelTonemappingMode": "Mode de mappage tonal", @@ -1807,8 +1807,8 @@ "LabelAllowContentWithTags": "Autoriser les objets comportants des étiquettes", "ConfirmDeleteSeries": "La suppression de cette série effacera l'ENTIÈRETÉ des {0} épisodes à la fois de votre système de ficher et de votre médiathèque. Êtes-vous sur de vouloir continuer ?", "DeleteEntireSeries": "Supprimer {0} Épisodes", - "DeleteSeries": "Supprimer Séries", - "DeleteEpisode": "Suppri", + "DeleteSeries": "Supprimer la série", + "DeleteEpisode": "Supprimer l'épisode", "HeaderDeleteSeries": "Supprimer Séries", "EnableSmoothScroll": "Activer le défilement fluide", "Lyric": "Parole", @@ -1835,7 +1835,7 @@ "LabelProcessPriorityHelp": "Un réglage inférieur ou supérieur déterminera la manière dont le processeur donne la priorité au processus de génération de trickplay ffmpeg par rapport aux autres processus. Si vous remarquez un ralentissement lors de la génération d'images trickplay mais que vous ne souhaitez pas arrêter complètement leur génération, essayez de réduire ce ralentissement en modifiant le nombre de threads.", "LabelImageIntervalHelp": "Intervalle de temps (ms) entre chaque nouvelle image trickplay.", "LabelWidthResolutions": "Largeur des résolutions", - "LabelTrickplayAccel": "Activer l'accélération matérielle", + "LabelTrickplayAccel": "Activer le décodage matériel", "LabelTrickplayAccelHelp": "Assurez-vous d'activer « Autoriser l'encodage MJPEG » dans Transcodage si votre matériel le prend en charge.", "NonBlockingScan": "Non bloquant - génération de files d'attente, puis retour", "BlockingScan": "Bloquant - génération de files d'attente, analyse des blocs jusqu'à la fin", @@ -1858,14 +1858,34 @@ "PlaybackError.MEDIA_NOT_SUPPORTED": "La lecture a échoué car le média n'est pas pris en charge par ce client.", "PlaybackError.NETWORK_ERROR": "La lecture a échoué à cause d'une erreur réseau.", "PlaybackError.NO_MEDIA_ERROR": "Impossible de trouver une source multimédia valide à lire.", - "PlaybackError.PLAYER_ERROR": "La lecture a échoué en raison d'une erreur fatale du joueur.", + "PlaybackError.PLAYER_ERROR": "La lecture a échoué en raison d'une erreur fatale du lecteur.", "LabelTrickplayAccelEncoding": "Activer l'encodage MJPEG accéléré par le matériel", "LabelTrickplayAccelEncodingHelp": "Actuellement disponible uniquement sur QSV et VAAPI, cette option n'a aucun effet sur les autres méthodes d'accélération matérielle.", "ErrorDeletingLyrics": "Une erreur est survenu lors de la suppression des paroles du serveur. S'il vous plaît verifier que Jellyfin peut modifier les fichier dans le dossier multimedia et réessayez.", - "HeaderDeleteLyrics": "Supprimez ces paroles", + "HeaderDeleteLyrics": "Suppression des paroles", "ConfirmDeleteLyrics": "En supprimant ces paroles vous les supprimez a la fois de votre systeme de fichier et de votre bibliothèque. Êtes vous sure de vouloir continuez ?", - "DeleteLyrics": "Supprimez ces paroles", + "DeleteLyrics": "Supprimer ces paroles", "HeaderNoLyrics": "Aucune paroles n'ont êtes trouves", "Lyrics": "Paroles", - "ViewLyrics": "Voir les paroles" + "ViewLyrics": "Voir les paroles", + "SavePassword": "Sauvegarder le mot de passe", + "EnableDts": "Activer DTS (DCA)", + "EnableDtsHelp": "N'activez cette option que si votre appareil prend en charge le DTS ou s'il est connecté à un lecteur audio compatible, sinon la lecture risque d'échouer.", + "EnableTrueHdHelp": "N'activez cette option que si votre appareil prend en charge la norme TrueHD ou s'il est connecté à un lecteur audio compatible, sinon la lecture risque d'échouer.", + "EnableTrueHd": "Activer le TrueHD", + "PlaylistError.CreateFailed": "Erreur lors de la création d'une liste de lecture", + "SaveLyricsIntoMediaFolders": "Enregistrer les paroles dans les dossiers média", + "PlaylistError.AddFailed": "Erreur d'ajout à la liste de lecture", + "SaveLyricsIntoMediaFoldersHelp": "Le stockage des paroles à côté des fichiers audio permet de les gérer plus facilement.", + "HeaderVideoAdvanced": "Vidéo avancée", + "PlaylistPublic": "Autoriser l'accès public", + "PlaylistPublicDescription": "Autoriser la lecture de cette liste de lecture par n'importe quel utilisateur connecté.", + "HeaderLyricDownloads": "Téléchargements des paroles", + "Illustrator": "Illustrateur", + "Author": "Auteur", + "LibraryScanFanoutConcurrencyHelp": "Nombre maximal de tâches en parallèle pour les scans de bibliothèque. Si vous définissez cette valeur à 0, la limite sera choisie en fonction du nombre de cœurs de votre système. ATTENTION : Définir une valeur trop élevée peut causer des problèmes avec les systèmes de fichiers en réseau ; si vous rencontrez des problèmes, diminuez cette valeur.", + "Colorist": "Coloriste", + "Creator": "Créateur", + "LibraryScanFanoutConcurrency": "Limite de tâches de scan de bibliothèque en parallèle", + "Translator": "Traducteur" } diff --git a/src/strings/he.json b/src/strings/he.json index b76b68354a..03525018f3 100644 --- a/src/strings/he.json +++ b/src/strings/he.json @@ -1281,5 +1281,6 @@ "LabelMaxAudiobookResume": "דקות נותרות בספר המוקלט להמשך", "LabelMaxAudiobookResumeHelp": "כותרים נחשבים כנוגנו במלואם כאשר משך הזמן הנותר קטן יותר מערך זה.", "LabelMetadataReaders": "קוראי מטא-דאטה", - "LabelMetadataSavers": "שומרי מטא-דאטה" + "LabelMetadataSavers": "שומרי מטא-דאטה", + "PlaybackError.RateLimitExceeded": "מדיה" } diff --git a/src/strings/hr.json b/src/strings/hr.json index e0e701b611..053ba990c4 100644 --- a/src/strings/hr.json +++ b/src/strings/hr.json @@ -1071,7 +1071,7 @@ "ButtonUseQuickConnect": "Omogući brzo povezivanje", "ButtonActivate": "Aktiviraj", "AllowedRemoteAddressesHelp": "Popis IP adresa ili mrežnih maska odvojen zarezom za mreže kojima će biti dopušten udaljeni pristup. Ako ostane prazno, bit će dopuštene sve udaljene adrese.", - "AllowFfmpegThrottlingHelp": "Kada se transkodira ili remiks dovoljno udalji od trenutne pozicije reprodukcije, zaustavite postupak tako da će potrošiti manje resursa. Ovo je najkorisnije kada gledate bez čestog traženja. Isključite ovo ako imate problema s reprodukcijom.", + "AllowFfmpegThrottlingHelp": "Kada se transkodira ili se remuks dovoljno udalji od trenutne pozicije reprodukcije, zaustavite postupak tako da se troši manje resursa. Ovo je najkorisnije kada gledate bez čestog traženja. Isključite ovo ako imate problema s reprodukcijom.", "BurnSubtitlesHelp": "Odredite treba li server snimati titlove tijekom transkodiranja videozapisa. Izbjegavanje toga uvelike će poboljšati performanse. Odaberite Automatski za snimanje slikovnih formata (VobSub, PGS, SUB, IDX itd.) i određenih ASS ili SSA titlova.", "BoxSet": "Komplet", "Authorize": "Ovlastite", @@ -1512,7 +1512,7 @@ "ShowYear": "Prikaži godinu", "LabelLocalCustomCss": "Prilagođeni CSS kod za stil koji se odnosi samo na ovog klijenta. Možda ćete htjeti onemogućiti prilagođeni CSS kod poslužitelja.", "LabelPlayerDimensions": "Dimenzije izvođača", - "LabelSegmentKeepSecondsHelp": "Vrijeme u sekundama za koje se segmenti trebaju čuvati prije nego što se prebrišu. Mora biti veći od \"Throttle after\". Radi samo ako je omogućeno brisanje segmenta.", + "LabelSegmentKeepSecondsHelp": "Vrijeme u sekundama za koje se segmenti trebaju čuvati prije nego što se prebrišu. Radi samo ako je omogućeno brisanje segmenta.", "LabelKnownProxies": "Poznati proxy-i", "ButtonBackspace": "Backspace", "LabelHomeScreenSectionValue": "{0}. odjeljak početne", diff --git a/src/strings/hu.json b/src/strings/hu.json index 49b416302f..534ba445c2 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -142,7 +142,7 @@ "HeaderSeasons": "Évadok", "HeaderSelectMetadataPath": "Válaszd ki a metaadat útvonalat", "HeaderSendMessage": "Üzenet küldése", - "HeaderSetupLibrary": "Média könyvtárak beállítása", + "HeaderSetupLibrary": "Állítsd be a média könyvtáraidat", "HeaderSortBy": "Megjelenítés", "HeaderSortOrder": "Sorrend", "HeaderStatus": "Állapot", @@ -482,7 +482,7 @@ "ButtonSelectView": "Válassz nézetet", "ButtonStart": "Indítás", "CancelRecording": "Felvétel törlése", - "CancelSeries": "Sorozat törlése", + "CancelSeries": "Sorozat visszavonása", "Categories": "Kategóriák", "ChangingMetadataImageSettingsNewContent": "A metaadatok vagy az artwork fileok letöltési beállításainak módosítása csak a könyvtárhoz hozzáadott új tartalomra vonatkozik. A meglévő címek módosításainak alkalmazásához manuálisan kell frissíteni a metaadatokat.", "ChannelAccessHelp": "Válaszd ki a megosztani kívánt csatornákat a felhasználóval. A rendszergazdák a metaadatkezelő segítségével szerkeszthetik az összes csatornát.", @@ -494,8 +494,8 @@ "Composer": "Zeneszerző", "ConfigureDateAdded": "Állítsa be, hogy a „Hozzáadás Dátuma” metaadatok hogyan legyenek meghatározva az Irányítópult > Könyvtárak > NFO-beállítások menüpontban", "ConfirmDeleteImage": "Kép törlése?", - "ConfirmDeleteItem": "Az elem törlése mind a fájlrendszerből, mind a médiakönyvtárból törlődik. Biztosan folytatni akarod?", - "ConfirmDeleteItems": "Az elem törlése mind a fájlrendszerből, mind a médiakönyvtárból törlődik. Biztosan folytatni akarod?", + "ConfirmDeleteItem": "Az elem törlésével az törlődni fog a fájlrendszerből és a médiakönyvtárból is. Biztosan folytatni akarod?", + "ConfirmDeleteItems": "Az elemek törlésével azok törlődni fognak a fájlrendszerből és a médiakönyvtárból is. Biztosan folytatni akarod?", "ConfirmDeletion": "Törlés megerősítése", "ConfirmEndPlayerSession": "Szeretnéd leállítani a Jellyfin-t {0}?", "ContinueWatching": "Megtekintés folytatása", @@ -563,7 +563,7 @@ "HeaderActivity": "Tevékenységek", "HeaderAdditionalParts": "További részek", "HeaderAdmin": "Felügyelet", - "HeaderAlbumArtists": "Albumelőadók", + "HeaderAlbumArtists": "Album előadók", "HeaderAlert": "Figyelem", "HeaderAllowMediaDeletionFrom": "Médiatörlés engedélyezése innen", "HeaderApiKey": "API kulcs", @@ -1114,7 +1114,7 @@ "EnableStreamLooping": "Élő műsorfolyamok automatikus újrajátszása", "EnableStreamLoopingHelp": "Kapcsold be, ha az élő stream csak néhány másodpercnyi adatot tartalmaz és folyamatosan újra kell kérni. Ennek szükségtelen bekapcsolása problémát okozhat.", "Guide": "Műsorújság", - "H264CrfHelp": "A 'Constant Rate Factor' (CRF) az alapértelmezett minőségi beállítás az x264 és x265 enkóderhez. Az értékek 0 és 51 között állíthatók, ahol az alacsonyabb érték jobb minőséget eredményez (nagyobb fájl méret mellett). Az ajánlott érték 18 és 28 között van. Az x264 alapértelmezett beállítása 23, x265-é 28, ez lehet kiindulási alap.", + "H264CrfHelp": "A 'Constant Rate Factor' (CRF) az alapértelmezett minőségi beállítás az x264 és x265 enkóderekhez. Az értékek 0 és 51 között állíthatók, ahol az alacsonyabb érték jobb minőséget eredményez (nagyobb fájl méret mellett). Az ajánlott érték 18 és 28 között van. Az x264 alapértelmezett beállítása 23, x265-é 28, ez lehet kiindulási alap. A hardveresen gyorsított enkóderek nem használják ezt a beállítást.", "HeaderApiKeysHelp": "A külső alkalmazásoknak egy API kulcsra van szüksége, hogy kommunikáljanak a szerverrel. A kulcsokat egy fiókkal történő belépéssel lehet megkapni, vagy kézileg felvenni egy alkalmazáshoz tartozó kulcsot.", "HeaderBranding": "Személyes arculat", "HeaderContinueListening": "Folyamatban lévő zenék", @@ -1397,7 +1397,7 @@ "LabelTonemappingRange": "Tónusleképezés tartomány", "TonemappingAlgorithmHelp": "A tónusleképezés finomhangolható. Ha még nem ismered ezeket az opciókat, tartsd meg az alapértelmezett értéket. Az ajánlott érték 'BT.2390'.", "LabelTonemappingAlgorithm": "Válaszd ki a használni kívánt tónusleképezési algoritmust", - "AllowTonemappingHelp": "", + "AllowTonemappingHelp": "A tónusleképzés képes a HDR videók dinamika tartományát SDR tartományba átalakítani, miközben megtartja a kép színét és részleteit, ami elengedhetetlen az eredeti látvány megőrzéséhez. Jelenleg csak 10 bites HDR10, HLG és DoVi tartalmakon működik. Használatához szükséges a vonatkozó GPGPU szolgáltatás.", "EnableTonemapping": "Tónusleképezés engedélyezése", "LabelOpenclDeviceHelp": "Ez az OpenCL eszköz, amelyet a tónusleképezéshez használnak. A pont bal oldala a platform száma, a jobb oldala pedig a platformon található eszköz száma. Az alapértelmezett érték 0.0. Az OpenCL hardveres gyorsítási módszert tartalmazó FFmpeg alkalmazásfájl szükséges.", "LabelOpenclDevice": "OpenCL eszköz", @@ -1649,7 +1649,7 @@ "OriginalAirDate": "Eredeti megjelenési dátum", "MessageUnauthorizedUser": "Jelenleg nincs jogosultsága a szerver elérésére. További információért fordulj a szerver rendszergazdájához.", "Digital": "Digitális", - "EnableEnhancedNvdecDecoderHelp": "Kísérleti NVDEC implementáció, csak akkor engedélyezze ezt a lehetőséget, ha dekódolási hibákat észlel.", + "EnableEnhancedNvdecDecoderHelp": "Bővített NVDEC implementáció, csak akkor engedélyezze, ha dekódolási hibákat észlel.", "HomeVideosPhotos": "Otthoni videók és fotók", "Bold": "Félkövér", "LabelTextWeight": "Betűvastagság", @@ -1795,5 +1795,74 @@ "LabelServerVersion": "Szerver verzió", "AllowSubtitleManagement": "Feliratok szerkesztésének engedélyezése ennél a felhasználónál", "AllowContentWithTagsHelp": "Csak a megadott címkék legalább egyikével rendelkező médiát jeleníti meg.", - "AirPlay": "AirPlay" + "AirPlay": "AirPlay", + "LabelScanBehaviorHelp": "A kiindulási magatartás nem blokkoló, tehát a tartalom a könyvtárba kerül a lejátszástrükk generálás befejezése előtt. A blokkoló magatartás meggátolja könyvtárba kerülést a generálás befejeződéséig, de lényegesen hosszabbá teszi a könyvtárak beolvasását.", + "PlaybackError.SERVER_ERROR": "A lejátszás meghiúsult kiszolgáló hiba miatt.", + "PlaybackError.NO_MEDIA_ERROR": "Nem található lejátszható tartalom.", + "BlockContentWithTagsHelp": "Rejtse el a legalább egy megadott címkével ellátott tartalmakat.", + "PlaybackError.NETWORK_ERROR": "A lejátszás meghiúsult hálózati hiba miatt.", + "PlaybackError.PLAYER_ERROR": "A lejátszás meghiúsult végzetes lejátszó hiba miatt.", + "SavePassword": "Jelszó mentése", + "LabelEncodingFormatOptions": "Enkóder formátum beállítások", + "EncodingFormatHelp": "Válaszd ki, hogy a Jellyfin melyik enkódert használja. Ha hardveres gyorsítás nem elérhető a választott enkóderhez, a Jellyfin szoftver enkódert fog helyette használni. A H264 enkóder mindig engedélyezve lesz.", + "Trickplay": "Lejátszótrükk", + "PlaybackError.MEDIA_DECODE_ERROR": "A lejátszás meghiúsult tartalom dekódolási hiba miatt.", + "PlaybackError.MEDIA_NOT_SUPPORTED": "A lejátszás meghiúsult, mert a tartalmat a kliens nem támogatja.", + "PlaybackError.NotAllowed": "Ennek a tartalomnak a lejátszása nem engedélyezett.", + "BlockingScan": "Blokkoló - beütemezi a generációt és blokkolja a tartalom keresést ameddig elkészül", + "LabelTrickplayAccelEncodingHelp": "Jelenleg csak QSV és VAAPI gyorsítókon elérhető, más hardveres gyorsítókat nem befolyásol.", + "PriorityHigh": "Magas", + "LabelTrickplayAccelEncoding": "Hardveresen gyorsított MJPEG enkódolás engedélyezése", + "ConfirmDeleteLyrics": "A dalszövegek törlésével azok törlődni fognak a fájlrendszerből és a médiakönyvtárból is. Biztosan folytatni akarod?", + "DeleteEntireSeries": "{0} Epizód törlése", + "DeleteEpisode": "Epizód törlése", + "DeleteLyrics": "Dalszövegek törlése", + "DeleteSeries": "Sorozat törlése", + "DeleteName": "{0} Törlése", + "ErrorDeletingLyrics": "A dalszövegek törlése közben hiba lépett fel. Kérlek ellenőrizd, hogy a Jellyfin rendelkezik e írási jogosultsággal a könyvtárhoz, majd próbáld újra.", + "HeaderDeleteSeries": "Sorozat törlése", + "HeaderDeleteLyrics": "Dalszövegek Törlése", + "HeaderNoLyrics": "Nem található dalszöveg", + "LimitSupportedVideoResolutionHelp": "Használja a maximum engedélyezett videó átkódolási felbontást a maximum támogatott videó felbontásként.", + "Lyric": "Dalszöveg", + "Lyrics": "Dalszövegek", + "PlaybackError.RateLimitExceeded": "Ez a tartalom jelenleg nem játszható adatkorlát miatt.", + "ViewLyrics": "Dalszövegek megtekintése", + "EnableVideoToolboxTonemapping": "VideoToolbox tónusleképzés engedélyezése", + "AllowVideoToolboxTonemappingHelp": "Hardveresen gyorsított tónusleképzés a VideoToolbox-tól. Képes a HDR10, HDR10+ és HLG formátumok dekódolására, de nem támogatja a Dolby Vision Profile 5-öt. Ez magasabb prioritású más Metal implementációkhoz képest.", + "PriorityAboveNormal": "Normális feletti", + "PriorityNormal": "Normális", + "PriorityBelowNormal": "Normális alatti", + "PriorityIdle": "Üresjárat", + "EnableLibrary": "Könyvtár engedélyezése", + "EnableLibraryHelp": "Könyvtár tiltása, miközben rejtve marad az összes felhasználó elől.", + "LabelProcessPriority": "Folyamat prioritása", + "EnableSmoothScroll": "Folyékony görgetés engedélyezése", + "LabelAllowContentWithTags": "Engedje a címkézett elemeket", + "LimitSupportedVideoResolution": "Korlátozza a maximális támogatott videó felbontást", + "PlaybackError.ASS_RENDER_ERROR": "Hiba történt az ASS/SSA feliratok renderelésekor.", + "PlaybackError.FATAL_HLS_ERROR": "Végzetes hiba jelentkezett a HLS stream-ben.", + "LabelTrickplayAccel": "Hardveres dekódolás engedélyezése", + "NonBlockingScan": "Nem blokkoló - beütemezi a generálást, majd visszatér", + "LabelScanBehavior": "Tartalom keresési magatartás", + "ConfirmDeleteSeries": "A sorozat törlésével törlődni fog az ÖSSZES {0} epizód a fájlrendszerből és a médiakönyvtárból is. Biztosan folytatni akarod?", + "LabelQscaleHelp": "Az ffmpeg kimeneti képkockák minőségskálája, melyen 2 a legmagasabb és 31 a legalacsonyabb minőségi érték.", + "LabelTrickplayThreads": "FFmpeg szálak", + "LabelWidthResolutions": "Horizontális felbontás", + "ExtractTrickplayImagesHelp": "A lejátszástrükk képkockák hasonlóak a fejezetképekhez, de a tartalom teljes hosszában generálódnak hogy aztán a videó tekerésekor megjelenjenek az idővonalon előnézeteként.", + "LabelProcessPriorityHelp": "Ennek az alacsonyabbra vagy magasabbra állításával szabályozható, hogy a processzoron az ffmpeg lejátszástrükk generálás folyamata milyen prioritással fusson más folyamatokhoz képest. Ha lassulást tapasztal lejátszástrükk generálás közben, de nem akarja leállítani a folyamatot, próbálja meg csökkenteni a prioritást és a használt processzor szálak számát.", + "LabelImageInterval": "Kép intervallum", + "LabelTileWidth": "Csempe szélesség", + "LabelTileHeight": "Csempe magasság", + "LabelTileWidthHelp": "Csempén elhelyezkedő képek maximális száma vízszintesen.", + "LabelImageIntervalHelp": "Időintervallum (ms) lejátszástrükk képkockák között.", + "LabelJpegQuality": "JPEG minőség", + "LabelWidthResolutionsHelp": "A generálandó lejátszástrükk képkockák szélességének (px) vesszővel elválasztott listája. Minden képkocka a forrás képarányával arányos, így egy 320 széles 16:9 arányú képkocka felbontása körülbelül 320x180 lesz.", + "LabelJpegQualityHelp": "Lejátszástrükk képkockák JPEG tömörítési minősége.", + "LabelQscale": "Qskála", + "LabelTileHeightHelp": "Csempén elhelyezkedő képek maximális száma függőlegesen.", + "LabelTrickplayThreadsHelp": "Az ffmpeg '-threads' argumentumának átadandó szálak száma.", + "OptionExtractTrickplayImage": "Lejátszástrükk képkockák kinyerésének engedélyezése", + "LabelExtractTrickplayDuringLibraryScan": "Lejátszástrükk képkockák kinyerése a könyvtár beolvasásakor", + "LabelExtractTrickplayDuringLibraryScanHelp": "Lejátszástrükk képkockák generálása könyvtár beolvasáskor a frissen importált videóknál. Ha nincs bekapcsolva, a lejátszástrükk képkockákat az erre ütemezett feladat fogja kinyerni. Nem blokkoló magatartás esetén ez nem befolyásolja a könyvtár beolvasás idejét." } diff --git a/src/strings/id.json b/src/strings/id.json index fef3296620..dc048bc640 100644 --- a/src/strings/id.json +++ b/src/strings/id.json @@ -915,11 +915,11 @@ "MinutesAfter": "Menit Setelah", "MetadataManager": "Manajer Metadata", "Metadata": "Metadata", - "MessageSyncPlayErrorMedia": "Gagal Mengaktifkan SyncPlay! Media Error cok.", + "MessageSyncPlayErrorMedia": "Gagal Mengaktifkan SyncPlay! Media Error.", "MessageSyncPlayErrorMissingSession": "SyncPlay gagal! Sesi Hilang njir...", "MessageSyncPlayErrorNoActivePlayer": "SyncPlay dimatikan. Tidak ada pemutar aktif.", "MessageSyncPlayErrorAccessingGroups": "Muncul Error ketika mengakses list grup.", - "MessageSyncPlayLibraryAccessDenied": "Akses konten ini Dibatasi cok.", + "MessageSyncPlayLibraryAccessDenied": "Akses konten ini Dibatasi.", "MessageSyncPlayJoinGroupDenied": "Tidak dapat bergabung dengan grup.", "MessageSyncPlayCreateGroupDenied": "ijin diperlukan untuk membuat grup.", "MessageSyncPlayGroupDoesNotExist": "Gagal bergabung dengan grup karena tidak ada njing!.", @@ -1681,5 +1681,7 @@ "AllowCollectionManagement": "Izinkan pengguna ini untuk mengatur koleksi", "AllowSegmentDeletion": "Hapus segmen", "LabelThrottleDelaySeconds": "Batasi setelah", - "LabelSegmentKeepSeconds": "" + "LabelSegmentKeepSeconds": "Waktu untuk menetapkan segmen", + "AllowSubtitleManagement": "Izinkan user untuk mengubah tarakir", + "AllowSegmentDeletionHelp": "Hapus bagian lama setelah terunduh oleh pengguna. Fitur ini akan mencegah penyimpanan file teralihsandikan ke dalam penyimpanan. Matikan fitur ini jika terjadi masalah dalam pemutaran." } diff --git a/src/strings/it.json b/src/strings/it.json index 40c814541e..58b1d9fc67 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -1264,7 +1264,7 @@ "ListPaging": "{0}-{1} di {2}", "WriteAccessRequired": "Jellyfin richiede il permesso di scrittura su questa cartella. Verificare l'autorizzazione e riprovare.", "PathNotFound": "Percorso non trovato. Assicurarsi che sia valido e riprovare.", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "Season": "Stagione", "Movie": "Film", "LabelLibraryPageSizeHelp": "Numero di elementi presenti nella paginazione della libreria. Il valore 0 disabilita la paginazione.", @@ -1369,7 +1369,7 @@ "Image": "Immagine", "Other": "Altro", "Data": "Dati", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "UseDoubleRateDeinterlacing": "Raddoppia il frame rate durante il deinterlacciamento", "KnownProxiesHelp": "Lista degli IP o hostname separati da virgola dei proxy utilizzati per connettersi a Jellyfin. Ciò consente di gestire al meglio gli header 'X-Forwarded-For'. Richiede il riavvio dopo il salvataggio.", "LabelKnownProxies": "Proxy conosciuti", @@ -1867,5 +1867,23 @@ "HeaderDeleteLyrics": "Cancella Testi", "HeaderNoLyrics": "Nessun testo trovato", "Lyrics": "Testi", - "ViewLyrics": "Visualizza testi" + "ViewLyrics": "Visualizza testi", + "PlaylistError.AddFailed": "Errore nell'aggiunta alla playlist", + "PlaylistError.CreateFailed": "Errore nella creazione della playlist", + "SavePassword": "Salva Password", + "Author": "Autore", + "Creator": "Creatore", + "Editor": "Editore", + "Illustrator": "Illustratore", + "Letterer": "Paroliere", + "SaveLyricsIntoMediaFolders": "Salva le liriche nella cartella dei media", + "Translator": "Traduttore", + "EnableDts": "Abilita DTS (DCA)", + "EnableDtsHelp": "Abilitare solo se il device supporta DTS o se connesso a un ricevitore audio compatibile, altrimenti può causare errori di riproduzione.", + "EnableTrueHd": "Abilita TrueHD", + "EnableTrueHdHelp": "Abilita solo se il device supporta TrueHD o se connesso a un ricevitore audio compatibile, altrimenti può causare errori di riproduzione.", + "HeaderVideoAdvanced": "Avanzate Video", + "PlaylistPublic": "Consenti accesso pubblico", + "PlaylistPublicDescription": "Consenti che questa playlist sia visibile ad ogni utente loggato.", + "HeaderLyricDownloads": "Downloads Liriche" } diff --git a/src/strings/ja.json b/src/strings/ja.json index 46f5e3202a..b9cf409cb1 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -190,7 +190,7 @@ "ColorTransfer": "Color transfer", "DeathDateValue": "死亡日:{0}", "Depressed": "陰鬱", - "ErrorAddingListingsToSchedulesDirect": "Schedules Directのアカウントにラインナップを追加中にエラーが発生しました。 スケジュールダイレクトでは、アカウントごとに限られた数のラインナップしか許可されません。続けるには、Schedules Direct にログインしてアカウントから他のリストを削除する必要があります。", + "ErrorAddingListingsToSchedulesDirect": "Schedules Direct のアカウントにラインナップを追加中にエラーが発生しました。Schedules Direct では、アカウントごとに限られた数のラインナップしか許可されません。続けるには、Schedules Direct にログインしてアカウントから他のリストを削除する必要があります。", "ErrorAddingMediaPathToVirtualFolder": "メディアパスの追加中にエラーが発生しました。 パスが有効で、Jellyfin がその場所にアクセスできることを確認してください。", "ErrorAddingTunerDevice": "チューナーデバイスの追加中にエラーが発生しました。 アクセス可能であることを確認して、もう一度やり直してください。", "ErrorAddingXmlTvFile": "XMLTV ファイルへのアクセス中にエラーが発生しました。 ファイルが存在することを確認して、やり直してください。", @@ -227,7 +227,7 @@ "Guide": "ガイド", "GuideProviderLogin": "ログイン", "GuideProviderSelectListings": "リストを選択", - "H264CrfHelp": "Constant Rate Factor」(CRF)は、x264 および x265 エンコーダのデフォルトの品質設定です。0 から 51 の間で値を設定することができ、低い値はより良い品質となります(より高いファイルサイズを犠牲にして)。正常な値は18と28の間です。x264のデフォルトは23、x265のデフォルトは28なので、これを出発点として使用することができます。", + "H264CrfHelp": "「Constant Rate Factor」(CRF)は、x264 および x265 ソフトウェアエンコーダのデフォルトの品質設定です。0 から 51 の間で値を設定することができ、低い値はより良い品質となります(より高いファイルサイズを犠牲にして)。正常な値は18と28の間です。x264のデフォルトは23、x265のデフォルトは28なので、これを出発点として使用することができます。ハードウェアエンコーダーはこれらの設定を使用しません。", "EncoderPresetHelp": "パフォーマンスを向上させるには小さい値を、品質を向上させるには大きい値を選んでください。", "HDPrograms": "HD番組", "HardwareAccelerationWarning": "ハードウェアアクセラレーションを有効にすると、環境によっては不安定になる可能性があります。 オペレーティングシステムとビデオドライバが完全に最新であることを確認してください。 これを有効にした後でビデオの再生が困難な場合は、設定を[なし]に戻す必要があります。", @@ -713,7 +713,7 @@ "LabelAlbumArtists": "アルバムアーティスト", "LabelAllowHWTranscoding": "ハードウェアトランスコーディングを許可", "LabelAllowedRemoteAddresses": "リモートIPアドレスフィルター", - "LabelAppNameExample": "例: スケートボード、ソナー", + "LabelAppNameExample": "API キーを識別するための人が判読できる名前。この設定は機能には影響しません。", "LabelArtists": "アーティスト", "LabelAudioBitDepth": "音声ビット深度", "LabelAudioBitrate": "音声ビットレート", @@ -1387,7 +1387,7 @@ "LabelTonemappingRange": "トーンマッピングの範囲", "TonemappingAlgorithmHelp": "トーンマッピングは微調整が可能です。これらのオプションに慣れていない場合は、デフォルトのままにしておいてください。推奨値は'BT.2390'です。", "LabelTonemappingAlgorithm": "使用するトーンマッピング アルゴリズムを選択", - "AllowTonemappingHelp": "トーンマッピングは、元のシーンを表現するのに非常に重要な情報である画像のディテールや色を維持したまま、映像のダイナミックレンジを HDR から SDR に変換することができます。現在、10 ビット HDR、HLG と DoVi ビデオでのみ動作します。対応する OpenCL または CUDA ランタイムが必須です。", + "AllowTonemappingHelp": "トーンマッピングは、元のシーンを表現するのに非常に重要な情報である画像のディテールや色を維持したまま、映像のダイナミックレンジを HDR から SDR に変換することができます。現在、10 ビット HDR、HLG と DoVi ビデオでのみ動作します。対応する GPGPU ランタイムが必須です。", "EnableTonemapping": "トーンマッピングを有効化", "LabelOpenclDeviceHelp": "これはトーンマッピングに使用する OpenCL デバイスです。ドットの左側がプラットフォーム番号、右側がプラットフォーム上のデバイス番号となります。デフォルト値は 0.0。FFmpeg アプリケーションファイルは OpenCL ハードウェアアクセラレーションメソッドを含む必要があります。", "LabelOpenclDevice": "OpenCL デバイス", @@ -1415,8 +1415,8 @@ "ListPaging": "{2} 中の {0}-{1}", "WriteAccessRequired": "Jellyfin はこのフォルダへの書き込み権限を要求します。書き込みアクセスを確認してもう一度お試しください。", "PathNotFound": "パスを見つけることができませんでした。パスが有効であることを確認してもう一度お試しください。", - "Bwdif": "BWDIF", - "Yadif": "YADIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "XmlTvSportsCategoriesHelp": "これらのカテゴリの番組はスポーツ番組として表示されます。複数の場合は '|' で区切ってください。", "XmlTvPathHelp": "XMLTV ファイルのパス。Jellyfin はこのファイルを読み込んで定期的に更新を確認します。ファイルの作成と更新はあなたが責任を持って行ってください。", "XmlTvNewsCategoriesHelp": "これらのカテゴリの番組はニュース番組として表示されます。複数の場合は '|' で区切ってください。", @@ -1748,7 +1748,7 @@ "Unknown": "不明", "AllowCollectionManagement": "このユーザーにコレクションの管理を許可する", "AllowSegmentDeletion": "セグメントを削除", - "AllowSegmentDeletionHelp": "クライアントに送信した古いセグメントを削除します。トランスコードしたファイル全体をディスクに保存しておくことはできなくなります。「スロットル」が有効の場合にのみ動作します。再生に問題が起きたら、オフにしてください。", + "AllowSegmentDeletionHelp": "クライアントによりダウンロードされた古いセグメントを削除します。トランスコードしたファイル全体をディスクに保存しておくことはできなくなります。再生に問題が起きたら、オフにしてください。", "LabelThrottleDelaySeconds": "スロットルまでの時間", "LabelThrottleDelaySecondsHelp": "「スロットル」を行うまでの秒数。クライアントが安定して再生できるバッファーを維持するのに十分大きなサイズでなければなりません。「スロットル」が有効の場合にのみ動作します。", "LabelSegmentKeepSeconds": "セグメントの保存時間", @@ -1783,5 +1783,89 @@ "LabelWebVersion": "ウェブバージョン", "LabelTrackGain": "トラックゲイン", "ForeignPartsOnly": "強制/外国語パートのみ", - "HeaderGuestCast": "ゲストスター" + "HeaderGuestCast": "ゲストスター", + "AirPlay": "AirPlay", + "ChannelResolutionSD": "SD", + "LabelEncodingFormatOptions": "エンコーディングフォーマットのオプション", + "AllowSubtitleManagement": "このユーザーに字幕の編集を許可する", + "AllowContentWithTagsHelp": "指定したタグのうち、少なくとも1つが付けられているメディアのみ表示します。", + "EncodingFormatHelp": "Jellyfinがトランスコードする際の動画エンコーディングを選択してください。選択したフォーマットのハードウェアアクセラレーションが利用できない場合、Jellyfinはソフトウェアエンコーディングを使用します。H264エンコーディングは常に有効になります。", + "LabelTrickplayAccelEncoding": "ハードウェアアクセラレーションを使用したMJPEGエンコーディングを有効にする", + "LimitSupportedVideoResolution": "最大対応動画解像度を制限する", + "SavePassword": "パスワードを保存", + "LabelJpegQuality": "JPEG の品質", + "LabelAllowContentWithTags": "タグ付きのアイテムを許可する", + "PlaybackError.FATAL_HLS_ERROR": "HLSストリームで致命的なエラーが発生しました。", + "PlaybackError.PLAYER_ERROR": "プレーヤーの致命的なエラーにより、再生に失敗しました。", + "PlaybackError.SERVER_ERROR": "サーバーエラーにより、再生に失敗しました。", + "PlaybackError.NotAllowed": "このメディアの再生は許可されていません。", + "LabelScanBehavior": "スキャンの動作", + "OptionExtractTrickplayImage": "トリックプレイ画像の抽出を有効にする", + "EnableLibrary": "ライブラリーを有効にする", + "EnableSmoothScroll": "スムーズスクロールを有効にする", + "PlaybackError.ASS_RENDER_ERROR": "ASS/SSA字幕レンダラーでエラーが発生しました。", + "AllowVideoToolboxTonemappingHelp": "VideoToolboxによるハードウェアアクセラレーションを使用したトーンマッピングです。これは、HDR10、HDR10+、HLGなどのほとんどのHDRフォーマットで動作しますが、Dolby Vision Profile 5では動作しません。これは、他のMetal実装と比較して優先度が高くなっています。", + "LabelImageIntervalHelp": "新しいトリックプレイ画像が生成される時間間隔(ミリ秒)です。", + "ConfirmDeleteLyrics": "これらの歌詞を削除すると、ファイルシステムとメディアライブラリーの両方から削除されます。本当に続行しますか?", + "DeleteEntireSeries": "{0} つのエピソードを削除", + "DeleteLyrics": "歌詞を削除", + "DeleteEpisode": "エピソードを削除", + "DlnaMovedMessage": "DLNA機能がプラグインに移行されました。", + "ErrorDeletingLyrics": "サーバーから歌詞を削除する際にエラーが発生しました。Jellyfinがメディアフォルダへの書き込み権限を持っていることを確認して、もう一度お試しください。", + "HeaderNoLyrics": "歌詞が見つかりません", + "LimitSupportedVideoResolutionHelp": "「許可された最大動画トランスコード解像度」を最大対応動画解像度として使用します。", + "Lyrics": "歌詞", + "PlaybackError.MEDIA_DECODE_ERROR": "メディアのデコード中にエラーが発生したため、再生に失敗しました。", + "PlaybackError.MEDIA_NOT_SUPPORTED": "クライアントがこのメディアをサポートしていないため、再生に失敗しました。", + "PlaybackError.NETWORK_ERROR": "ネットワークエラーのため、再生に失敗しました。", + "PlaybackError.NO_MEDIA_ERROR": "再生できる有効なメディアソースが見つかりません。", + "ViewLyrics": "歌詞を表示", + "LabelTrickplayAccel": "ハードウェアデコーディングを有効にする", + "LabelTrickplayAccelEncodingHelp": "現在、QSVとVAAPIでのみ利用可能です。このオプションは、他のハードウェアアクセラレーション方式には影響しません。", + "LabelQscaleHelp": "ffmpeg で出力される画像のクオリティスケールで、2が最高品質、31が最低品質となります。", + "LabelTrickplayThreads": "FFmpeg のスレッド数", + "ExtractTrickplayImagesHelp": "トリックプレイ画像は、チャプター画像に似ていますが、コンテンツの全体にわたって使用され、ビデオをスクラブしているときにプレビューを表示するために使用されます。", + "LabelExtractTrickplayDuringLibraryScan": "ライブラリスキャン中にトリックプレイ画像を抽出する", + "Lyric": "歌詞", + "BlockContentWithTagsHelp": "指定したタグの少なくとも1つがあるメディアを隠します。", + "ChannelResolutionHD": "HD", + "ChannelResolutionFullHD": "Full HD", + "ChannelResolutionSDPAL": "SD (PAL)", + "DeleteName": "{0} を削除", + "ChannelResolutionUHD4K": "UHD (4K)", + "Colorist": "カラリスト", + "CoverArtist": "カバーアーティスト", + "HeaderDeleteSeries": "シリーズを削除", + "ConfirmDeleteSeries": "このシリーズを削除すると、システムとメディアライブラリーの両方から {0} エピソード「すべて」を削除することになります。本当に続行してもいいですか?", + "EnableLibraryHelp": "ライブラリーを無効化すると、すべてのユーザービューからライブラリーが非表示になります。", + "EnableDts": "DTS (DCA) を有効化", + "EnableDtsHelp": "デバイスが DTS をサポートしているか、互換性のある音声レシーバーに接続している場合にも見有効化してください。そうでなければ、再生が失敗する可能性があります。", + "EnableTrueHd": "TrueHD を有効化", + "EnableTrueHdHelp": "TrueHD をサポートするデバイスか、互換性のある音声レシーバーと接続した場合にのみ有効化してください。そうでなければ、再生が失敗する可能性があります。", + "HeaderDeleteLyrics": "歌詞を削除", + "DeleteSeries": "シリーズを削除", + "LabelProcessPriority": "プロセスの優先度", + "Author": "作者", + "Creator": "クリエイター", + "Editor": "編集者", + "Illustrator": "イラストレーター", + "Translator": "翻訳者", + "PriorityNormal": "普通", + "LabelTileWidth": "タイルの幅", + "LabelTileHeight": "タイルの高さ", + "PriorityIdle": "アイドル中", + "PlaybackError.RateLimitExceeded": "レート制限のため、現在このメディアは再生できません。", + "PriorityBelowNormal": "普通以下", + "PriorityAboveNormal": "普通以上", + "LabelImageInterval": "画像インターバル", + "PriorityHigh": "高", + "LabelTileWidthHelp": "X 方向のタイルあたりの画像の最大数。", + "LabelTileHeightHelp": "Y 方向のタイルあたりの画像の最大数。", + "LabelTrickplayThreadsHelp": "ffmpeg の「-threads」引数に渡すスレッドの数。", + "PlaylistPublic": "パブリックアクセスを許可", + "PlaylistPublicDescription": "ログインしているすべてのユーザーがこのプレイリストを閲覧できるようにします。", + "HeaderLyricDownloads": "歌詞のダウンロード", + "SaveLyricsIntoMediaFolders": "歌詞をメディアフォルダーに保存", + "SaveLyricsIntoMediaFoldersHelp": "歌詞をオーディオファイルの隣に保存すると、歌詞の管理がより簡単になります。", + "LabelWidthResolutions": "横の解像度" } diff --git a/src/strings/ka.json b/src/strings/ka.json index c53b230909..0905f2b261 100644 --- a/src/strings/ka.json +++ b/src/strings/ka.json @@ -51,5 +51,100 @@ "LabelThrottleDelaySecondsHelp": "წამთა ოდენობა, რის შემდეგაც ტრანსკოდირება იქნება შეფერხებული. უნდა იყოს საკმარისად ხანგრძლივი, იმისთვის რომ, კლიენტმა შეინარჩუნოს ჯანსაღი ბუფერი. მუშაობს მხოლოდ მაშინ, როდესაც შეფერხების ფუნქცია ჩართულია.", "LabelSegmentKeepSeconds": "მითითებული დროის განმავლობაში მონაკვეთები შეინახება", "AirPlay": "ეარფლეი", - "LabelThrottleDelaySeconds": "შემდეგ" + "LabelThrottleDelaySeconds": "შემდეგ", + "Audio": "აუდიო", + "AllowRemoteAccessHelp": "თუ არარის მონიშნული, ყველა გარე კავშირი დაიბლოკება.", + "AllowMediaConversionHelp": "მედიის კონვერტაციის უფლების მიცემა ან ჩამორთმევა.", + "AspectRatio": "ასპექტის თანაფარდობა", + "Auto": "ავტომატური", + "ButtonAddServer": "სერვერის დამატება", + "AllowOnTheFlySubtitleExtraction": "სუბტიტრების პროცესში ამოღების დაშვება", + "ButtonUninstall": "წაშლა", + "AllowMediaConversion": "მედიის კონვერტაციის დაშვება", + "AnyLanguage": "ნებისმიერი ენა", + "BlockContentWithTagsHelp": "ისეთი მედიის დამალვა, რომელსაც გააჩნია არჩეულებიდან ერთი თეგი მაინც.", + "ButtonParentalControl": "მშობლის კონტროლი", + "ChannelResolutionUHD4K": "UHD (4K)", + "AllowRemoteAccess": "ამ სერვერზე გარე კავშირების დაშვება", + "Artist": "მსახიობი", + "ButtonAddScheduledTaskTrigger": "ტრიგერის დამატება", + "ButtonRefreshGuideData": "გაიდის დატის გადატვირთვა", + "ButtonRename": "გადარქმევა", + "ChannelNameOnly": "მხოლოდ არხი {0}", + "ChannelNumber": "არხის ნომერი", + "Author": "ავტორი", + "Blacklist": "შავი სია", + "ButtonActivate": "აქტივაცია", + "ButtonAddMediaLibrary": "მედიის ბიბლიოთეკის დამატება", + "ButtonArrowLeft": "მარცხნივ", + "ButtonArrowRight": "მარჯვნივ", + "ButtonEditUser": "იუზერის რედაქტირება", + "ButtonForgotPassword": "პაროლი დამავიწყდა", + "ButtonPlayer": "ფლეერი", + "ButtonResume": "გაგრძელება", + "ButtonRevoke": "წართმევა", + "ButtonSelectView": "ხედვის არჩევა", + "ButtonSend": "გაგზავნა", + "ButtonStart": "დაწყება", + "CancelRecording": "ჩაწერვის გაუქმება", + "Categories": "კატეგორიები", + "ChannelResolutionFullHD": "Full HD", + "ClearQueue": "რიგის გასუფთავება", + "ClientSettings": "კლიენტის პარამეტრები", + "CommunityRating": "საზოგადოების რეიტინგი", + "Composer": "კომპოზიტორი", + "Conductor": "დირიჟორი", + "AlwaysPlaySubtitles": "ყოველთვის დაკვრა", + "AlwaysPlaySubtitlesHelp": "სუბტიტრები ჩაიტვირთება ენის პარამეტრის მიხედვით, აუდიოს ენის მიუხედავად.", + "Anytime": "ნებისმიერ დროს", + "ApiKeysCaption": "ამჟამად ჩართული API გასაღებთა სია", + "AroundTime": "დაახლოებით {0}", + "Arranger": "დამხარისხებელი", + "Ascending": "ზრდადი", + "AskAdminToCreateLibrary": "ბიბლიოთეკის შექმნისათვის, თხოვეთ ადმინისტრატორს.", + "AsManyAsPossible": "რაც შეიძლება მეტი", + "Authorize": "ნების დართვა", + "AuthProviderHelp": "აირჩიეთ აუტენთიფიკატორი რომელიც იქნება გამოყენებული იუზერის პაროლის აუტენთიფიკაციის დროს.", + "Banner": "ბანერი", + "BirthDateValue": "დაიბადა: {0}", + "BirthLocation": "დაბადების ადგილი", + "BirthPlaceValue": "დაბადების ადგილი: {0}", + "ButtonAddImage": "სურათის დამატება", + "ButtonAddUser": "იუზერის დამატება", + "ButtonAudioTracks": "აუდიო ხაზები", + "ButtonBack": "უკან", + "ButtonCancel": "გაუქმება", + "ButtonChangeServer": "სერვერის ცვლილება", + "ButtonEditOtherUserPreferences": "შეცვალეთ ამ იუზერის პროფილი, სურათი და პირადი პარამეტრები.", + "ButtonGotIt": "გასაგებია", + "ButtonInfo": "ინფო", + "ButtonManualLogin": "ხელით დალოგინება", + "ButtonMore": "კიდე", + "ButtonPause": "პაუზა", + "ButtonQuickStartGuide": "სწრაფი სტარტის გაიდი", + "ButtonRemove": "ამოღება", + "ButtonSignOut": "გამოსვლა", + "ButtonExitApp": "აპლიკაციის დახურვა", + "ButtonSpace": "სფეისი", + "ButtonSplit": "გახლეჩვა", + "ButtonTogglePlaylist": "ფლეილისთი", + "ButtonTrailer": "ტრეილერი", + "CancelSeries": "სერიალის გაუქმება", + "ButtonClose": "დახურვა", + "ButtonFullscreen": "მთელ ეკრანზე", + "ButtonScanAllLibraries": "ყველა ბიბლიოთეკის სკანირება", + "ButtonSelectDirectory": "დირექტორიის არჩევა", + "ButtonSubmit": "გაგზავნა", + "ButtonLibraryAccess": "წვდომა ბიბლიოთეკაზე", + "ButtonNextTrack": "შემდეგი თრექი", + "ButtonOk": "ოკ", + "ButtonPreviousTrack": "წინა თრექი", + "ButtonShutdown": "გამორთვა", + "ButtonSignIn": "შესვლა", + "ButtonStop": "გაჩერება", + "ButtonUseQuickConnect": "Quick Connect-ის გამოყენება", + "ButtonWebsite": "ვებსაიტი", + "ChannelResolutionHD": "HD", + "ChannelResolutionSD": "SD", + "ChannelResolutionSDPAL": "SD (PAL)" } diff --git a/src/strings/mt.json b/src/strings/mt.json index d00dc1217b..288b22613f 100644 --- a/src/strings/mt.json +++ b/src/strings/mt.json @@ -6,17 +6,44 @@ "AllEpisodes": "L-episodji kollha", "AllLanguages": "Il-lingwi kollha", "AllLibraries": "Il-libreriji kollha", - "AccessRestrictedTryAgainLater": "Bħalissa l-aċċess huwa ristrett. Jekk jogħgbok erġa' prova iktar tard.", + "AccessRestrictedTryAgainLater": "L-aċċess bħalissa huwa ristrett. Jekk jogħgbok erġa' pprova aktar tard.", "Actor": "Attur", "Add": "Żid", - "AddedOnValue": "{0} Miżjuda", + "AddedOnValue": "{0} miżjud", "AddToCollection": "Żid fil-kollezzjoni", "AddToFavorites": "Żid fil-lista tal-favoriti", "AgeValue": "({0} snin)", "AirDate": "Data tax-xandir", "Aired": "Imxandar", "Albums": "Albums", - "All": "Kollox", + "All": "Kollha", "AllChannels": "L-istazzjonijiet kollha", - "AllComplexFormats": "Il-formats ikkumplikati kollha (ASS, SSA, VobSub, PGS, SUB, IDX, …)" + "AllComplexFormats": "Il-formats kumplessi kollha (ASS, SSA, VobSub, PGS, SUB, IDX, …)", + "AirPlay": "AirPlay", + "Alerts": "Twissijiet", + "AlbumArtist": "Artist tal-Album", + "AllowedRemoteAddressesHelp": "Lista separata b'virgola ta' indirizzi IP jew entrati ta' IP/netmask għal netwerks li se jitħallew jikkonnettjaw remotament. Jekk titħalla vojta, l-indirizzi remoti kollha jkunu permessi.", + "AllowCollectionManagement": "Ħalli lil dan l-utent jimmaniġġja l-kollezzjonijiet", + "AllowContentWithTagsHelp": "Uri biss midja b'mill-inqas waħda mit-tags speċifikati.", + "AllowSubtitleManagement": "Ħalli lil dan l-utent jeditja s-sottotitli", + "Artists": "Artisti", + "Collections": "Kollezzjonijiet", + "Genres": "Ġeneri", + "HeaderContinueWatching": "Kompli Segwi", + "Favorites": "Favoriti", + "Books": "Kotba", + "Channels": "Kanali", + "HeaderAlbumArtists": "Artisti tal-album", + "AllowSegmentDeletionHelp": "Ħassar segmenti qodma wara li jkunu ġew imniżżla mill-klijent. Dan jipprevjeni li jkollu jaħżen il-fajl kollu transkodifikat fuq disk. Itfi din jekk ikollok problemi ta' daqq.", + "AllowSegmentDeletion": "Ħassar segmenti", + "LabelSegmentKeepSeconds": "Żmien li żżomm is-segmenti", + "Shows": "Programmi", + "Default": "Standard", + "Playlists": "Playlists", + "Folders": "Folders", + "Photos": "Ritratti", + "Songs": "Kanzunetti", + "Movies": "Films", + "MusicVideos": "Vidjows tal-Mużika", + "ValueSpecialEpisodeName": "Speċjali - {0}" } diff --git a/src/strings/nl.json b/src/strings/nl.json index 0a99698043..0bc93e6776 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -410,7 +410,7 @@ "LabelAllowedRemoteAddresses": "Filter externe IP-adressen", "LabelAllowedRemoteAddressesMode": "Filtermodus externe IP-adressen", "LabelAppName": "Applicatienaam", - "LabelAppNameExample": "Voorbeeld: Sickbeard, Sonarr", + "LabelAppNameExample": "Een leesbare naam om de API-sleutel te herkennen. Deze instelling heeft geen invloed op de functionaliteit.", "LabelArtists": "Artiesten", "LabelArtistsHelp": "Scheid meerdere artiesten met een puntkomma.", "LabelAudioLanguagePreference": "Voorkeurstaal geluid", @@ -481,7 +481,7 @@ "LabelEnableDlnaServerHelp": "Sta UPnP-apparaten op je netwerk toe om door inhoud te bladeren en deze af te spelen.", "LabelEnableHardwareDecodingFor": "Hardwaredecodering inschakelen voor", "LabelEnableRealtimeMonitor": "Real-time monitoring inschakelen", - "LabelEnableRealtimeMonitorHelp": "Wijzigingen aan bestanden worden op ondersteunde bestandssystemen direct verwerkt.", + "LabelEnableRealtimeMonitorHelp": "Op ondersteunde bestandssystemen worden wijzigingen aan bestanden direct verwerkt.", "LabelEnableSingleImageInDidlLimit": "Beperken tot een enkele ingesloten afbeelding", "LabelEnableSingleImageInDidlLimitHelp": "Sommige apparaten zullen niet goed weergeven als er meerdere afbeeldingen ingesloten zijn in DIDL.", "LabelEndDate": "Einddatum", @@ -637,8 +637,8 @@ "LabelServerHost": "Host", "LabelServerHostHelp": "192.168.1.100:8096 of https://mijnserver.nl", "LabelSimultaneousConnectionLimit": "Limiet gelijktijdige streams", - "LabelSkipBackLength": "Terugspoellengte", - "LabelSkipForwardLength": "Vooruitspoellengte", + "LabelSkipBackLength": "Stapgrootte terugspringen", + "LabelSkipForwardLength": "Stapgrootte vooruitspringen", "LabelSkipIfAudioTrackPresent": "Overslaan als het standaard geluidsspoor overeenkomt met de taal van de download", "LabelSkipIfAudioTrackPresentHelp": "Vink dit uit om ervoor te zorgen dat alle video's ondertiteling krijgen, ongeacht de geluidstaal.", "LabelSkipIfGraphicalSubsPresent": "Overslaan als de video al ingesloten ondertiteling heeft", @@ -649,7 +649,7 @@ "LabelSortOrder": "Sorteervolgorde", "LabelSortTitle": "Sorteertitel", "LabelSource": "Bron", - "LabelSpecialSeasonsDisplayName": "Weergavenaam speciaal seizoen", + "LabelSpecialSeasonsDisplayName": "Weergavenaam specials-seizoen", "LabelSportsCategories": "Sportcategorieën", "LabelStartWhenPossible": "Starten indien mogelijk", "LabelStopWhenPossible": "Stoppen indien mogelijk", @@ -917,7 +917,7 @@ "PleaseSelectTwoItems": "Selecteer ten minste twee items.", "MessagePluginInstalled": "De plug-in is succesvol geïnstalleerd. De server moet opnieuw worden opgestart om de wijzigingen door te voeren.", "PreferEmbeddedTitlesOverFileNames": "Ingesloten titels boven bestandsnamen verkiezen", - "PreferEmbeddedTitlesOverFileNamesHelp": "Bepaal de standaard weergavetitel wanneer er geen internetmetadata of lokale metadata beschikbaar is.", + "PreferEmbeddedTitlesOverFileNamesHelp": "Bepaal de standaard weergavetitel wanneer er geen internetmetadata of lokale metadata beschikbaar zijn.", "Premieres": "Premières", "Previous": "Vorige", "Primary": "Primair", @@ -990,7 +990,7 @@ "Shows": "Series", "Shuffle": "Willekeurig", "SimultaneousConnectionLimitHelp": "Het maximum aantal toegestane gelijktijdige streams. Geef 0 in voor geen limiet.", - "SkipEpisodesAlreadyInMyLibrary": "Neem geen afleveringen op die al in mijn bibliotheek aanwezig zijn", + "SkipEpisodesAlreadyInMyLibrary": "Geen afleveringen opnemen die al in mijn bibliotheek staan", "SkipEpisodesAlreadyInMyLibraryHelp": "Afleveringen zullen worden vergeleken met behulp van seizoens- en afleveringsnummers, indien beschikbaar.", "Small": "Klein", "SmallCaps": "Kleine letters", @@ -1072,7 +1072,7 @@ "ValueTimeLimitSingleHour": "Tijdslimiet: 1 uur", "Vertical": "Verticaal", "ViewAlbum": "Album weergeven", - "ViewPlaybackInfo": "Afspeelinfo weergeven", + "ViewPlaybackInfo": "Afspeelinformatie weergeven", "Watched": "Gekeken", "Wednesday": "Woensdag", "WelcomeToProject": "Welkom bij Jellyfin!", @@ -1157,7 +1157,7 @@ "OptionResElement": "'res'-element", "TV": "Tv", "LabelTypeMetadataDownloaders": "Metadata-downloaders ({0})", - "OptionLoginAttemptsBeforeLockout": "Bepaal hoeveel foutieve inlogpogingen kunnen plaatsvinden voordat de gebruiker buitengesloten wordt.", + "OptionLoginAttemptsBeforeLockout": "Bepaal hoeveel foutieve aanmeldpogingen kunnen plaatsvinden voordat de gebruiker buitengesloten wordt.", "Premiere": "Première", "TabPlugins": "Plug-ins", "LabelAudioSampleRate": "Bemonsteringsfrequentie geluid", @@ -1173,7 +1173,7 @@ "MusicLibraryHelp": "Bekijk de {0}muzieknaamgevingsgids{1}.", "LabelAudioBitDepth": "Bitdiepte geluid", "OptionRandom": "Willekeurig", - "PlaybackData": "Afspeelinfo", + "PlaybackData": "Afspeelinformatie", "PasswordResetProviderHelp": "Kies een aanbieder voor wachtwoordherstel die moet worden gebruikt wanneer deze gebruiker een wachtwoordherstel aanvraagt.", "Screenshots": "Schermafdruk", "Series": "Series", @@ -1237,7 +1237,7 @@ "BoxSet": "Boxset", "AskAdminToCreateLibrary": "Vraag een beheerder om een bibliotheek aan te maken.", "Artist": "Artiest", - "AllowFfmpegThrottlingHelp": "Wanneer een transcodering of remux ver genoeg voorloopt op de huidige afspeelpositie zal het proces worden gepauzeerd zodat er minder middelen worden gebruikt. Dit is vooral nuttig wanneer je kijkt zonder vaak te spoelen. Schakel dit uit als je afspeelproblemen ondervindt.", + "AllowFfmpegThrottlingHelp": "Wanneer een transcodering of remux ver genoeg voorloopt op de huidige afspeelpositie zal het proces worden gepauzeerd zodat er minder middelen worden gebruikt. Dit is vooral nuttig wanneer er beperkt terug- of vooruitgespoeld wordt. Schakel dit uit als je afspeelproblemen ondervindt.", "AllowFfmpegThrottling": "Transcoderingen afknijpen", "LabelPlayerDimensions": "Afmetingen speler", "LabelLibraryPageSizeHelp": "Kies het aantal items dat wordt weergegeven op een bibliotheekpagina. Kies 0 om dit te verbergen.", @@ -1253,7 +1253,7 @@ "PlaybackErrorNoCompatibleStream": "Dit apparaat ondersteunt de afgespeelde media niet en de server verstuurt geen compatibel mediaformaat.", "Person": "Persoon", "OptionForceRemoteSourceTranscoding": "Transcoderen forceren van mediabronnen op afstand (zoals live-tv)", - "NoCreatedLibraries": "Het lijkt erop dat er nog geen bibliotheek is gecreëerd. {0}Wil je er nu een aanmaken?{1}", + "NoCreatedLibraries": "Het lijkt erop dat er nog geen bibliotheek is aangemaakt. {0}Wil je er nu een aanmaken?{1}", "Movie": "Film", "MessageConfirmAppExit": "Wil je afsluiten?", "LabelVideoResolution": "Beeldresolutie", @@ -1271,7 +1271,7 @@ "ListPaging": "{0}-{1} van {2}", "WriteAccessRequired": "Jellyfin vereist schrijftoegang tot deze map. Zorg voor schrijftoegang en probeer het opnieuw.", "PathNotFound": "Het pad kan niet gevonden worden. Zorg ervoor dat het pad geldig is en probeer opnieuw.", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "SelectAdminUsername": "Kies een gebruikersnaam voor de beheerdersaccount.", "ButtonTogglePlaylist": "Afspeellijst", "LabelRequireHttpsHelp": "Indien aangevinkt, zal de server alle verzoeken via HTTP automatisch omleiden naar HTTPS. Dit heeft geen effect als de server niet luistert op HTTPS.", @@ -1347,7 +1347,7 @@ "MessageGetInstalledPluginsError": "Er is een fout opgetreden bij het ophalen van de lijst met geïnstalleerde plug-ins.", "MessagePluginInstallError": "Er is een fout opgetreden tijdens het installeren van de plugin.", "LabelUnstable": "Instabiel", - "NextTrack": "Naar volgende gaan", + "NextTrack": "Volgend item", "LabelAlbumArtMaxResHelp": "Maximale resolutie van de albumhoes, beschreven in de eigenschap 'upnp:albumArtURI'.", "Image": "Afbeelding", "Other": "Andere", @@ -1355,9 +1355,9 @@ "LabelIconMaxResHelp": "Maximale resolutie van pictogrammen die worden weergegeven via de eigenschap 'upnp:icon'.", "MusicVideos": "Muziekvideo's", "Preview": "Voorvertoning", - "SubtitleVerticalPositionHelp": "Regelnummer waar tekst verschijnt. Positieve cijfers geven top-down aan. Negatieve getallen geven bottom-up aan.", + "SubtitleVerticalPositionHelp": "Regelnummer waar tekst verschijnt. Positieve getallen geven top-down aan. Negatieve getallen geven bottom-up aan.", "ButtonCast": "Naar apparaat casten", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "VideoAudio": "Beeld Geluid", "Video": "Beeld", "UseDoubleRateDeinterlacingHelp": "Deze instelling gebruikt de veldsnelheid bij de-interliniëren, ook wel bob-de-interliniëring genoemd, waarmee de verversingssnelheid van de video wordt verdubbeld om volledige beweging te bieden, zoals je zou zien bij het bekijken van geïnterlinieerd beeld op een tv.", @@ -1369,7 +1369,7 @@ "Restart": "Herstarten", "ResetPassword": "Wachtwoord opnieuw instellen", "Profile": "Profiel", - "PreviousTrack": "Naar vorige gaan", + "PreviousTrack": "Vorig item", "PosterCard": "Posterkaart", "Poster": "Poster", "PlaybackRate": "Afspeelsnelheid", @@ -1575,8 +1575,8 @@ "LabelSyncPlaySettingsSkipToSync": "SkipToSync inschakelen", "LabelSyncPlaySettingsSpeedToSyncHelp": "Methode voor synchronisatiecorrectie die bestaat uit het versnellen van het afspelen. Synchronisatiecorrectie moet ingeschakeld zijn.", "LabelSyncPlaySettingsSpeedToSync": "SpeedToSync inschakelen", - "LabelSyncPlaySettingsMinDelaySkipToSyncHelp": "Minimale afspeelvertraging (in ms) waarna SpeedToSync de afspeelpositie probeert te corrigeren.", - "LabelSyncPlaySettingsMinDelaySkipToSync": "Minimumvertraging SpeedToSync", + "LabelSyncPlaySettingsMinDelaySkipToSyncHelp": "Minimale afspeelvertraging (in ms) waarna SkipToSync de afspeelpositie probeert te corrigeren.", + "LabelSyncPlaySettingsMinDelaySkipToSync": "Minimumvertraging SkipToSync", "LabelSyncPlaySettingsSpeedToSyncDurationHelp": "Hoeveelheid milliseconden die SpeedToSync gebruikt om de afspeelpositie te corrigeren.", "LabelSyncPlaySettingsSpeedToSyncDuration": "Duur SpeedToSync", "LabelSyncPlaySettingsMaxDelaySpeedToSyncHelp": "Maximale afspeelvertraging (in ms) waarna SkipToSync gebruikt wordt in plaats van SpeedToSync.", @@ -1717,7 +1717,7 @@ "Featurette": "Featurette", "Short": "Korte film", "HeaderPerformance": "Prestaties", - "LabelParallelImageEncodingLimitHelp": "Maximaal aantal afbeeldingscoderingen dat tegelijkertijd mag lopen. Bij een instelling van 0 wordt een limiet gekozen gebaseerd op je systeemspecificaties.", + "LabelParallelImageEncodingLimitHelp": "Maximaal aantal afbeeldingscoderingen dat tegelijkertijd mag lopen. Bij een instelling van 0 wordt een limiet gekozen gebaseerd op het aantal processorkernen in je systeem.", "LabelParallelImageEncodingLimit": "Limiet gelijktijdige afbeeldingscoderingen", "LabelEnableAudioVbr": "VBR-audiocodering inschakelen", "LabelEnableAudioVbrHelp": "Een variabele bitsnelheid biedt een betere verhouding tussen kwaliteit en gemiddelde bitsnelheid, maar kan in zeldzame gevallen tot bufferen of compatibiliteitsproblemen leiden.", @@ -1818,8 +1818,8 @@ "LabelTrickplayAccelHelp": "Zorg dat 'MJPEG-codering toestaan' onder Transcoderen is ingeschakeld indien je hardware dit ondersteunt.", "AllowMjpegEncoding": "Coderen in MJPEG-formaat toestaan (gebruikt tijdens trickplay-generatie)", "LabelScanBehaviorHelp": "Het standaardgedrag is niet-blokkerend en zal media toevoegen aan de bibiotheek voordat de trickplay-generatie voltooid is. Blokkeren zorgt ervoor dat trickplay-bestanden gegenereerd worden voordat media aan de bibliotheek wordt toegevoegd. De scan duurt hierdoor significant langer.", - "NonBlockingScan": "Niet-blokkerend - scan gaat verder tijdens generatie", - "BlockingScan": "Blokkerend - wacht met scannen tot generatie is voltooid", + "NonBlockingScan": "Niet-blokkerend - scan gaat verder tijdens het genereren", + "BlockingScan": "Blokkerend - wacht met scannen tot het genereren is voltooid", "PriorityBelowNormal": "Beneden normaal", "PriorityAboveNormal": "Boven normaal", "LabelWidthResolutions": "Breedteresoluties", @@ -1830,11 +1830,11 @@ "LabelTrickplayThreads": "FFmpeg-threads", "LabelTrickplayThreadsHelp": "Het aantal threads dat aan het '-threads'-argument van FFmpeg wordt doorgegeven.", "OptionExtractTrickplayImage": "Uitpakken van trickplay-afbeeldingen inschakelen", - "LabelProcessPriorityHelp": "Deze instelling bepaalt welke prioriteit de processor aan het trickplay-generatieproces van ffmpeg geeft. Als het systeem traag reageert tijdens het genereren van trickplay-afbeeldingen maar je de generatie niet volledig wilt stoppen, kun je deze instelling, alsmede de hoeveelheid threads, verlagen.", + "LabelProcessPriorityHelp": "Deze instelling bepaalt welke prioriteit de processor aan het trickplay-generatieproces van ffmpeg geeft. Als het systeem traag reageert tijdens het genereren van trickplay-afbeeldingen maar je het genereren niet volledig wilt stoppen, kun je deze instelling, alsmede de hoeveelheid threads, verlagen.", "LabelTileHeightHelp": "Maximaal aantal afbeeldingen per tegel in de Y-richting.", "LabelQscale": "Qscale", "LabelQscaleHelp": "De kwaliteitsschaal van afbeeldingen die door FFmpeg worden geproduceerd, waarbij 2 de hoogste en 31 de laagste kwaliteit is.", - "LabelExtractTrickplayDuringLibraryScanHelp": "Genereer trickplay-afbeeldingen wanneer video's worden geïmporteerd tijdens de bibliotheekscan. Anders zullen ze worden uitgepakt tijdens de geplande taak voor trickplay-afbeeldingen. Als de generatie op niet-blokkerend wordt ingesteld heeft deze optie geen negatieve invloed op de duur van de bibliotheekscan.", + "LabelExtractTrickplayDuringLibraryScanHelp": "Genereer trickplay-afbeeldingen wanneer video's worden geïmporteerd tijdens de bibliotheekscan. Anders zullen ze worden uitgepakt tijdens de geplande taak voor trickplay-afbeeldingen. Als het genereren op niet-blokkerend wordt ingesteld heeft deze optie geen negatieve invloed op de duur van de bibliotheekscan.", "ExtractTrickplayImagesHelp": "Trickplay-afbeeldingen lijken op hoofdstukafbeeldingen, maar beslaan de gehele lengte van de inhoud en geven een voorvertoning bij het spoelen door video's.", "Lyric": "Songtekst", "PlaybackError.ASS_RENDER_ERROR": "Er is een fout opgetreden in de renderer voor ASS/SSA-ondertiteling.", @@ -1866,5 +1866,30 @@ "ConfirmDeleteLyrics": "Dit zal deze liedtekst verwijderen van zowel het bestandssysteem als uit je mediabibliotheek. Weet je zeker dat je wilt doorgaan?", "DeleteLyrics": "Liedtekst verwijderen", "HeaderNoLyrics": "Geen liedtekst gevonden", - "Lyrics": "Liedtekst" + "Lyrics": "Liedtekst", + "SavePassword": "Wachtwoord opslaan", + "EnableDts": "DTS (DCA) inschakelen", + "EnableDtsHelp": "Schakel dit alleen in als je apparaat DTS ondersteunt of is verbonden met een compatibele geluidsontvanger, anders kan dit afspeelfouten veroorzaken.", + "EnableTrueHd": "TrueHD inschakelen", + "EnableTrueHdHelp": "Schakel dit alleen in als je apparaat TrueHD ondersteunt of is verbonden met een compatibele geluidsontvanger, anders kan dit afspeelfouten veroorzaken.", + "HeaderVideoAdvanced": "Video geavanceerd", + "PlaylistError.CreateFailed": "Fout bij aanmaken afspeellijst", + "PlaylistError.AddFailed": "Fout bij toevoegen aan afspeellijst", + "PlaylistPublicDescription": "Iedere aangemelde gebruiker toestaan deze afspeellijst te bekijken.", + "PlaylistPublic": "Openbare toegang toestaan", + "HeaderLyricDownloads": "Liedtekstdownloads", + "SaveLyricsIntoMediaFolders": "Liedteksten opslaan in mediamappen", + "SaveLyricsIntoMediaFoldersHelp": "Het opslaan van liedteksten in dezelfde map als de geluidsbestanden zorgt ervoor dat deze beter te beheren zijn.", + "Author": "Auteur", + "Colorist": "Inkleurder", + "CoverArtist": "Omslagartiest", + "Creator": "Bedenker", + "Editor": "Redacteur", + "Illustrator": "Illustrator", + "Inker": "Inkter", + "Letterer": "Beletteraar", + "Penciller": "Schetser", + "Translator": "Vertaler", + "LibraryScanFanoutConcurrencyHelp": "Maximaal aantal gelijktijdige taken tijdens bibliotheekscans. Bij een instelling van 0 wordt een limiet gekozen gebaseerd op het aantal processorkernen in je systeem. WAARSCHUWING: een te hoge instelling kan problemen veroorzaken met netwerkbestandssystemen; verlaag dit getal als je problemen tegenkomt.", + "LibraryScanFanoutConcurrency": "Limiet gelijktijdige bibiotheekscantaken" } diff --git a/src/strings/pl.json b/src/strings/pl.json index 864a6d9166..07c9f5cb4a 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -367,7 +367,7 @@ "HeaderSeriesOptions": "Opcje nagrywania serialu", "HeaderSeriesStatus": "Stan serialu", "HeaderServerSettings": "Ustawienia serwera", - "HeaderSetupLibrary": "Skonfiguruj swoje biblioteki mediów", + "HeaderSetupLibrary": "Skonfiguruj biblioteki mediów", "HeaderSortBy": "Sortuj według", "HeaderSortOrder": "Porządek sortowania", "HeaderSpecialEpisodeInfo": "Specjalne informacje o odcinku", @@ -435,7 +435,7 @@ "LabelAllowedRemoteAddresses": "Filtr adresów IP", "LabelAllowedRemoteAddressesMode": "Tryb filtra adresów IP", "LabelAppName": "Nazwa aplikacji", - "LabelAppNameExample": "Przykład: Sickbeard, Sonarr", + "LabelAppNameExample": "Czytelna dla człowieka nazwa służąca do identyfikacji kluczy API. To ustawienie nie ma wpływu na funkcjonalność.", "LabelArtists": "Wykonawcy", "LabelArtistsHelp": "Oddziel wielu wykonawców średnikiem \";\".", "LabelAudioLanguagePreference": "Preferowany język ścieżki dźwiękowej", @@ -1255,7 +1255,7 @@ "Episode": "Odcinek", "DeinterlaceMethodHelp": "Wybierz metodę usuwania przeplotu używaną podczas transkodowania. Gdy przyśpieszenie sprzętowe wspierające usuwanie przeplotu jest włączone sprzętowe usuwanie przeplotu zostanie użyte zamiast tego ustawienia.", "ClientSettings": "Ustawienia klienta", - "ButtonTogglePlaylist": "Playlista", + "ButtonTogglePlaylist": "Lista odtwarzania", "ButtonSyncPlay": "Odtwarzanie zsynchronizowane", "ClearQueue": "Wyczyść kolejkę", "StopPlayback": "Zatrzymaj odtwarzanie", @@ -1276,7 +1276,7 @@ "ListPaging": "{0}-{1} z {2}", "WriteAccessRequired": "Jellyfin wymaga praw zapisu do tego katalogu. Upewnij się, że prawa zapisu zostały przyznane i spróbuj ponownie.", "PathNotFound": "Ścieżka nie została znaleziona. Upewnij się, że ścieżka jest poprawna i spróbuj ponownie.", - "Yadif": "YADIF", + "Yadif": "YADIF (Yet Another DeInterlacing Filter)", "Writers": "Scenariusz", "ViewAlbumArtist": "Zobacz wykonawcę albumu", "TabRepositories": "Repozytoria", @@ -1367,7 +1367,7 @@ "Poster": "Plakat", "MusicVideos": "Teledyski", "VideoAudio": "Dźwięk wideo", - "Bwdif": "BWDIF", + "Bwdif": "BWDIF (Bob Weaver DeInterlacing Filter)", "UseDoubleRateDeinterlacing": "Podwój częstotliwość wyświetlania klatek podczas usuwania przeplotu", "Photo": "Zdjęcie", "LabelIconMaxResHelp": "Maksymalna rozdzielczość ikon udostępnianych przez 'upnp:icon'.", @@ -1480,7 +1480,7 @@ "LabelSyncPlayTimeSyncDevice": "Synchronizacja czasu z", "LabelSyncPlayResumePlaybackDescription": "Wróć do grupy odtwarzania", "LabelSyncPlayResumePlayback": "Wznów lokalne odtwarzanie", - "LabelSyncPlayHaltPlaybackDescription": "I ignoruj aktualizacje aktualnej playlisty", + "LabelSyncPlayHaltPlaybackDescription": "I ignoruj aktualizacje aktualnej listy odtwarzania", "LabelSyncPlayHaltPlayback": "Zatrzymaj lokalne odtwarzanie", "LabelSSDPTracingFilterHelp": "Opcjonalny adres IP po który filtrować ruch SSDP.", "LabelSSDPTracingFilter": "Filtr SSDP", @@ -1867,5 +1867,30 @@ "ErrorDeletingLyrics": "Wystąpił błąd podczas usuwania słów z serwera. Sprawdź, czy Jellyfin ma uprawnienia do zapisu w folderze multimediów i spróbuj ponownie.", "HeaderDeleteLyrics": "Usuń słowa", "Lyrics": "Słowa", - "ViewLyrics": "Zobacz słowa" + "ViewLyrics": "Zobacz słowa", + "SavePassword": "Zapisz hasło", + "EnableDts": "Włącz DTS (DCA)", + "EnableDtsHelp": "Włącz tylko wtedy, gdy urządzenie obsługuje DTS lub jest podłączone do kompatybilnego odbiornika audio, w przeciwnym razie może to spowodować błąd odtwarzania.", + "EnableTrueHd": "Włącz TrueHD", + "EnableTrueHdHelp": "Włącz tylko wtedy, gdy urządzenie obsługuje TrueHD lub jest podłączone do kompatybilnego odbiornika audio, w przeciwnym razie może to spowodować błąd odtwarzania.", + "HeaderVideoAdvanced": "Zaawansowane wideo", + "PlaylistError.AddFailed": "Błąd dodawania do listy odtwarzania", + "PlaylistError.CreateFailed": "Błąd tworzenia listy odtwarzania", + "SaveLyricsIntoMediaFoldersHelp": "Przechowywanie słów obok plików audio ułatwi zarządzanie nimi.", + "PlaylistPublic": "Zezwól na dostęp publiczny", + "PlaylistPublicDescription": "Zezwól na oglądanie tej listy odtwarzania każdemu zalogowanemu użytkownikowi.", + "HeaderLyricDownloads": "Pobieranie słów", + "SaveLyricsIntoMediaFolders": "Zapisuj słowa w folderach multimediów", + "Author": "Autor", + "Colorist": "Kolorysta", + "CoverArtist": "Artysta okładki", + "Creator": "Twórca", + "Editor": "Edytor", + "Illustrator": "Ilustrator", + "Inker": "Inker", + "Letterer": "Liternik", + "Penciller": "Rysownik", + "Translator": "Tłumacz", + "LibraryScanFanoutConcurrency": "Limit zadań równoległego skanowania bibliotek", + "LibraryScanFanoutConcurrencyHelp": "Maksymalna liczba zadań równoległych podczas skanowania bibliotek. Ustawienie tej opcji na 0 spowoduje wybranie limitu na podstawie liczby rdzeni systemu. OSTRZEŻENIE: ustawienie zbyt dużej liczby może powodować problemy z sieciowymi systemami plików; jeśli napotkasz problemy, obniż tę liczbę." } diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index e53c9b25b3..0079d71e0b 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -209,7 +209,7 @@ "GuestStar": "Convidado especial", "Guide": "Guia", "GuideProviderSelectListings": "Selecionar Listas", - "H264CrfHelp": "O CRF (Constant Rate Factor) é a configuração padrão de qualidade para o codificador x264 e x265. Você pode definir valores entre 0 e 51, onde valores menores resultarão em melhor qualidade (ao custo de arquivos maiores). Valores saudáveis estão entre 18 e 28. O padrão para o x264 é 23 e para x265 é 28, então você pode usar esses valores como um ponto de partida.", + "H264CrfHelp": "O 'Constant Rate Factor' (CRF) é a configuração de qualidade padrão para os codificadores de software x264 e x265. Você pode definir os valores entre 0 e 51, sendo que valores mais baixos resultam em melhor qualidade (às custas de tamanhos de arquivo maiores). Valores adequados estão entre 18 e 28. O padrão para x264 é 23 e para x265 é 28, portanto, você pode usar isso como ponto de partida. Os codificadores por hardware não usam essas configurações.", "EncoderPresetHelp": "Escolha um valor mais rápido para melhorar o desempenho ou um valor mais lento para melhorar a qualidade.", "HDPrograms": "Programas em HD", "HardwareAccelerationWarning": "Ativar a aceleração de hardware pode causar instabilidade em alguns sistemas. Verifique se seu sistema operacional e drivers de vídeo estão atualizados. Se tiver dificuldades em reproduzir vídeo depois de ativar, retorne a configuração para automático.", @@ -1390,7 +1390,7 @@ "LabelTonemappingRange": "Faixa de mapeamento de tom", "TonemappingAlgorithmHelp": "O mapeamento de tons pode ser ajustado precisamente. Se você não esta familiarizado com essas opções, mantenha o valor padrão. O valor recomendado é 'BT.2390'.", "LabelTonemappingAlgorithm": "Selecione o algoritmo de mapeamento de tons a ser usado", - "AllowTonemappingHelp": "O mapeamento de tons pode transformar a faixa dinâmica de um vídeo de HDR para SDR, mantendo detalhes de cores da imagem e informações muito importantes para representar a cena original. Atualmente, funciona apenas ao transcodificar vídeos no padrão HDR10, HLG e DoVI . Isso requer as bibliotecas OpenCL ou CUDA correspondente.", + "AllowTonemappingHelp": "O mapeamento de tons pode transformar a faixa dinâmica de um vídeo de HDR para SDR, mantendo detalhes e cores da imagem, que são informações muito importantes para representar a cena original. Atualmente, funciona apenas ao transcodificar vídeos com 10bit HDR10, HLG e DoVi. Isso requer a biblioteca GPGPU correspondente.", "EnableTonemapping": "Ativar mapeamento de tons", "LabelOpenclDeviceHelp": "Dispositivo OpenCL usado para a mapeação de tons. Os números ao lado esquerdo do ponto (.) são referentes ao número da plataforma, os números a direita representam o número do dispositivo dentro da plataforma. O valor padrão é 0.0. O arquivo da aplicação FFmpeg contendo o método de aceleração de hardware OpenCL é obrigatório.", "LabelOpenclDevice": "Dispositivo OpenCL", @@ -1634,7 +1634,7 @@ "Trailer": "Trailer", "Clip": "Destaque", "AllowEmbeddedSubtitlesAllowNoneOption": "Não permitir nada", - "EnableEnhancedNvdecDecoderHelp": "Implementação experimental do NVDEC. Não habilite esta opção a menos que você encontre erros de decodificação.", + "EnableEnhancedNvdecDecoderHelp": "Implementação aprimorada do NVDEC, desative essa opção para usar o CUVID se encontrar erros de decodificação.", "ThemeVideo": "Vídeo tema", "ThemeSong": "Música tema", "Sample": "Amostra", @@ -1767,11 +1767,11 @@ "AiTranslated": "Traduzido por IA", "MachineTranslated": "Traduzido por Máquina", "AllowSegmentDeletion": "Remover segmentos", - "AllowSegmentDeletionHelp": "Remover segmentos antigos após serem enviados ao cliente. Isso previne armazenar o arquivo transcodificado em disco. Funciona apenas com limitação habilitada. Desligue esta opção se você tiver problemas com a reprodução.", + "AllowSegmentDeletionHelp": "Exclua segmentos antigos depois que eles tiverem sido baixados pelo cliente. Isso evita a necessidade de armazenar todo o arquivo transcodificado no disco. Desative esse recurso se você tiver problemas de reprodução.", "LabelThrottleDelaySeconds": "Limitar após", "LabelThrottleDelaySecondsHelp": "Tempo em segundos em que o transcodificador será limitado. É necessário que seja grande o suficiente para que o cliente mantenha um buffer saudável. Funciona apenas se o limitador estiver habilitado.", "LabelSegmentKeepSeconds": "Tempo para manter seguimentos", - "LabelSegmentKeepSecondsHelp": "Tempo em segundos para que os seguimentos sejam armazenados antes de serem sobrescritos. É necessário que seja maior que \"Limitar após\". Funciona apenas se a remoção de segmentos estiver habilitada.", + "LabelSegmentKeepSecondsHelp": "Tempo em segundos, pelo qual os segmentos devem ser mantidos após serem baixados pelo cliente. Só funciona se a exclusão de segmentos estiver ativada.", "SearchResultsEmpty": "Desculpe! Nenhum resultaod encontrado para \"{0}\"", "ForeignPartsOnly": "Apenas partes extrangeiras/forçadas", "HearingImpairedShort": "HI/SDH", @@ -1825,5 +1825,37 @@ "PlaybackError.NETWORK_ERROR": "A reprodução falhou devido a um erro de rede.", "PlaybackError.NO_MEDIA_ERROR": "Não foi possível encontrar uma fonte de mídia válida para reproduzir.", "PlaybackError.SERVER_ERROR": "A reprodução falhou devido a um erro no servidor.", - "ViewLyrics": "Ver letras" + "ViewLyrics": "Ver letras", + "LabelEncodingFormatOptions": "Opções de formato de codificação", + "EncodingFormatHelp": "Selecione a codificação de vídeo para a qual o Jellyfin deve transcodificar. O Jellyfin usará codificação por software quando a aceleração de hardware para o formato selecionado não estiver disponível. A codificação H264 sempre estará ativada.", + "AllowVideoToolboxTonemappingHelp": "Mapeamento de tons acelerado por hardware fornecido pelo VideoToolbox. Ele funciona com a maioria dos formatos HDR, incluindo HDR10, HDR10+ e HLG, mas não funciona com o Dolby Vision Profile 5. Isso tem uma prioridade mais alta em comparação com outra implementação do Metal.", + "PriorityHigh": "Alta", + "LabelTrickplayAccelEncoding": "Ativar codificação MJPEG acelerada por hardware", + "LabelTrickplayAccel": "Ativar decodificação por hardware", + "LabelTrickplayAccelEncodingHelp": "Atualmente disponível apenas no QSV e VAAPI, essa opção não tem efeito sobre outros métodos de aceleração por hardware.", + "LabelScanBehavior": "Comportamento do Escaneamento", + "PriorityAboveNormal": "Acima do normal", + "PriorityNormal": "Normal", + "EnableVideoToolboxTonemapping": "Habilitar mapeamento de tons do VideoToolbox", + "PriorityBelowNormal": "Abaixo do normal", + "PriorityIdle": "Ocioso", + "LabelProcessPriority": "Prioridade do Processo", + "LabelImageIntervalHelp": "Intervalo de tempo (ms) entre cada nova imagem do trickplay.", + "LabelWidthResolutionsHelp": "Lista separada por vírgula das larguras (px) em que as imagens do trickplay serão geradas. Todas as imagens devem ser geradas proporcionalmente à fonte, de modo que uma largura de 320 em um vídeo de 16:9 resulta em cerca de 320x180.", + "OptionExtractTrickplayImage": "Ativar extração de imagens trickplay", + "ExtractTrickplayImagesHelp": "Imagens de Trickplay são semelhantes às imagens de capítulo, exceto que abrangem todo o comprimento do conteúdo e são usadas para mostrar uma prévia ao navegar pelos vídeos.", + "LabelExtractTrickplayDuringLibraryScan": "Extrair imagens trickplay durante o escaneamento da biblioteca", + "LabelExtractTrickplayDuringLibraryScanHelp": "Gerar imagens de trickplay quando os vídeos são importados durante o escaneamento da biblioteca. Caso contrário, elas serão extraídas durante a tarefa agendada de imagens trickplay. Se a geração estiver configurada como não-bloqueadora, isso não afetará o tempo que a varredura da biblioteca leva para ser concluída.", + "LabelWidthResolutions": "Resolução de largura", + "NonBlockingScan": "Não Bloqueadora - enfileira a geração e depois retorna", + "BlockingScan": "Bloqueadora - enfileira a geração e bloqueia escaneamento até a conclusão", + "LabelImageInterval": "Intervalo de imagens", + "LabelJpegQuality": "Qualidade JPEG", + "LabelJpegQualityHelp": "A qualidade de compressão JPEG para imagens trickplay.", + "LabelQscaleHelp": "A escala de qualidade das imagens produzidas pelo ffmpeg, sendo 2 a qualidade mais alta e 31 a mais baixa.", + "LabelProcessPriorityHelp": "A configuração desse valor mais baixo ou mais alto determinará como a CPU prioriza o processo de geração de trickplay do ffmpeg em relação a outros processos. Se você notar lentidão durante a geração de imagens do trickplay, mas não quiser interromper totalmente a geração, tente diminuir esse valor, bem como a contagem de threads.", + "LabelScanBehaviorHelp": "O comportamento padrão é não bloqueadora, o que adicionará mídia à biblioteca antes que a geração do trickplay seja feita. Bloquear garantirá que os arquivos trickplay sejam gerados antes que a mídia seja adicionada à biblioteca, mas tornará os escaneamentos significativamente mais longos.", + "LabelTrickplayThreadsHelp": "O número de threads a ser passado para o argumento '-threads' do ffmpeg.", + "LabelTrickplayThreads": "FFmpeg Threads", + "Trickplay": "Trickplay" } diff --git a/src/strings/pt-pt.json b/src/strings/pt-pt.json index d2fad957b5..88998636a9 100644 --- a/src/strings/pt-pt.json +++ b/src/strings/pt-pt.json @@ -215,7 +215,7 @@ "LabelAlbumArtPN": "PN da capa do álbum", "LabelAlbumArtists": "Artistas do álbum", "LabelAppName": "Nome da aplicação", - "LabelAppNameExample": "Exemplo: Sickbeard, Sonarr", + "LabelAppNameExample": "Um nome legível por humanos para identificar as chaves da API. Esta definição não afetará a funcionalidade.", "LabelArtists": "Artistas", "LabelArtistsHelp": "Separe múltiplos artistas com ponto e virgula (;).", "LabelAudioLanguagePreference": "Idioma de áudio preferido", @@ -1763,7 +1763,7 @@ "LabelAlbumGain": "Ganho do Album", "BackdropScreensaver": "Fundo do protetor de ecrã", "LabelIsHearingImpaired": "Para deficientes auditivos (SDH)", - "LabelBackdropScreensaverIntervalHelp": "O tempo em segundos entre diferentes cenários ao usar o protetor de ecrã de cenário.", + "LabelBackdropScreensaverIntervalHelp": "O tempo em segundos entre a mudança de diferentes imagens de fundo na proteção de ecrã.", "LabelBackdropScreensaverInterval": "Intervalo do fundo do protetor de ecrã", "HeaderAllRecordings": "Todas as Gravações", "SelectAudioNormalizationHelp": "Ganho de faixa - ajusta o volume de cada faixa para que sejam reproduzidas com o mesmo volume. Ganho do álbum - ajusta o volume de todas as faixas apenas de um álbum, mantendo a faixa dinâmica do álbum.", @@ -1862,5 +1862,19 @@ "PlaybackError.NO_MEDIA_ERROR": "Não foi possível encontrar uma fonte multimédia válida para reproduzir.", "LabelServerVersion": "Versão do servidor", "LabelWebVersion": "Versão web", - "LabelBuildVersion": "Versão de compilação" + "LabelBuildVersion": "Versão de compilação", + "SavePassword": "Guardar palavra-passe", + "Author": "Autor", + "Colorist": "Colorista", + "CoverArtist": "Artista da capa", + "Creator": "Criador", + "Editor": "Editor", + "EnableTrueHd": "Ativar TrueHD", + "EnableTrueHdHelp": "Ativar apenas se o dispositivo suportar TrueHD ou estiver ligado a um recetor de áudio compatível; caso contrário, pode provocar falhas de reprodução.", + "Illustrator": "Ilustrador", + "Letterer": "Letrista", + "EnableDts": "Ativar DTS (DCA)", + "EnableDtsHelp": "Ativar apenas se o dispositivo suportar DTS ou estiver ligado a um recetor de áudio compatível; caso contrário, pode provocar falhas de reprodução.", + "HeaderLyricDownloads": "Descarregar letras", + "HeaderVideoAdvanced": "Avançadas do vídeo" } diff --git a/src/strings/pt.json b/src/strings/pt.json index 99816bfa0e..b30f363271 100644 --- a/src/strings/pt.json +++ b/src/strings/pt.json @@ -395,7 +395,7 @@ "LabelAudioBitrate": "Taxa de bits de áudio", "LabelArtistsHelp": "Separe artistas múltiplos com um ponto e vírgula.", "LabelArtists": "Artistas", - "LabelAppNameExample": "Exemplo: Sickbeard, NzbDrone", + "LabelAppNameExample": "Um nome legível por humanos para identificar as chaves da API. Esta definição não afetará a funcionalidade.", "LabelAppName": "Nome da aplicação", "LabelAllowedRemoteAddressesMode": "Tipo de filtro de IP remoto", "LabelAllowedRemoteAddresses": "Filtro de IP remoto", @@ -1487,7 +1487,7 @@ "UnsupportedPlayback": "Jellyfin não pode desencriptar conteúdo protegido por DRM, mas todo o conteúdo será testado de qualquer maneira, incluindo títulos protegidos. Alguns arquivos podem aparecer completamente pretos devido à encriptação ou a outros recursos não suportados, como títulos interativos.", "MessageSyncPlayGroupWait": "{0} está a armazenar em buffer…", "LabelSelectAudioNormalization": "Normalização de áudio", - "LabelBackdropScreensaverIntervalHelp": "O tempo em segundos entre diferentes cenários ao usar o protetor de tela de cenário.", + "LabelBackdropScreensaverIntervalHelp": "O tempo em segundos entre a mudança de diferentes imagens de fundo na proteção de ecrã.", "LabelServerVersion": "Versão do servidor", "LabelTonemappingPeakHelp": "Substitua o sinal/pico nominal/de referência por este valor. Útil quando as informações de pico incorporadas nos metadados de exibição não são confiáveis ou quando há mapeamento de tons de uma faixa mais baixa para uma faixa mais alta. Os valores recomendados e padrão são 100 e 0.", "OptionDateShowAdded": "Data de exibição adicionada", @@ -1495,7 +1495,7 @@ "WriteAccessRequired": "Jellyfin requer acesso de gravação a esta pasta. Garanta o acesso de gravação e tente novamente.", "LabelFallbackFontPathHelp": "Essas fontes são usadas por alguns clientes para renderizar legendas. Consulte a documentação para obter mais informações.", "EnableGamepadHelp": "Ouça a entrada de qualquer controlador conectado. (Requer: Modo de exibição 'TV')", - "BackdropScreensaver": "Protetor de tela de fundo", + "BackdropScreensaver": "Fundo do protetor de ecrã", "LabelLevel": "Nível", "LabelSyncPlaySettingsMinDelaySpeedToSync": "Atraso mínimo da velocidade de sincronização", "OptionDateEpisodeAdded": "Data do episódio adicionado", @@ -1611,7 +1611,7 @@ "LabelVideoRange": "Alcance de vídeo", "Mixer": "Misturador", "LabelSystem": "Sistema", - "SaveRecordingImages": "Salvar gravação de imagens EPG", + "SaveRecordingImages": "Guardar imagens da gravação EPG", "SaveRecordingImagesHelp": "Guardar imagens do fornecedor de listas EPG juntamente com os ficheiros multimédia.", "UseDoubleRateDeinterlacing": "Duplicar a velocidade de fotogramas ao desentrelaçar", "MessageSyncPlayUserJoined": "{0} entrou no grupo.", @@ -1624,7 +1624,7 @@ "YoutubeBadRequest": "Requisição ruim.", "YoutubeDenied": "O vídeo solicitado não pode ser reproduzido em players incorporados.", "TypeOptionPluralBoxSet": "Conjuntos de caixas", - "LabelBackdropScreensaverInterval": "Intervalo do protetor de tela de fundo", + "LabelBackdropScreensaverInterval": "Intervalo do fundo do protetor de ecrã", "UseDoubleRateDeinterlacingHelp": "Esta definição utiliza a taxa de campo durante o desentrelaçamento, muitas vezes referido como desentrelaçamento bob, que duplica a taxa de fotogramas do vídeo para proporcionar movimento fluído, como o que verias ao ver vídeo entrelaçado numa televisão.", "LabelDirectStreamingInfo": "Informações de transmissão direta", "LabelAlbumGain": "Ganho do álbum", @@ -1860,5 +1860,19 @@ "NonBlockingScan": "Não bloqueante - coloca a geração em fila de espera e depois regressa", "LabelExtractTrickplayDuringLibraryScan": "Extrair imagens trickplay durante a análise da biblioteca", "LabelExtractTrickplayDuringLibraryScanHelp": "Gera imagens trickplay quando os vídeos são importados durante a análise da biblioteca. Caso contrário, serão extraídas durante a tarefa agendada de imagens trickplay. Se a geração estiver definida como não bloqueante, isto não afetará o tempo que a análise da biblioteca demora a ser concluída.", - "PlaybackError.ASS_RENDER_ERROR": "Foi encontrado um erro no renderizador de legendas ASS/SSA." + "PlaybackError.ASS_RENDER_ERROR": "Foi encontrado um erro no renderizador de legendas ASS/SSA.", + "SavePassword": "Guardar palavra-passe", + "Author": "Autor", + "Colorist": "Colorista", + "CoverArtist": "Artista da capa", + "Creator": "Criador", + "Editor": "Editor", + "Illustrator": "Ilustrador", + "EnableDts": "Ativar DTS (DCA)", + "EnableDtsHelp": "Ativar apenas se o dispositivo suportar DTS ou estiver ligado a um recetor de áudio compatível; caso contrário, pode provocar falhas de reprodução.", + "EnableTrueHd": "Ativar TrueHD", + "EnableTrueHdHelp": "Ativar apenas se o dispositivo suportar TrueHD ou estiver ligado a um recetor de áudio compatível; caso contrário, pode provocar falhas de reprodução.", + "HeaderVideoAdvanced": "Avançadas do vídeo", + "HeaderLyricDownloads": "Descarregar letras", + "Letterer": "Letrista" } diff --git a/src/strings/ru.json b/src/strings/ru.json index ff1597d15d..adf6f5c237 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -760,7 +760,7 @@ "MediaInfoAnamorphic": "Анаморфность", "MediaInfoAspectRatio": "Соотношение сторон", "MediaInfoBitDepth": "Разрядность", - "MediaInfoBitrate": "Битрейт", + "MediaInfoBitrate": "Потоковая скорость", "MediaInfoChannels": "Каналы", "MediaInfoCodec": "Кодек", "MediaInfoCodecTag": "Тег кодека", @@ -1816,7 +1816,7 @@ "AllowMjpegEncoding": "Разрешить кодирование в формате MJPEG (используется при создании трюковой игры)", "LabelProcessPriorityHelp": "Установив это значение ниже или выше, вы определите, как процессор расставит приоритеты для процесса генерации trickplay в формате ffmpeg по отношению к другим процессам. Если вы заметили замедление при создании изображений trickplay, но не хотите полностью останавливать их генерацию, попробуйте уменьшить это значение, а также количество потоков.", "LabelEncodingFormatOptions": "Параметры формата кодирования", - "LabelTrickplayAccel": "Включить аппаратное ускорение", + "LabelTrickplayAccel": "Включить аппаратное декодирование", "LabelTrickplayAccelHelp": "Обязательно включите \"Разрешить кодировку MJPEG\" в режиме транскодирования, если ваше оборудование поддерживает это.", "PriorityAboveNormal": "Выше нормы", "LabelTileWidth": "Ширина плитки", @@ -1858,5 +1858,15 @@ "PriorityHigh": "Высокий", "PriorityNormal": "Нормальный", "LabelJpegQualityHelp": "Уровень сжатия JPEG для кадров trickplay.", - "NonBlockingScan": "Асинхронное - ставит генерацию в очередь и продолжает" + "NonBlockingScan": "Асинхронное - ставит генерацию в очередь и продолжает", + "Lyrics": "Текст песни", + "SavePassword": "Сохранить пароль", + "ViewLyrics": "Просмотр текста песни", + "LabelTrickplayAccelEncoding": "Включить аппаратное ускорение кодирования MJPEG", + "LabelTrickplayAccelEncodingHelp": "Эта опция доступна только для QSV и VAAPI, она не влияет на другие методы аппаратного ускорения.", + "ConfirmDeleteLyrics": "Удаление этих текстов песен приведет к удалению их как из файловой системы, так и из вашей медиатеки. Вы уверены, что хотите продолжить?", + "DeleteLyrics": "Удалить тексты песен", + "ErrorDeletingLyrics": "Возникла ошибка при удалении текста песни с сервера. Пожалуйста, проверьте, имеет ли Jellyfin доступ на запись в папку с медиа, и попробуйте ещё раз.", + "HeaderDeleteLyrics": "Удалить Текст песни", + "HeaderNoLyrics": "Текст песни не найден" } diff --git a/src/strings/sk.json b/src/strings/sk.json index 8ea448e95f..8b60547a0b 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -215,7 +215,7 @@ "HeaderSelectPath": "Vybrať priečinok", "HeaderSendMessage": "Poslať správu", "HeaderServerSettings": "Nastavenia servera", - "HeaderSetupLibrary": "Nastavenie vašich knižníc médií", + "HeaderSetupLibrary": "Nastavenie Vašich knižníc médií", "HeaderSortBy": "Zoradiť podľa", "HeaderStartNow": "Začať teraz", "HeaderStopRecording": "Zastaviť nahrávanie", @@ -251,7 +251,7 @@ "LabelAllowHWTranscoding": "Povoliť hardvérové prekódovanie", "LabelAllowedRemoteAddresses": "Filter vzdialených IP adries", "LabelAppName": "Názov appky", - "LabelAppNameExample": "Príklad: Sickbeard, Sonarr", + "LabelAppNameExample": "Čitateľný názov na identifikáciu kľúčov API. Toto nastavenie neovplyvní funkčnosť.", "LabelArtists": "Interpreti", "LabelArtistsHelp": "Viacej interpretov oddeľte pomocou bodkočiarky.", "LabelAudioLanguagePreference": "Uprednostňovaný jazyk zvuku", @@ -1261,7 +1261,7 @@ "ListPaging": "{0}-{1} z {2}", "WriteAccessRequired": "Server vyžaduje práva na zapisovanie do tohoto priečinku. Prosím, uistite sa že má práva na zapisovanie a skúste to znova.", "PathNotFound": "Táto cesta nebola nájdená. Prosím, uistite sa že cesta je správna a skúste to znovu.", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "Season": "Séria", "Person": "Osoba", "Movie": "Film", @@ -1363,7 +1363,7 @@ "DeleteAll": "Zmazať všetko", "Data": "Údaje", "ThumbCard": "Thumb karta", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "LabelEnableSSDPTracing": "Povoliť trasovanie SSDP", "LabelEnableIP6Help": "Povolí IPv6 funkcionalitu.", "LabelEnableIP6": "Povoliť IPv6", @@ -1706,7 +1706,7 @@ "LabelEnableAudioVbr": "Povoliť kódovanie zvuku VBR", "HeaderPerformance": "Výkon", "AllowCollectionManagement": "Povoliť tomuto používateľovi spravovať kolekcie", - "LabelParallelImageEncodingLimitHelp": "Maximálny počet kódovaní obrazu, ktoré môžu bežať paralelne. Nastavením tejto hodnoty na 0 sa zvolí limit na základe špecifikácie vášho systému.", + "LabelParallelImageEncodingLimitHelp": "Maximálny počet kódovaní obrázkov, ktoré môžu bežať paralelne. Nastavením tejto hodnoty na 0 sa zvolí limit na základe špecifikácie vášho systému.", "TonemappingModeHelp": "Vyberte režim mapovania tónov. Ak sa vyskytnú preexponované svetlé miesta, skúste prepnúť na režim RGB.", "Featurette": "Stredne dlhý film", "Short": "Krátky film", @@ -1867,5 +1867,30 @@ "ErrorDeletingLyrics": "Pri odstraňovaní textov piesní zo servera došlo k chybe. Skontrolujte, či má Jellyfin prístup na zápis do priečinka médií, a skúste to znova.", "HeaderDeleteLyrics": "Odstrániť texty piesní", "HeaderNoLyrics": "Nenašli sa žiadne texty piesní", - "ViewLyrics": "Zobraziť texty piesní" + "ViewLyrics": "Zobraziť texty piesní", + "SavePassword": "Uložiť heslo", + "PlaylistError.AddFailed": "Chyba pri pridávaní do playlistu", + "PlaylistError.CreateFailed": "Chyba pri vytváraní playlistu", + "EnableDts": "Povoliť DTS (DCA)", + "EnableDtsHelp": "Povoľte len vtedy, ak vaše zariadenie podporuje DTS alebo je pripojené ku kompatibilnému audio receiveru, inak môže dôjsť k zlyhaniu prehrávania.", + "EnableTrueHd": "Povoliť TrueHD", + "EnableTrueHdHelp": "Povoľte len vtedy, ak vaše zariadenie podporuje TrueHD alebo je pripojené ku kompatibilnému audio receiveru, inak môže dôjsť k zlyhaniu prehrávania.", + "HeaderVideoAdvanced": "Pokročilé video", + "PlaylistPublic": "Povoliť verejný prístup", + "HeaderLyricDownloads": "Stiahnutie textov piesní", + "Author": "Autor", + "Colorist": "Kolorista", + "Creator": "Tvorca", + "CoverArtist": "Autor obálky", + "Editor": "Editor", + "Illustrator": "Ilustrátor", + "Inker": "Inker", + "Letterer": "Lettrista", + "Penciller": "Penciler", + "SaveLyricsIntoMediaFolders": "Uložiť texty piesní do priečinkov médií", + "SaveLyricsIntoMediaFoldersHelp": "Uloženie textov piesní k zvukovým súborom umožní ich jednoduchšie spravovanie.", + "Translator": "Prekladateľ", + "PlaylistPublicDescription": "Povoliť zobrazenie tohto playlistu každému prihlásenému používateľovi.", + "LibraryScanFanoutConcurrencyHelp": "Maximálny počet paralelných úloh počas skenovania knižnice. Nastavením tejto hodnoty na 0 sa zvolí limit na základe počtu jadier CPU vášho systému. UPOZORNENIE: Nastavenie príliš vysokého čísla môže spôsobiť problémy so sieťovými súborovými systémami, Ak sa vyskytnú problémy, znížte toto číslo.", + "LibraryScanFanoutConcurrency": "Limit úloh paralelného skenovania knižnice" } diff --git a/src/strings/ta.json b/src/strings/ta.json index 344e30ee12..b3dddb74dd 100644 --- a/src/strings/ta.json +++ b/src/strings/ta.json @@ -21,7 +21,7 @@ "AllowedRemoteAddressesHelp": "தொலைதூரத்துடன் இணைக்க அனுமதிக்கப்படும் நெட்வொர்க்குகளுக்கான ஐபி முகவரிகள் அல்லது ஐபி / நெட்மாஸ்க் உள்ளீடுகளின் கமாவால் பிரிக்கப்பட்ட பட்டியல். காலியாக இருந்தால், எல்லா தொலை முகவரிகளும் அனுமதிக்கப்படும்.", "AllowRemoteAccessHelp": "தேர்வு செய்யப்படாவிட்டால், எல்லா தொலைநிலை இணைப்புகளும் தடுக்கப்படும்.", "AllowRemoteAccess": "இந்த சேவையகத்திற்கு தொலை இணைப்புகளை அனுமதிக்கவும்", - "AllowFfmpegThrottlingHelp": "ஒரு டிரான்ஸ்கோட் அல்லது ரீமக்ஸ் தற்போதைய பின்னணி நிலையிலிருந்து வெகு தொலைவில் இருக்கும்போது, செயல்முறையை இடைநிறுத்துங்கள், இதனால் அது குறைந்த ஆதாரங்களை நுகரும். அடிக்கடி தேடாமல் பார்க்கும்போது இது மிகவும் பயனுள்ளதாக இருக்கும். பின்னணி சிக்கல்களை நீங்கள் சந்தித்தால் இதை அணைக்கவும்.", + "AllowFfmpegThrottlingHelp": "டிரான்ஸ்கோட் அல்லது ரீமக்ஸ் தற்போதைய பிளேபேக் நிலையில் இருந்து போதுமான அளவு முன்னேறும் போது, செயல்முறையை இடைநிறுத்தவும், அதனால் அது குறைவான ஆதாரங்களைப் பயன்படுத்தும். அடிக்கடி தேடாமல் பார்க்கும் போது இது மிகவும் பயனுள்ளதாக இருக்கும். பிளேபேக் சிக்கல்களை நீங்கள் சந்தித்தால் இதை முடக்கவும்.", "AllowFfmpegThrottling": "திராட்டில் ட்ரான்ஸ்கோட்கள்", "AllowOnTheFlySubtitleExtractionHelp": "வீடியோ டிரான்ஸ்கோடிங்கைத் தடுக்க உதவும் வகையில் உட்பொதிக்கப்பட்ட வசனங்களை வீடியோக்களிலிருந்து பிரித்தெடுத்து வாடிக்கையாளர்களுக்கு எளிய உரையில் வழங்கலாம். சில கணினிகளில் இது நீண்ட நேரம் எடுக்கும் மற்றும் பிரித்தெடுக்கும் செயல்பாட்டின் போது வீடியோ பிளேபேக் நிறுத்தப்படும். கிளையன்ட் சாதனத்தால் பூர்வீகமாக ஆதரிக்கப்படாதபோது உட்பொதிக்கப்பட்ட வசன வரிகள் வீடியோ டிரான்ஸ்கோடிங்கில் எரிக்கப்படுவதை முடக்கு.", "AllowOnTheFlySubtitleExtraction": "வசன வரிகள் பிரித்தெடுக்க அனுமதிக்கவும்", @@ -333,7 +333,7 @@ "HeaderConfirmRevokeApiKey": "API விசையைத் திரும்பப்பெறுக", "HeaderConfirmProfileDeletion": "சுயவிவர நீக்குதலை உறுதிப்படுத்தவும்", "HeaderSortBy": "மூலம் வரிசைப்படுத்து", - "HeaderSetupLibrary": "உங்கள் மீடியா நூலகங்களை அமைக்கவும்", + "HeaderSetupLibrary": "உங்கள் ஊடக நூலகங்களை அமைக்கவும்", "HeaderServerSettings": "சேவையக அமைப்புகள்", "HeaderServerAddressSettings": "சேவையக முகவரி அமைப்புகள்", "HeaderSeriesStatus": "தொடர் நிலை", @@ -492,7 +492,7 @@ "LabelAudioBitDepth": "ஆடியோ பிட் ஆழம்", "LabelArtistsHelp": "அரைக்காற்புள்ளியுடன் பல கலைஞர்களைப் பிரிக்கவும்.", "LabelArtists": "கலைஞர்கள்", - "LabelAppNameExample": "எடுத்துக்காட்டு: Sickbeard, Sonarr", + "LabelAppNameExample": "API விசைகளை அடையாளம் காண மனிதனால் படிக்கக்கூடிய பெயர். இந்த அமைப்பு செயல்பாட்டை பாதிக்காது.", "LabelAppName": "பயன்பாட்டின் பெயர்", "LabelAllowedRemoteAddressesMode": "தொலை ஐபி முகவரி வடிகட்டி பயன்முறை", "LabelAllowedRemoteAddresses": "தொலை ஐபி முகவரி வடிப்பான்", @@ -1241,7 +1241,7 @@ "Yesterday": "நேற்று", "Yes": "ஆம்", "YadifBob": "யடிஃப் பாப்", - "Yadif": "யடிஃப்", + "Yadif": "இன்னுமொரு டீஇண்டர்லேசிங் வடிகட்டி (YADIF)", "XmlTvSportsCategoriesHelp": "இந்த வகைகளைக் கொண்ட நிகழ்ச்சிகள் விளையாட்டுத் திட்டங்களாகக் காட்டப்படும். '|' உடன் பலவற்றைப் பிரிக்கவும்.", "XmlTvPathHelp": "XMLTV கோப்புக்கான பாதை. ஜெல்லிஃபின் இந்த கோப்பைப் படித்து புதுப்பிப்புகளுக்கு அவ்வப்போது சரிபார்க்கும். கோப்பை உருவாக்கி புதுப்பிக்க நீங்கள் பொறுப்பு.", "XmlTvNewsCategoriesHelp": "இந்த வகைகளைக் கொண்ட நிகழ்ச்சிகள் செய்தித் திட்டங்களாகக் காட்டப்படும். '|' உடன் பலவற்றைப் பிரிக்கவும்.", @@ -1385,7 +1385,7 @@ "LabelIconMaxResHelp": "'upnp:icon' பண்பு வழியாக வெளிப்படும் ஐகான்களின் அதிகபட்ச தெளிவுத்திறன்.", "LabelAlbumArtMaxResHelp": "'upnp:albumArtURI' பண்பு மூலம் வெளிப்படும் ஆல்பம் கலையின் அதிகபட்ச தெளிவுத்திறன்.", "Other": "மற்றவை", - "Bwdif": "BWDIF", + "Bwdif": "பாப் வீவர் டிஇண்டர்லேசிங் வடிகட்டி (BWDIF)", "UseDoubleRateDeinterlacingHelp": "டீஇன்டர்லேசிங் செய்யும் போது இந்த அமைப்பு புலம் வீதத்தைப் பயன்படுத்துகிறது, இது பெரும்பாலும் பாப் டீஇன்டர்லேசிங் என அழைக்கப்படுகிறது, இது டிவியில் ஒன்றோடொன்று இணைக்கப்பட்ட வீடியோவைப் பார்க்கும்போது நீங்கள் பார்ப்பது போன்ற முழு இயக்கத்தையும் வழங்க வீடியோவின் பிரேம் வீதத்தை இரட்டிப்பாக்குகிறது.", "UseDoubleRateDeinterlacing": "செயலிழக்கும்போது பிரேம் வீதத்தை இரட்டிப்பாக்குங்கள்", "LabelMaxMuxingQueueSizeHelp": "அனைத்து ஸ்ட்ரீம்களும் தொடங்கும் வரை காத்திருக்கும் போது, இடையகப்படுத்தக்கூடிய பாக்கெட்டுகளின் அதிகபட்ச எண்ணிக்கை. FFmpeg பதிவுகளில் \"அவுட்புட் ஸ்ட்ரீமிற்காக பல பாக்கெட்டுகள் இடையகப்படுத்தப்பட்டுள்ளன\" என்ற பிழையை நீங்கள் இன்னும் சந்தித்தால் அதை அதிகரிக்க முயற்சிக்கவும். பரிந்துரைக்கப்பட்ட மதிப்பு 2048 ஆகும்.", @@ -1764,7 +1764,7 @@ "LogLevel.Critical": "முக்கியம்", "NotificationsMovedMessage": "அறிவிப்புகள் செயல்பாடு Webhook செருகுநிரலுக்கு நகர்த்தப்பட்டது.", "LabelEnableLUFSScanHelp": "டிராக்குகள் முழுவதும் சமமான ஒலியைப் பெற செயலிகள் ஆடியோ பிளேபேக்கை இயல்பாக்கலாம். இது லைப்ரரி ஸ்கேன்களில் தாமதத்தை ஏற்படுத்தும் மற்றும் அதிக கணினி வளங்களை உபயோக படுத்தும் என்பதை நினைவில் கொள்ளவும்.", - "LabelParallelImageEncodingLimitHelp": "இணையாக இயக்க அனுமதிக்கப்படும் பட குறியாக்கங்களின் அதிகபட்ச அளவு. இதை 0 ஆக அமைப்பது உங்கள் கணினி விவரக்குறிப்புகளின் அடிப்படையில் வரம்பை தேர்வு செய்யும்.", + "LabelParallelImageEncodingLimitHelp": "இணையாக இயக்க அனுமதிக்கப்படும் பட குறியாக்கங்களின் அதிகபட்ச எண்ணிக்கை. இதை 0 ஆக அமைப்பது உங்கள் கணினியின் முக்கிய எண்ணிக்கையின் அடிப்படையில் வரம்பை தேர்ந்தெடுக்கும்.", "MessageRenameMediaFolder": "மீடியா லைப்ரரிக்கு மறுபெயரிடுவது அனைத்து மெட்டாடேட்டாவையும் இழக்க நேரிடும், எச்சரிக்கையுடன் தொடரவும்.", "SubtitleRed": "சிவப்பு", "SubtitleWhite": "வெள்ளை", @@ -1846,7 +1846,7 @@ "EncodingFormatHelp": "ஜெல்லிஃபின் மாற்றியமைக்க வேண்டிய வீடியோ குறியாக்கத்தைத் தேர்ந்தெடுக்கவும். தேர்ந்தெடுக்கப்பட்ட வடிவமைப்பிற்கான வன்பொருள் முடுக்கம் கிடைக்காதபோது ஜெல்லிஃபின் மென்பொருள் குறியாக்கத்தைப் பயன்படுத்தும். H264 குறியாக்கம் எப்போதும் இயக்கப்படும்.", "LabelTileWidthHelp": "X திசையில் ஒரு டைலுக்கு அதிகபட்ச படங்களின் எண்ணிக்கை.", "AllowMjpegEncoding": "MJPEG வடிவத்தில் குறியாக்கத்தை அனுமதிக்கவும் (ட்ரிக்ப்ளே உருவாக்கத்தின் போது பயன்படுத்தப்பட்டது)", - "LabelTrickplayAccel": "வன்பொருள் முடுக்கத்தை இயக்கு", + "LabelTrickplayAccel": "வன்பொருள் டிகோடிங்கை இயக்கு", "LabelScanBehavior": "ஸ்கேன் நடத்தை", "PriorityHigh": "உயர்", "LabelImageInterval": "பட இடைவெளி", @@ -1869,5 +1869,39 @@ "PriorityNormal": "இயல்பானது", "PriorityIdle": "செயலற்ற", "LabelProcessPriority": "செயல்முறை முன்னுரிமை", - "LabelQscale": "Qscale" + "LabelQscale": "Qscale", + "EnableTrueHdHelp": "உங்கள் சாதனம் TrueHD ஐ ஆதரித்தால் அல்லது இணக்கமான ஆடியோ ரிசீவருடன் இணைக்கப்பட்டிருந்தால் மட்டுமே இயக்கவும், இல்லையெனில் அது பிளேபேக் தோல்வியை ஏற்படுத்தலாம்.", + "LibraryScanFanoutConcurrencyHelp": "லைப்ரரி ஸ்கேன்களின் போது இணையான பணிகளின் அதிகபட்ச எண்ணிக்கை. இதை 0 ஆக அமைப்பது உங்கள் கணினியின் முக்கிய எண்ணிக்கையின் அடிப்படையில் வரம்பை தேர்ந்தெடுக்கும். எச்சரிக்கை: இந்த எண்ணை மிக அதிகமாக அமைப்பதால் பிணைய கோப்பு முறைமைகளில் சிக்கல்கள் ஏற்படலாம்; நீங்கள் சிக்கல்களை எதிர்கொண்டால், இந்த எண்ணைக் குறைக்கவும்.", + "PlaylistError.CreateFailed": "பிளேலிஸ்ட்டை உருவாக்குவதில் பிழை", + "PlaylistError.AddFailed": "பிளேலிஸ்ட்டில் சேர்ப்பதில் பிழை", + "SaveLyricsIntoMediaFolders": "மீடியா கோப்புறைகளில் பாடல் வரிகளைச் சேமிக்கவும்", + "LibraryScanFanoutConcurrency": "இணை நூலக ஸ்கேன் பணிகள் வரம்பு", + "ViewLyrics": "பாடல் வரிகளைப் பார்க்கவும்", + "SavePassword": "கடவுச்சொல்லை சேமிக்கவும்", + "Author": "நூலாசிரியர்", + "Colorist": "வண்ணமயமானவர்", + "CoverArtist": "அட்டைப்படக் கலைஞர்", + "Creator": "படைப்பாளி", + "DeleteLyrics": "பாடல் வரிகளை நீக்கவும்", + "Editor": "ஆசிரியர்", + "EnableTrueHd": "TrueHD ஐ இயக்கவும்", + "Illustrator": "சித்திரக்காரர்", + "Inker": "இன்கர்", + "Letterer": "கடிதம் எழுதுபவர்", + "Penciller": "பென்சிலர்", + "SaveLyricsIntoMediaFoldersHelp": "ஆடியோ கோப்புகளுக்கு அடுத்ததாக பாடல் வரிகளை சேமிப்பது அவற்றை எளிதாக நிர்வகிக்க அனுமதிக்கும்.", + "Translator": "மொழிபெயர்ப்பாளர்", + "EnableDts": "DTS (DCA) ஐ இயக்கு", + "EnableDtsHelp": "உங்கள் சாதனம் DTSஐ ஆதரித்தால் அல்லது இணக்கமான ஆடியோ ரிசீவருடன் இணைக்கப்பட்டிருந்தால் மட்டுமே இயக்கவும், இல்லையெனில் அது பிளேபேக் தோல்வியை ஏற்படுத்தக்கூடும்.", + "HeaderDeleteLyrics": "பாடல் வரிகளை நீக்கு", + "HeaderVideoAdvanced": "வீடியோ மேம்பட்டது", + "Lyrics": "பாடல் வரிகள்", + "ConfirmDeleteLyrics": "இந்தப் பாடல் வரிகளை நீக்குவது கோப்பு முறைமை மற்றும் உங்கள் மீடியா லைப்ரரி இரண்டிலிருந்தும் நீக்கப்படும். நீங்கள் நிச்சயமாக தொடர விரும்புகிறீர்களா?", + "LabelTrickplayAccelEncodingHelp": "தற்போது QSV மற்றும் VAAPI இல் மட்டுமே கிடைக்கிறது, இந்த விருப்பம் மற்ற வன்பொருள் முடுக்க முறைகளில் எந்த விளைவையும் ஏற்படுத்தாது.", + "LabelTrickplayAccelEncoding": "வன்பொருள் துரிதப்படுத்தப்பட்ட MJPEG குறியாக்கத்தை இயக்கவும்", + "PlaylistPublic": "பொது அணுகலை அனுமதிக்கவும்", + "PlaylistPublicDescription": "உள்நுழைந்துள்ள எவரும் இந்த பிளேலிஸ்ட்டைப் பார்க்க அனுமதிக்கவும்.", + "ErrorDeletingLyrics": "சேவையகத்திலிருந்து பாடல் வரிகளை நீக்குவதில் பிழை. ஜெல்லிஃபின் மீடியா கோப்புறையில் எழுதுவதற்கான அணுகலைப் பெற்றுள்ளதா என்பதைச் சரிபார்த்து, மீண்டும் முயற்சிக்கவும்.", + "HeaderNoLyrics": "பாடல் வரிகள் எதுவும் கிடைக்கவில்லை", + "HeaderLyricDownloads": "பாடல் வரிகள் பதிவிறக்கம்" } diff --git a/src/strings/tr.json b/src/strings/tr.json index 016588109a..246eddccbb 100644 --- a/src/strings/tr.json +++ b/src/strings/tr.json @@ -580,7 +580,7 @@ "ClientSettings": "İstemci Ayarları", "BoxSet": "Seri Filmler", "AskAdminToCreateLibrary": "Bir yöneticiden kütüphane oluşturmasını isteyin.", - "AllowFfmpegThrottlingHelp": "Video kod dönüştürme işlemleri yeterince ilerlediyse kaynak tüketimini azaltmak için durdur. İleri/geri sarma işlemlerinin az yapıldığı durumlarda çok kullanışlıdır. Oynatım sorunları ile karşılaşırsanız bu özelliği kapatın.", + "AllowFfmpegThrottlingHelp": "Video kod dönüştürme işlemleri yeterince ilerlediyse daha az kaynak tüketmesi için işlem duraklatılır. İleri/geri sarma işlemlerinin az yapıldığı durumlarda çok kullanışlıdır. Oynatım sorunları ile karşılaşırsanız bu özelliği kapatın.", "AlbumArtist": "Albüm Sanatçısı", "HeaderTuners": "Alıcılar", "HeaderTranscodingProfileHelp": "Kod dönüştürme gerektiğinde hangi biçimin kullanılacağını belirlemek için kod dönüştürme profilleri ekle.", @@ -695,7 +695,7 @@ "LabelAudioBitrate": "Ses bit hızı", "LabelAudioBitDepth": "Ses bit derinliği", "LabelArtistsHelp": "Birden çok sanatçıyı noktalı virgülle ayırın.", - "LabelAppNameExample": "Örnek: Sickbeard, Sonarr", + "LabelAppNameExample": "API anahtarlarını tanımlamak için kullanılan bir ad. Bu ayar işlevselliği etkilemeyecektir.", "LabelAllowedRemoteAddressesMode": "Uzak IP adresi filtre modu", "LabelAllowedRemoteAddresses": "Uzak IP adresi filtresi", "LabelAlbumArtists": "Albüm sanatçıları", @@ -890,7 +890,7 @@ "HeaderNetworking": "IP Protokolleri", "HeaderDebugging": "Hata ayıklama ve izleme", "EnableTonemapping": "Ton eşlemeyi etkinleştir", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver DeInterlacing Filter (BWDIF)", "Sort": "Sırala", "Shuffle": "Karıştır", "Suggestions": "Öneriler", @@ -1630,7 +1630,7 @@ "EnableFallbackFontHelp": "Özel alternatif yazı tiplerini etkinleştirin. Bu, yanlış altyazı oluşturma sorununu önleyebilir.", "EnableFallbackFont": "Yedek yazı tiplerini etkinleştir", "HeaderSelectFallbackFontPath": "Yedek Yazı Tipi Klasörü Yolunu Seçin", - "Yadif": "YADIF", + "Yadif": "Yet Another DeInterlacing Filter (YADIF)", "XmlTvSportsCategoriesHelp": "Bu kategorilere sahip programlar spor programları olarak gösterilecektir. Birden çok girdiyi '|' ile ayırın.", "XmlTvPathHelp": "Bir XMLTV dosya yolu. Jellyfin bu dosyayı okuyacak ve güncellemeler için düzenli olarak kontrol edecektir. Dosyayı oluşturmak ve güncellemek sizin sorumluluğunuzdadır.", "XmlTvNewsCategoriesHelp": "Bu kategorilere sahip programlar haber programları olarak gösterilecektir. Birden çok girdiyi '|' ile ayırın.", @@ -1730,7 +1730,7 @@ "LabelDummyChapterDuration": "Aralık", "LabelChapterImageResolutionHelp": "Çıkarılan bölüm resimleri çözünürlüğü. Bunu değiştirmenin mevcut sahte bölümler üzerinde hiçbir etkisi olmayacaktır.", "LabelParallelImageEncodingLimit": "Paralel resim kodlama sınırı", - "LabelParallelImageEncodingLimitHelp": "Paralel olarak çalışmasına izin verilen maksimum resim kodlaması miktarı. Bunu 0 olarak ayarlamak, sistem özelliklerinize göre bir sınır seçecektir.", + "LabelParallelImageEncodingLimitHelp": "Paralel olarak çalışmasına izin verilen maksimum resim kodlaması sayısı. Bunu 0 olarak ayarlamak, sisteminizin çekirdek sayısına göre bir sınır seçecektir.", "AllowSegmentDeletionHelp": "İstemcinin indirdiği eski segmentleri silin. Bu işlem tamamen dönüştürülmüş dosyaların diskte yer kaplamasına engel olur. Eğer oynatımda problem yaşıyorsanız lütfen bu seçeneği devre dışı bırakın.", "LabelDeveloper": "Geliştirici", "HeaderEpisodesStatus": "Bölüm Durumu", @@ -1852,5 +1852,33 @@ "EnableLibrary": "Kütüphaneyi etkinleştir", "EnableLibraryHelp": "Kütüphanenin devre dışı bırakılması kütüphaneyi tüm kullanıcı görünümlerinden gizleyecektir.", "LabelTrickplayAccelEncoding": "Donanım hızlandırmalı MJPEG kodlamayı etkinleştir", - "LabelTrickplayAccelEncodingHelp": "Şu anda yalnızca QSV ve VAAPI'de kullanılabilir. Bu seçeneğin diğer donanım hızlandırma yöntemleri üzerinde bir etkisi yoktur." + "LabelTrickplayAccelEncodingHelp": "Şu anda yalnızca QSV ve VAAPI'de kullanılabilir. Bu seçeneğin diğer donanım hızlandırma yöntemleri üzerinde bir etkisi yoktur.", + "HeaderDeleteLyrics": "Şarkı Sözlerini Sil", + "ViewLyrics": "Şarkı sözünü göster", + "ConfirmDeleteLyrics": "Bu şarkı sözlerini silmek, onları hem dosya sisteminden hem de medya kütüphanenizden silecektir. Devam etmek istediğinizden emin misiniz?", + "ErrorDeletingLyrics": "Şarkı sözlerini sunucudan silerken bir hata oluştu. Lütfen Jellyfin'in medya klasörüne yazma erişimi olup olmadığını kontrol edin ve tekrar deneyin.", + "DeleteLyrics": "Şarkı sözünü sil", + "HeaderNoLyrics": "Şarkı sözü bulunamadı", + "Lyrics": "Şarkı sözü", + "SavePassword": "Parolayı Kaydet", + "PlaylistError.CreateFailed": "Çalma listesi oluşturulamadı", + "LibraryScanFanoutConcurrency": "Paralel kütüphane tarama görevleri sınırı", + "LibraryScanFanoutConcurrencyHelp": "Kütüphane taramaları sırasında maksimum paralel görev sayısı. Bunu 0 olarak ayarlamak, sisteminizin çekirdek sayısına göre bir sınır seçecektir. UYARI: Bu sayının çok yüksek ayarlanması ağ dosya sistemlerinde sorunlara neden olabilir; sorunla karşılaşırsanız bu sayıyı düşürün.", + "PlaylistError.AddFailed": "Çalma listesine eklenemedi", + "SaveLyricsIntoMediaFoldersHelp": "Şarkı sözlerini ses dosyalarının yanında saklamak, bunların daha kolay yönetilmesini sağlayacaktır.", + "SaveLyricsIntoMediaFolders": "Şarkı sözlerini medya klasörlerine kaydet", + "Author": "Yazar", + "Colorist": "Renklendiren", + "CoverArtist": "Kapak sanatçısı", + "Creator": "Yaratıcı", + "Editor": "Editör", + "Illustrator": "İllüstratör", + "Translator": "Çeviri", + "EnableDts": "DTS'yi (DCA) etkinleştir", + "EnableTrueHd": "TrueHD'yi etkinleştir", + "EnableTrueHdHelp": "Yalnızca cihazınız TrueHD'yi destekliyorsa veya uyumlu bir ses alıcısına bağlıysa etkinleştirin; aksi takdirde oynatma hatasına neden olabilir.", + "EnableDtsHelp": "Yalnızca cihazınız DTS'yi destekliyorsa veya uyumlu bir ses alıcısına bağlıysa etkinleştirin; aksi takdirde oynatma hatasına neden olabilir.", + "PlaylistPublic": "Genel erişime izin ver", + "PlaylistPublicDescription": "Bu oynatma listesinin oturum açmış herhangi bir kullanıcı tarafından görüntülenmesine izin verin.", + "HeaderLyricDownloads": "Şarkı Sözü İndirme" } diff --git a/src/strings/uk.json b/src/strings/uk.json index 6d9ab023c6..9e21e28e29 100644 --- a/src/strings/uk.json +++ b/src/strings/uk.json @@ -284,7 +284,7 @@ "DashboardArchitecture": "Архітектура: {0}", "DailyAt": "Щодня о {0}", "ClearQueue": "Очистити чергу", - "Bwdif": "Фільтр BWDIF", + "Bwdif": "Фільтр деінтерлейсингу Боба Уівера (BWDIF)", "ButtonUseQuickConnect": "Використати Quick Connect", "ButtonPlayer": "Програвач", "ButtonCast": "Трансляція на пристрій", @@ -558,7 +558,7 @@ "LabelAudioSampleRate": "Розрядність аудіо", "LabelAudioBitDepth": "Розрядність аудіо", "LabelArtistsHelp": "Розділіть декількох виконавців крапкою з комою.", - "LabelAppNameExample": "Приклад: Боляча борода, Sonarr", + "LabelAppNameExample": "Людська назва для ідентифікації API-ключів. Цей параметр не впливає на функціональність.", "LabelAlbumArtPN": "Обкладинка альбому PN", "LabelAlbumArtists": "Виконавці альбому", "LabelAlbumArtHelp": "PN використовується для обкладинки альбому в атрибуті 'dlna:profileID' в 'upnp:albumArtURI'. Деякі пристрої вимагають певного значення, незалежно від розміру зображення.", @@ -1553,7 +1553,7 @@ "HeaderSelectFallbackFontPath": "Оберіть шлях до теки резервного шрифту", "Yesterday": "Вчора", "Yes": "Так", - "Yadif": "YADIF", + "Yadif": "Ще один фільтр деінтерлейсингу (YADIF)", "XmlTvSportsCategoriesHelp": "Програми з цими категоріями відображатимуться як спортивні програми. Розділіть множинні символом «|».", "XmlTvNewsCategoriesHelp": "Програми з цими категоріями відображатимуться як програми новин. Розділіть множинні символом «|».", "XmlTvMovieCategoriesHelp": "Програми з цими категоріями відображатимуться як фільми. Розділіть множинні символом «|».", @@ -1716,7 +1716,7 @@ "Featurette": "Художник", "HeaderPerformance": "Продуктивність", "LabelParallelImageEncodingLimit": "Обмеження на паралельне кодування зображень", - "LabelParallelImageEncodingLimitHelp": "Максимальна кількість кодувань зображень, які дозволено запускати паралельно. Якщо встановити значення 0, буде обрано обмеження на основі характеристик вашої системи.", + "LabelParallelImageEncodingLimitHelp": "Максимальна кількість кодувань зображень, які дозволено запускати паралельно. Якщо встановити значення 0, буде обрано обмеження на основі кількості ядер у вашій системі.", "LabelEnableAudioVbrHelp": "Змінний бітрейт забезпечує краще співвідношення якості до середнього бітрейту, але в деяких рідкісних випадках може спричинити проблеми з буферизацією та сумісністю.", "LabelEnableAudioVbr": "Увімкнути VBR", "Select": "Обрати", @@ -1864,5 +1864,27 @@ "HeaderDeleteLyrics": "Видалити текст пісні", "HeaderNoLyrics": "Текст пісні не знайдено", "Lyrics": "Текст пісні", - "ViewLyrics": "Переглянути текст пісні" + "ViewLyrics": "Переглянути текст пісні", + "SavePassword": "Зберегти пароль", + "PlaylistError.AddFailed": "Помилка додавання до списку відтворення", + "PlaylistError.CreateFailed": "Помилка створення списку відтворення", + "SaveLyricsIntoMediaFoldersHelp": "Зберігання текстів пісень поруч з аудіофайлами дозволить легше ними керувати.", + "Author": "Автор", + "Colorist": "Колорист", + "CoverArtist": "Художник обкладинки", + "Creator": "Творець", + "Editor": "Редактор", + "Illustrator": "Ілюстратор", + "Letterer": "Письменник", + "Translator": "Перекладач", + "EnableDts": "Увімкнути DTS (DCA)", + "EnableDtsHelp": "Увімкніть, якщо ваш пристрій підтримує DTS або підключений до сумісного аудіо ресивера, інакше це може призвести до збоїв у відтворенні.", + "EnableTrueHd": "Увімкнути TrueHD", + "EnableTrueHdHelp": "Увімкніть, якщо ваш пристрій підтримує TrueHD або підключений до сумісного аудіо приймача, інакше це може призвести до збоїв у відтворенні.", + "PlaylistPublic": "Дозволити публічний доступ", + "PlaylistPublicDescription": "Дозвольте переглядати цей список відтворення будь-якому зареєстрованому користувачеві.", + "HeaderLyricDownloads": "Завантаження текстів пісень", + "SaveLyricsIntoMediaFolders": "Зберігати тексти пісень в теках з медіафайлами", + "LibraryScanFanoutConcurrencyHelp": "Максимальна кількість паралельних завдань під час сканування медіатеки. Якщо встановити значення 0, буде обрано обмеження на основі кількості ядер у вашій системі. ПОПЕРЕДЖЕННЯ: Занадто високе значення цього параметра може спричинити проблеми з мережевими файловими системами; якщо ви зіткнулися з такими проблемами, зменшіть це значення.", + "LibraryScanFanoutConcurrency": "Обмеження на паралельне сканування медіатек" } diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index f78bb196a9..d5f6104d78 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -398,7 +398,7 @@ "LabelAllowedRemoteAddresses": "远程IP地址过滤器", "LabelAllowedRemoteAddressesMode": "远程IP地址过滤器模式", "LabelAppName": "APP名称", - "LabelAppNameExample": "例如:Sickbeard, Sonarr", + "LabelAppNameExample": "用于识别 API 密钥的可读名称。此设置不影响功能。", "LabelArtists": "艺术家", "LabelArtistsHelp": "将多个艺术家用分号分隔。", "LabelAudioLanguagePreference": "首选音频语言", @@ -457,7 +457,7 @@ "LabelDownloadLanguages": "下载语言", "LabelDropImageHere": "拖拽或点击选择图像于此处。", "LabelDroppedFrames": "丢弃的帧", - "LabelDropShadow": "阴影", + "LabelDropShadow": "字体描边", "LabelDynamicExternalId": "{0} Id", "LabelEasyPinCode": "简单 PIN 码", "LabelEmbedAlbumArtDidl": "在DIDL中嵌入专辑封面", @@ -523,7 +523,7 @@ "LabelKodiMetadataSaveImagePaths": "保存图像路径在NFO文件", "LabelKodiMetadataSaveImagePathsHelp": "如果你的图像文件名不符合Kodi的规范,推荐使用。", "LabelKodiMetadataUser": "为以下用户保存观看历史数据到 NFO 文件中", - "LabelKodiMetadataUserHelp": "保存观看历史数据至 NFO 文件中以供其他应用程序利用。", + "LabelKodiMetadataUserHelp": "保存观看历史数据至 NFO 文件中以供其他应用程序使用。", "LabelLanNetworks": "局域网", "LabelLanguage": "语言", "LabelLineup": "排队", @@ -705,7 +705,7 @@ "LabelffmpegPathHelp": "FFmpeg 应用文件或包含 FFmpeg 的文件夹的路径。", "LanNetworksHelp": "在强制带宽限制时,认作本地网络上的 IP 地址或 IP/网络掩码条目的逗号分隔列表。如果设置此项,所有其它 IP 地址将被视为在外部网络上,并且将受到外部带宽限制。如果保留为空,则只将服务器的子网视为本地网络。", "Large": "大", - "LatestFromLibrary": "最近添加于 {0}", + "LatestFromLibrary": "最近添加的 {0}", "LearnHowYouCanContribute": "了解如何贡献。", "LibraryAccessHelp": "选择共享给此用户的媒体库。管理员有权使用媒体资料管理器来编辑所有文件夹。", "List": "列表", @@ -924,7 +924,7 @@ "PasswordResetComplete": "密码已重置。", "PasswordResetConfirmation": "你确定要重置密码?", "PasswordSaved": "密码已保存。", - "People": "人物", + "People": "演职人员", "PerfectMatch": "最佳匹配", "Photos": "照片", "PictureInPicture": "画中画", @@ -1019,7 +1019,7 @@ "SortName": "排序名称", "Sports": "体育", "StopRecording": "停止录制", - "Studios": "工作室", + "Studios": "制片发行商", "SubtitleAppearanceSettingsAlsoPassedToCastDevices": "这些设置也会被应用于任何通过此设备发起的 Google Cast 播放。", "SubtitleAppearanceSettingsDisclaimer": "以下设置不适用于上述图形字幕或嵌入其自身样式的 ASS/SSA 字幕。", "SubtitleDownloadersHelp": "按优先顺序启用并排列您的首选字幕下载程序。", @@ -1270,7 +1270,7 @@ "EveryXMinutes": "每 {0} 分钟", "WriteAccessRequired": "Jellyfin需要此文件夹的写入权限。请确认是否拥有写入权限并重试。", "PathNotFound": "无法找到此路径。请确认路径有效并重试。", - "Yadif": "YADIF", + "Yadif": "另一种去隔行滤镜(YADIF)", "LabelDeinterlaceMethod": "反交错方法", "DeinterlaceMethodHelp": "选择对隔行扫描内容进行软转码时所用的反交错方法。当启用支持硬件反交错的硬件加速后,将使用硬件解码器代替此设置。", "LabelLibraryPageSize": "媒体库分页阈值", @@ -1408,7 +1408,7 @@ "Data": "数据", "UseDoubleRateDeinterlacing": "反交错时使帧率翻倍", "UseDoubleRateDeinterlacingHelp": "此设置使用去隔行时的场频,通常称为 Bob 去隔行,它将视频的帧频加倍,以提供完整的运动效果,就像在电视上观看隔行视频时看到的那样。", - "Bwdif": "BWDIF", + "Bwdif": "Bob Weaver 去隔行滤镜(BWDIF)", "QuickConnectNotActive": "快速连接在此服务器上未启用", "QuickConnectNotAvailable": "联系您的服务器管理员以启用快速连接", "QuickConnectInvalidCode": "无效的快速连接验证码", @@ -1626,7 +1626,7 @@ "ShowParentImages": "显示节目图片", "AllowEmbeddedSubtitlesAllowTextOption": "允许文本", "AllowEmbeddedSubtitlesAllowImageOption": "允许图像", - "AllowEmbeddedSubtitlesAllowNoneOption": "允许无", + "AllowEmbeddedSubtitlesAllowNoneOption": "不允许", "AllowEmbeddedSubtitlesAllowAllOption": "允许全部", "AllowEmbeddedSubtitlesHelp": "禁用媒体容器中封装的字幕。 需要对媒体库进行全面刷新。", "AllowEmbeddedSubtitles": "禁用不同类型的嵌入字幕", @@ -1642,7 +1642,7 @@ "ButtonBackspace": "退格", "EnableRewatchingNextUpHelp": "启用在“接下来”模块中显示已观看的剧集。", "Localization": "本地化", - "ItemDetails": "文件详情", + "ItemDetails": "项目详情", "EnableRewatchingNextUp": "在接下来界面中启用重新播放", "Production": "制片", "StoryArc": "故事线", @@ -1652,7 +1652,7 @@ "EnableEnhancedNvdecDecoderHelp": "增强的 NVDEC 实现,如果遇到解码错误,请禁用此选项以使用 CUVID。", "HomeVideosPhotos": "家庭视频和照片", "Bold": "粗体", - "LabelTextWeight": "文字粗细", + "LabelTextWeight": "文本粗细", "EnableSplashScreen": "显示启动画面", "MediaInfoDvBlSignalCompatibilityId": "杜比视界 BL 兼容性序号", "MediaInfoBlPresentFlag": "杜比视界 BL 存在标记", @@ -1717,7 +1717,7 @@ "SubtitleYellow": "黄色", "Featurette": "花絮", "Short": "短片", - "LabelParallelImageEncodingLimitHelp": "允许并行运行的图像编码的最大数量。设为 0 以根据您的系统配置自动设置。", + "LabelParallelImageEncodingLimitHelp": "允许并行运行的最大图像编码数量。 将其设置为 0 将根据您的系统核心数量选择限制。", "HeaderPerformance": "性能", "LabelParallelImageEncodingLimit": "并行图像编码限制", "LabelEnableAudioVbr": "启用 VBR 音频编码", @@ -1728,7 +1728,7 @@ "MenuOpen": "打开菜单", "MenuClose": "关闭菜单", "UserMenu": "用户菜单", - "Studio": "广播", + "Studio": "制片发行商", "AllowCollectionManagement": "允许该用户管理收藏夹", "EnableAudioNormalizationHelp": "音频标准化将添加一个恒定的增益,以保持平均音量在所需的级别(-18dB)。", "EnableAudioNormalization": "音频标准化", @@ -1773,7 +1773,7 @@ "ForeignPartsOnly": "仅限强制开启/外语部分", "HearingImpairedShort": "听障/聋哑人士字幕", "UnknownError": "发生未知错误。", - "GoHome": "回家", + "GoHome": "返回主页", "BackdropScreensaver": "背景屏保", "LogoScreensaver": "徽标屏保", "LabelIsHearingImpaired": "用于听障/聋哑人士", @@ -1867,5 +1867,30 @@ "DeleteLyrics": "删除歌词", "HeaderDeleteLyrics": "删除歌词", "HeaderNoLyrics": "未找到歌词", - "ViewLyrics": "查看歌词" + "ViewLyrics": "查看歌词", + "SavePassword": "保存密码", + "EnableDts": "启用 DTS(DCA)", + "EnableDtsHelp": "仅当您的设备支持 DTS 编码或连接到兼容的音频接收器时才启用,否则可能会导致播放失败。", + "EnableTrueHd": "启用 TrueHD", + "HeaderVideoAdvanced": "高级视频选项", + "EnableTrueHdHelp": "仅当您的设备支持 TrueHD 编码或连接到兼容的音频接收器时才启用,否则可能会导致播放失败。", + "HeaderLyricDownloads": "歌词下载", + "SaveLyricsIntoMediaFolders": "将歌词保存到媒体文件夹中", + "SaveLyricsIntoMediaFoldersHelp": "将歌词存储在音频文件旁边将使它们更容易管理。", + "PlaylistPublic": "允许公开访问", + "PlaylistPublicDescription": "允许任何登录用户查看此播放列表。", + "PlaylistError.CreateFailed": "创建播放列表时出错", + "PlaylistError.AddFailed": "添加到播放列表时出错", + "Author": "作者", + "Colorist": "着色师", + "CoverArtist": "封面艺术家", + "Creator": "创作者", + "Editor": "编辑", + "Illustrator": "插画师", + "Inker": "着墨师", + "Letterer": "文字书写员", + "Penciller": "铅笔师", + "Translator": "译者", + "LibraryScanFanoutConcurrency": "并行媒体库扫描任务限制", + "LibraryScanFanoutConcurrencyHelp": "媒体库扫描期间并行任务的最大数量。将其设置为 0 将根据您的系统核心数量选择限制。警告:将此数字设置得太高可能会导致网络文件系统出现问题; 如果您遇到问题,请降低此数字。" } diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index cd01fcfd76..5a1423f6c5 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -3,7 +3,7 @@ "All": "全部", "AllowRemoteAccessHelp": "如果未勾選,所有遠端連線都將被阻擋。", "Browse": "瀏覽", - "MessageBrowsePluginCatalog": "瀏覽我們的附加元件目錄來查看可用的附加元件。", + "MessageBrowsePluginCatalog": "瀏覽我們的擴充功能目錄來查看可用的擴充功能。", "ButtonAddServer": "新增伺服器", "ButtonAddUser": "新增使用者", "ButtonCancel": "取消", @@ -35,26 +35,26 @@ "FileReadError": "在讀取檔案時發生錯誤。", "Friday": "星期五", "GuideProviderLogin": "登入", - "HeaderActiveRecordings": "正在錄影的節目", - "HeaderAdditionalParts": "附加部份", + "HeaderActiveRecordings": "正在錄製的節目", + "HeaderAdditionalParts": "額外的部份", "HeaderAdmin": "管理", "HeaderCustomDlnaProfiles": "自訂設定檔", "HeaderDeleteItem": "刪除項目", "HeaderEasyPinCode": "簡易 PIN 碼", - "HeaderFeatureAccess": "功能存取", - "HeaderFetchImages": "抓取圖片", + "HeaderFeatureAccess": "可用的功能", + "HeaderFetchImages": "擷取圖片", "HeaderFrequentlyPlayed": "經常播放", "HeaderGuideProviders": "節目表提供者", "HeaderImageSettings": "圖像設定", - "HeaderInstantMix": "瞬時混播", + "HeaderInstantMix": "即使混音", "HeaderLatestEpisodes": "最新劇集", "HeaderLatestMovies": "最新電影", - "HeaderLatestRecordings": "最新錄影的節目", + "HeaderLatestRecordings": "最新錄製的節目", "HeaderMediaFolders": "媒體資料夾", "HeaderPaths": "路徑", "HeaderPlayAll": "全部播放", "HeaderPleaseSignIn": "請登入", - "HeaderPreferredMetadataLanguage": "首選媒體資訊語言", + "HeaderPreferredMetadataLanguage": "偏好媒體資訊語言", "HeaderRecentlyPlayed": "最近播放", "HeaderScenes": "場景", "HeaderSelectServerCachePath": "選擇伺服器快取路徑", @@ -63,12 +63,12 @@ "HeaderUsers": "使用者", "Help": "說明", "ItemCount": "{0}個項目", - "LabelAudioLanguagePreference": "音訊語言偏好選項", + "LabelAudioLanguagePreference": "偏好的音軌語言", "LabelCachePath": "快取路徑", - "LabelCollection": "收藏櫃", + "LabelCollection": "系列", "LabelContentType": "內容類型", "LabelCountry": "國家/地區", - "LabelCurrentPassword": "當前的密碼", + "LabelCurrentPassword": "目前密碼", "LabelDay": "星期", "LabelEnableDlnaClientDiscoveryInterval": "尋找用戶端時間間隔", "LabelEnableDlnaDebugLogging": "記錄 DLNA 除錯資料到日誌", @@ -81,8 +81,8 @@ "LabelFinish": "完成", "LabelServerNameHelp": "名稱將作為伺服器名稱,預設是伺服器的主機名稱。", "LabelLanguage": "語言", - "LabelMaxBackdropsPerItem": "每個項目背景的最大數目", - "LabelMaxParentalRating": "最大允許的家長評級", + "LabelMaxBackdropsPerItem": "每個項目的最大背景數量", + "LabelMaxParentalRating": "最大允許的年齡分級", "LabelMaxResumePercentage": "最大繼續播放百分比", "LabelMaxResumePercentageHelp": "媒體若於此時間後停止,會被認定為已播放。", "LabelMaxScreenshotsPerItem": "每件物品截圖的最大數量:", @@ -93,7 +93,7 @@ "LabelMinResumePercentage": "最低繼續播放百分比", "LabelMinResumePercentageHelp": "媒體如果在這個時間之前停止,會被認定為未播放。", "LabelMinScreenshotDownloadWidth": "最小截圖下載寬度:", - "LabelName": "名字", + "LabelName": "名稱", "LabelNewPassword": "新密碼", "LabelNewPasswordConfirm": "確認新密碼", "LabelPassword": "密碼", @@ -186,7 +186,7 @@ "TabCatalog": "目錄", "TabLatest": "最新", "TabMusic": "音樂", - "TabMyPlugins": "我的附加元件", + "TabMyPlugins": "我的擴充功能", "TabNetworks": "電視網路", "TabProfiles": "設定", "TabServer": "伺服器", @@ -197,7 +197,7 @@ "TrackCount": "{0} 個曲目", "Tuesday": "星期二", "UninstallPluginConfirmation": "你確定要解除安裝 {0}?", - "HeaderUninstallPlugin": "解除安裝附加元件", + "HeaderUninstallPlugin": "解除安裝擴充功能", "UserProfilesIntro": "Jellyfin 可單獨對使用者進行設定,所有使用者擁有自己的顯示設定,播放狀態和家長控制。", "Wednesday": "星期三", "WelcomeToProject": "歡迎使用 Jellyfin!", @@ -250,7 +250,7 @@ "AllEpisodes": "所有集數", "AllowHWTranscodingHelp": "若啟用,將會允許調解器同步轉檔。能夠減少伺服器轉檔需求。", "AllowOnTheFlySubtitleExtraction": "允許即時提取字幕", - "AllowOnTheFlySubtitleExtractionHelp": "從影片中提取內建字幕並以純文字的形式顯示以避免影片轉檔。某些系統中提取的過程可能花費較長時間並導致影片播放出現停滯。若停用這個選項,當內建字幕不被播放端設備支援時,字幕將透過轉檔燒錄至影片中。", + "AllowOnTheFlySubtitleExtractionHelp": "從影片中提取內建字幕並以純文字的形式顯示以避免影片轉檔。某些系統中提取的過程可能花費較長時間並導致影片播放出現停滯。若停用這個選項,當內建字幕不被播放端裝置支援時,字幕將透過轉檔燒錄至影片中。", "AllowedRemoteAddressesHelp": "可以從非本地連線的 IP 位址或 IP/子網域遮罩清單,用逗號分隔。 留白則允許所有IP。", "BookLibraryHelp": "支援有聲書和電子書。請參閱 {0} 書籍命名指南 {1}。", "Box": "盒子", @@ -359,7 +359,7 @@ "Episodes": "劇集", "ErrorAddingListingsToSchedulesDirect": "在將電視節目時間表新增到您的 Schedules Direct 帳號時出現錯誤。每個 Schedules Direct 帳號只允許有限的時間表。您在繼續前可能需要登入 Schedules Direct 網站並刪除帳號中的其它項目。", "ErrorAddingMediaPathToVirtualFolder": "新增媒體路徑時發生錯誤,請確認路徑是否有效,且 Jellyfin 具此位置的存取權。", - "ErrorAddingTunerDevice": "新增解碼器設備時發生錯誤,請確認它是否可被存取後重試。", + "ErrorAddingTunerDevice": "新增電視解碼器裝置時發生錯誤,請確認它是否可被存取後重試。", "ErrorAddingXmlTvFile": "存取 XMLTV 檔案時發生錯誤,請確認此檔案是否存在後重試。", "ErrorDeletingItem": "從伺服器刪除項目時發生錯誤,請確認伺服器對此位置有寫入權限並重試。", "ErrorGettingTvLineups": "下載電視節目表時發生錯誤,請確認你的資訊是否正確後重試。", @@ -371,30 +371,30 @@ "ExtraLarge": "特大", "ExtractChapterImagesHelp": "擷取章節圖片將允許 Jellyfin 顯示圖片形式的章節選單,過程可能會非常緩慢、佔用大量 CPU 資源,並且可能需要幾 GB 的硬碟空間。擷取會在影片被偵測到時啟動,同時也可作為一個夜間排程工作運行,這個工作可以在「排程工作」選項中進行設定,不建議在尖峰時段進行這個工作。", "Extras": "額外", - "FFmpegSavePathNotFound": "我們無法通過你輸入的路徑找到 FFmpeg。 FFprobe 同樣也是必要且應該被放在同一個資料夾中。他們通常會被打包在一起以供下載。請檢查這個路徑後重試。", + "FFmpegSavePathNotFound": "我們無法通過你輸入的路徑找到 FFmpeg。 FFprobe 同樣也是必要的,且必須被放在同一個資料夾中。他們通常會被打包在一起以供下載。請檢查這個路徑後重試。", "FastForward": "快轉", "Favorites": "我的最愛", "Features": "功能", "FileReadCancelled": "檔案讀取已取消。", - "Filters": "濾鏡", + "Filters": "篩選器", "Folders": "資料夾", "FormatValue": "格式:{0}", "Fullscreen": "全螢幕", "General": "一般", - "Genre": "類型", + "Genre": "風格", "Genres": "風格", - "GroupBySeries": "按系列分組", - "GroupVersions": "按版本分組", - "GuestStar": "客串", + "GroupBySeries": "按系列分類", + "GroupVersions": "按版本分類", + "GuestStar": "客串演員", "Guide": "指南", "GuideProviderSelectListings": "選擇清單", - "H264CrfHelp": "Constant Rate Factor(CRF)是 x264 和 x265 軟體編碼器的品質設定。 有效範圍為 0 - 51,數值越低品質越好(檔案較大)。 推薦值為18到28之間。x264的預設值為23,x265的預設值為28。硬體編碼器不會使用這些設定值。", + "H264CrfHelp": "Constant Rate Factor(CRF)是 x264 和 x265 軟體編碼器的畫質設定。 有效範圍為 0 - 51,數值越低品質越好(檔案較大)。 建議值為18到28之間。x264的預設值為23,x265的預設值為28。硬體編碼器不會使用這些設定值。", "EncoderPresetHelp": "選擇較快的值以提升效能,或者選擇較慢的值以提升品質。", "HDPrograms": "HD 節目", - "HardwareAccelerationWarning": "啟動硬體加速可能在某些環境下導致系統不穩定。請確認你的作業系統和影片驅動程式是最新的。如果你在開啟此項後難以播放影片,那麼你需要將此選項設回「無」。", - "HeaderAccessSchedule": "存取時程", - "HeaderAccessScheduleHelp": "建立一個存取時程以限制可存取的時段。", - "HeaderActiveDevices": "運行中裝置", + "HardwareAccelerationWarning": "啟動硬體加速可能在某些環境下導致系統不穩定。請確認你的作業系統和顯示驅動程式是最新的。如果你在開啟此項後播放影片遇到困難,請將此選項設定為「無」。", + "HeaderAccessSchedule": "存取時段限制", + "HeaderAccessScheduleHelp": "建立存取時段限制以限制可存取的時段。", + "HeaderActiveDevices": "使用中的裝置", "HeaderActivity": "活動", "HeaderAddToCollection": "加到收藏", "HeaderAddToPlaylist": "加到播放清單", @@ -404,12 +404,12 @@ "HeaderAllowMediaDeletionFrom": "允許從以下位置刪除媒體", "HeaderApiKey": "API 金鑰", "HeaderApiKeys": "API 金鑰", - "HeaderApiKeysHelp": "外部應用程式需要有一個 API 金鑰以用於和伺服器溝通。金鑰會在使用者登入時自動發行,也可以手動產生一個金鑰。", + "HeaderApiKeysHelp": "外部應用程式需要有一個 API 金鑰用於和伺服器溝通。金鑰會在使用者登入時自動發放。你也可以手動產生一個金鑰。", "HeaderApp": "應用程式", - "HeaderAppearsOn": "同時出現於", + "HeaderAppearsOn": "出現於", "HeaderAudioBooks": "有聲書", "HeaderAudioSettings": "音訊設定", - "HeaderBlockItemsWithNoRating": "封鎖沒有或無法識別評級的內容", + "HeaderBlockItemsWithNoRating": "封鎖沒有或無法識別分級的內容", "HeaderBranding": "品牌", "HeaderCancelRecording": "取消錄製", "HeaderCancelSeries": "取消系列", @@ -418,36 +418,36 @@ "HeaderChapterImages": "章節圖片", "HeaderCodecProfile": "編碼設定檔", "HeaderCodecProfileHelp": "編碼器的設定檔標明了設備播放特定編碼時的限制;如果在限制之內則媒體將被轉檔,否則編碼器將被設定為直接播放。", - "HeaderConfigureRemoteAccess": "設定遠端訪問", - "HeaderConfirmPluginInstallation": "確認附加元件安裝", + "HeaderConfigureRemoteAccess": "設定遠端存取", + "HeaderConfirmPluginInstallation": "確認擴充功能安裝", "HeaderConfirmProfileDeletion": "確認刪除個人資料", - "HeaderConfirmRevokeApiKey": "重設 API 金鑰", - "HeaderConnectToServer": "連結至伺服器", - "HeaderConnectionFailure": "連結失敗", + "HeaderConfirmRevokeApiKey": "撤銷 API 金鑰", + "HeaderConnectToServer": "連接至伺服器", + "HeaderConnectionFailure": "連接失敗", "HeaderContainerProfile": "影片載體設定", "HeaderContainerProfileHelp": "影片容器的設定檔標明了設備播放特定媒體格式時的限制。如果在限制之內則媒體將被轉檔,否則媒體格式將被設定為直接播放。", - "HeaderContinueListening": "繼續聆聽", + "HeaderContinueListening": "繼續收聽", "HeaderContinueWatching": "繼續觀看", "HeaderDateIssued": "發布日期", "HeaderDefaultRecordingSettings": "預設錄製設定", "HeaderDeleteDevice": "刪除裝置", "HeaderDeleteItems": "刪除項目", - "HeaderDeleteProvider": "刪除供應者", + "HeaderDeleteProvider": "刪除提供者", "HeaderDeleteTaskTrigger": "刪除工作觸發條件", - "HeaderDetectMyDevices": "偵測我的設備", + "HeaderDetectMyDevices": "偵測我的裝置", "HeaderDeveloperInfo": "開發者資訊", - "HeaderDeviceAccess": "允許裝置存取", + "HeaderDeviceAccess": "裝置存取", "HeaderDevices": "裝置", "HeaderDirectPlayProfile": "直接播放設定檔", "HeaderDirectPlayProfileHelp": "新增直接播放設定檔,標明哪些媒體格式設備可以自己處理。", "HeaderDownloadSync": "下載與同步", "HeaderEditImages": "編輯圖片", "HeaderEnabledFields": "已啟用的欄位", - "HeaderEnabledFieldsHelp": "反選欄位以鎖定並不讓其數據被更改。", + "HeaderEnabledFieldsHelp": "取消選取欄位以鎖定並不讓其內容被更改。", "HeaderError": "錯誤", "HeaderExternalIds": "外部 ID", "HeaderFetcherSettings": "擷取器設定", - "HeaderForKids": "給兒童", + "HeaderForKids": "面向兒童", "HeaderHttpHeaders": "HTTP 標頭", "HeaderIdentification": "身份識別", "HeaderIdentificationCriteriaHelp": "至少輸入一個識別標準。", @@ -456,8 +456,8 @@ "HeaderImageOptions": "圖片選項", "HeaderInstall": "安裝", "HeaderKeepRecording": "繼續錄製", - "HeaderKeepSeries": "保存系列", - "HeaderKodiMetadataHelp": "要啟用或停用 NFO 媒體資訊,請在設定裡「建立媒體庫」頁面中編輯「媒體資訊儲存」部分。", + "HeaderKeepSeries": "保留系列", + "HeaderKodiMetadataHelp": "要啟用或停用 NFO 媒體資訊,請在設定中的「媒體庫」頁面中編輯「媒體資訊儲存」設定。", "HeaderLatestMedia": "最新媒體", "HeaderLatestMusic": "最新音樂", "HeaderLibraries": "媒體庫", @@ -465,7 +465,7 @@ "HeaderLibraryFolders": "媒體庫資料夾", "HeaderLibraryOrder": "媒體庫排序", "HeaderLibrarySettings": "媒體庫設定", - "HeaderLiveTvTunerSetup": "電視直播調諧器安裝", + "HeaderLiveTvTunerSetup": "電視直播解碼器設定", "HeaderLoginFailure": "登入失敗", "HeaderMedia": "媒體", "HeaderMetadataSettings": "媒體資訊設定", @@ -482,25 +482,25 @@ "HeaderOnNow": "現正播放", "HeaderOtherItems": "其他項目", "HeaderPassword": "密碼", - "HeaderPasswordReset": "重設密碼", + "HeaderPasswordReset": "重置密碼", "HeaderPhotoAlbums": "相簿", "HeaderPinCodeReset": "重設簡易 PIN 碼", "HeaderPlayOn": "播放在", "HeaderPlayback": "媒體播放", "HeaderPlaybackError": "播放錯誤", - "HeaderPluginInstallation": "附加元件安裝", + "HeaderPluginInstallation": "安裝擴充功能", "HeaderRecordingOptions": "錄影選項", "HeaderRecordingPostProcessing": "錄影後製", "HeaderRemoteControl": "遙控", "HeaderRemoveMediaFolder": "刪除媒體資料夾", - "HeaderRemoveMediaLocation": "刪除媒體位址", - "HeaderRevisionHistory": "更改紀錄", + "HeaderRemoveMediaLocation": "刪除媒體位置", + "HeaderRevisionHistory": "修改紀錄", "HeaderRunningTasks": "正在進行的工作", "HeaderSeasons": "季數", "HeaderSecondsValue": "{0} 秒", - "HeaderSelectPath": "選擇位址", - "HeaderSelectTranscodingPath": "選擇轉檔暫放位址", - "HeaderSelectTranscodingPathHelp": "瀏覽或輸入轉檔用來存暫時資料的位址。資料夾需具寫入權限。", + "HeaderSelectPath": "選擇路徑", + "HeaderSelectTranscodingPath": "選擇轉檔暫存位址", + "HeaderSelectTranscodingPathHelp": "瀏覽或輸入轉檔時使用的暫存資料夾。資料夾需具寫入權限。", "HeaderSendMessage": "傳送訊息", "HeaderSeriesOptions": "系列選項", "HeaderSeriesStatus": "系列狀態", @@ -513,9 +513,9 @@ "HeaderStopRecording": "停止錄影", "HeaderSubtitleAppearance": "字幕外觀", "HeaderSubtitleDownloads": "字幕下載", - "HeaderThisUserIsCurrentlyDisabled": "這個使用者目前停用", - "HeaderTracks": "軌", - "HeaderTunerDevices": "調諧器裝置", + "HeaderThisUserIsCurrentlyDisabled": "這個使用者目前已被停用", + "HeaderTracks": "軌道", + "HeaderTunerDevices": "電視解碼器裝置", "Movies": "電影", "Photos": "相片", "Playlists": "播放清單", @@ -524,12 +524,12 @@ "Sync": "同步", "ValueSpecialEpisodeName": "特輯 - {0}", "AuthProviderHelp": "選擇用於驗證使用者密碼的身份驗證提供者。", - "HeaderParentalRatings": "家長評級", + "HeaderParentalRatings": "年齡分級", "HeaderProfileInformation": "設定檔訊息", "HeaderProfileServerSettingsHelp": "這些數值將控制伺服器如何呈現給設備。", "HeaderResponseProfile": "回覆設定檔", "HeaderResponseProfileHelp": "當播放某些類型的媒體時,回覆設定檔提供一種方法來發送自定訊息到設備。", - "HeaderSelectCertificatePath": "選擇證書路徑", + "HeaderSelectCertificatePath": "選擇憑證路徑", "HeaderSelectMetadataPath": "選擇媒體資訊資料夾", "HeaderSubtitleProfile": "字幕設定檔", "HeaderSubtitleProfiles": "字幕設定檔", @@ -537,8 +537,8 @@ "HeaderTaskTriggers": "工作觸發條件", "HeaderTranscodingProfile": "轉檔設定", "HeaderTranscodingProfileHelp": "新增轉檔設定檔標明哪些媒體格式需要轉檔處理。", - "HeaderTuners": "調諧器", - "HeaderTypeImageFetchers": "圖片獲取程序 ({0})", + "HeaderTuners": "電視解碼器", + "HeaderTypeImageFetchers": "圖片擷取器({0})", "HeaderTypeText": "輸入文字", "HeaderUpcomingOnTV": "即將播放", "HeaderUploadImage": "上傳圖片", @@ -555,17 +555,17 @@ "HideWatchedContentFromLatestMedia": "從最新媒體中隱藏已觀看的內容", "Home": "首頁", "Horizontal": "橫向", - "HttpsRequiresCert": "要啟用安全連線,您需要提供受信任的SSL證書,如 Let's Encrypt。 請提供證書,或停用安全連線。", + "HttpsRequiresCert": "若要啟用安全連線,您需要提供由受信任的單位發放的SSL憑證,如 Let's Encrypt。 請提供憑證,或停用安全連線。", "Identify": "識別", "Images": "圖片", - "ImportFavoriteChannelsHelp": "若啟用,僅於解碼器中被標記為最愛的頻道才會被匯入。", + "ImportFavoriteChannelsHelp": "若啟用,僅於電視解碼器中被標記為最愛的頻道才會被匯入。", "InstallingPackage": "正在安裝 {0}(版本 {1})", "InstantMix": "即時混音", "Items": "項目", "Kids": "兒童", "Label3DFormat": "3D 格式", "LabelAbortedByServerShutdown": "(因為伺服器關閉被中止)", - "LabelAccessDay": "一週中的某一天", + "LabelAccessDay": "星期", "LabelAccessEnd": "結束時間", "LabelAccessStart": "開始時間", "LabelAirDays": "播出日期", @@ -578,56 +578,56 @@ "LabelAlbumArtMaxHeight": "專輯封面最大高度", "LabelAlbumArtMaxWidth": "專輯封面最大寬度", "LabelAlbumArtPN": "專輯封面 PN", - "LabelAlbumArtists": "專輯作家", + "LabelAlbumArtists": "專輯藝人", "LabelAllowHWTranscoding": "允許硬體轉檔", "LabelAllowedRemoteAddresses": "遠端 IP 位址過濾", "LabelAllowedRemoteAddressesMode": "遠端 IP 位址過濾模式", "LabelAppName": "APP 名稱", "LabelAppNameExample": "例如:可愛蹦蹦主機、小安的 Jellyfin", "LabelArtists": "藝人", - "LabelArtistsHelp": "將多位演出者以「;」分隔。", + "LabelArtistsHelp": "將多位演出者以分號(;)分隔。", "LabelAuthProvider": "身份驗證提供者", - "LabelAutomaticallyRefreshInternetMetadataEvery": "從網路自動更新媒體資訊", + "LabelAutomaticallyRefreshInternetMetadataEvery": "自動從網路更新媒體資訊", "LabelBindToLocalNetworkAddress": "綁定本地網路地址", - "LabelBindToLocalNetworkAddressHelp": "(選用)覆蓋 HTTP 伺服器綁定的本地 IP 位址。留空則將監聽所有可用的位址。更改此欄位需重啟伺服器。", + "LabelBindToLocalNetworkAddressHelp": "覆蓋 HTTP 伺服器綁定的本地 IP 位址。留空則將監聽所有可用的位址。更改此欄位需重啟伺服器。", "LabelBirthDate": "出生日期", "LabelBirthYear": "出生年", "LabelBlastMessageInterval": "活動信號的時間間隔", "LabelBlastMessageIntervalHelp": "確定伺服器活動消息之間的持續時間(秒)。", - "LabelBlockContentWithTags": "阻止帶有標籤的項目", + "LabelBlockContentWithTags": "阻擋帶有標籤的項目", "LabelBurnSubtitles": "燒錄字幕", "LabelCache": "快取", - "LabelCachePathHelp": "選擇指定所需的快取檔案(像是圖片)路徑。保留空白以使用預設設定。", + "LabelCachePathHelp": "選擇快取檔案(如圖片)的路徑。保留空白以使用預設設定。", "LabelCancelled": "已取消", - "LabelCertificatePassword": "證書密碼", - "LabelCertificatePasswordHelp": "如果你的證書需要密碼,請在此輸入它。", + "LabelCertificatePassword": "憑證密碼", + "LabelCertificatePasswordHelp": "如果你的憑證需要密碼,請在此輸入它。", "LabelChannels": "頻道", - "LabelCommunityRating": "討論區評分", + "LabelCommunityRating": "社群評分", "LabelCriticRating": "影評評分", - "LabelCustomCertificatePath": "自訂 SSL 證書路徑", - "LabelCustomCertificatePathHelp": "提供包含證書和金鑰的 PKCS #12 文件的路徑以在自訂域名上啟用 TLS。", + "LabelCustomCertificatePath": "自訂 SSL 憑證路徑", + "LabelCustomCertificatePathHelp": "提供包含憑證和金鑰的 PKCS #12 文件的路徑以在自訂域名上啟用 TLS。", "LabelCustomCss": "自訂 CSS", "LabelCustomCssHelp": "於網頁介面套用您自訂的標籤或品牌樣式。", "Depressed": "凹陷", "HeaderSelectMetadataPathHelp": "瀏覽或者輸入儲存媒體資訊的資料夾,請確保資料夾可以寫入。", "HeaderSelectServerCachePathHelp": "瀏覽或者輸入路徑以用於伺服器快取檔案。請確保此資料夾可以被寫入。", - "LabelCustomDeviceDisplayNameHelp": "指定自訂的顯示名稱,或者留空以使用設備自己報告的名稱。", - "LabelCustomRating": "自定義評級", + "LabelCustomDeviceDisplayNameHelp": "指定自訂的顯示名稱,或者留空以使用裝置回報的名稱。", + "LabelCustomRating": "自定義分級", "LabelDashboardTheme": "控制台佈景主題", "LabelDateAdded": "新增日期", - "LabelDateAddedBehavior": "新增內容的添加日期行", + "LabelDateAddedBehavior": "新增內容的添加日期行為", "LabelDateTimeLocale": "設定時區", - "LabelDeathDate": "死亡時間", + "LabelDeathDate": "死亡日期", "LabelDefaultScreen": "預設分頁", "LabelDefaultUser": "預設使用者", "LabelDeviceDescription": "裝置說明", "LabelDidlMode": "DIDL 模式", "LabelDiscNumber": "光碟編號", "LabelDisplayLanguage": "顯示語言", - "LabelDisplayLanguageHelp": "翻譯 Jellyfin 是個進行中的專案。", + "LabelDisplayLanguageHelp": "翻譯 Jellyfin 是個持續的工作。", "LabelDisplayMode": "顯示模式", "LabelDisplayName": "顯示名稱", - "MessageNoPluginsInstalled": "您尚未安裝任何附加元件。", + "MessageNoPluginsInstalled": "您尚未安裝任何擴充功能。", "Mobile": "手機", "Option3D": "3D", "OptionEveryday": "每天", @@ -635,14 +635,14 @@ "LabelAudioBitDepth": "音訊位元深度", "LabelBaseUrl": "根路徑", "LabelIconMaxHeight": "圖示最高高度", - "LabelHttpsPortHelp": "HTTPS 伺服器的 TCP 埠。", + "LabelHttpsPortHelp": "HTTPS 伺服器的 TCP 通訊埠。", "CopyStreamURL": "複製串流網址", "MediaInfoDefault": "預設", "LabelDateAddedBehaviorHelp": "若原本存在媒體資訊,將會優先使用現存資訊。", "LabelScreensaver": "螢幕保護程式", "LabelSeasonNumber": "季", - "LabelDropImageHere": "拖移圖片到這裡,或是點擊來選取。", - "LabelImageType": "圖片格式", + "LabelDropImageHere": "拖放圖片到這裡,或是點擊來選取。", + "LabelImageType": "圖片類別", "LabelIdentificationFieldHelp": "不區分大小寫的子字串或正則表達式。", "Large": "大", "LabelTranscodePath": "轉檔路徑", @@ -670,7 +670,7 @@ "ValueAudioCodec": "音訊編碼:{0}", "ValueCodec": "編碼:{0}", "ValueSongCount": "{0} 首歌", - "LabelFileOrUrl": "檔案或路徑", + "LabelFileOrUrl": "檔案或網址", "LabelKodiMetadataSaveImagePaths": "在 NFO 檔案中儲存圖片路徑", "LabelLanNetworks": "區域網路", "LabelMetadataPathHelp": "儲存下載的圖片與媒體資訊的資料夾。", @@ -690,7 +690,7 @@ "LabelAudioBitrate": "音訊位元率", "LabelAudioCodec": "音訊編碼", "LabelBitrate": "位元率", - "LabelAudioChannels": "音訊聲道", + "LabelAudioChannels": "音訊聲道數", "LabelAudioSampleRate": "音訊取樣率", "LabelFont": "字體", "LabelFolder": "資料夾", @@ -698,11 +698,11 @@ "LabelEnableBlastAliveMessages": "活動訊息", "LabelEnableDlnaServer": "啟用 DLNA 伺服器", "LabelEnableDlnaServerHelp": "允許網路上的 UPnP 設備瀏覽和播放內容。", - "LabelEnableHardwareDecodingFor": "啟用硬體解碼", + "LabelEnableHardwareDecodingFor": "啟用硬體解碼的項目:", "LabelEpisodeNumber": "集數", - "LabelBaseUrlHelp": "您可以在此處自訂伺服器 URL 路徑的子目錄,如:http://example.com/<baseurl>", + "LabelBaseUrlHelp": "您可以在此處自訂伺服器網址的子目錄,如:http://example.com/<baseurl>", "LabelExtractChaptersDuringLibraryScan": "於媒體庫掃描時擷取章節圖片", - "LabelHttpsPort": "本地 HTTPS 埠", + "LabelHttpsPort": "本地 HTTPS 通訊埠", "LabelFailed": "失敗", "LabelSupportedMediaTypes": "支援的媒體類型", "LabelTextBackgroundColor": "文字背景顏色", @@ -764,12 +764,12 @@ "RecentlyWatched": "最近觀賞", "RecommendationBecauseYouLike": "因為您喜歡 {0}", "SearchResults": "搜尋結果", - "TabPlugins": "附加元件", + "TabPlugins": "擴充功能", "Transcoding": "轉檔", "ValueTimeLimitMultiHour": "時間限制:{0} 小時", "ValueVideoCodec": "影片編碼:{0}", "ViewAlbum": "查看專輯", - "LabelKodiMetadataDateFormatHelp": "NFO 檔案中的所有日期都將使用此格式。", + "LabelKodiMetadataDateFormatHelp": "NFO 檔案中的所有日期都將以此格式讀取。", "LabelServerHostHelp": "192.168.1.100:8096 或是 https://myserver.com", "LabelServerName": "伺服器名稱", "LabelTag": "標籤", @@ -787,19 +787,19 @@ "TV": "電視", "Trailers": "預告", "LabelImageFetchersHelp": "啟用並按優先順序排序您的首選圖片擷取器。", - "LabelDownMixAudioScale": "縮混時音訊增強", - "LabelDownMixAudioScaleHelp": "縮混時增強音訊。其中一個音軌將保持原始音量。", + "LabelDownMixAudioScale": "向下混時的音訊增強", + "LabelDownMixAudioScaleHelp": "向下混音時增強音訊。設定為 1 將保持原始音量。", "LabelDownloadLanguages": "下載語言", "LabelDynamicExternalId": "{0} Id", "LabelEasyPinCode": "簡易 PIN 碼", "LabelEnableAutomaticPortMap": "啟用自動通訊埠轉發", "LabelEnableSingleImageInDidlLimit": "限制單個嵌入式圖片", "LabelEndDate": "結束日期", - "LabelLockItemToPreventChanges": "鎖定此項目來避免被更改", + "LabelLockItemToPreventChanges": "鎖定此項目以避免被更改", "LabelManufacturer": "製造商", "LabelLoginDisclaimerHelp": "顯示在登入頁面底部的訊息。", "LabelManufacturerUrl": "製造商網址", - "LabelMaxChromecastBitrate": "Google Cast 串流解析度", + "LabelMaxChromecastBitrate": "Google Cast 串流畫質", "LabelOriginalTitle": "原始標題", "LabelSelectUsers": "選擇使用者", "LabelSelectVersionToInstall": "選擇要安裝的版本", @@ -810,7 +810,7 @@ "MediaInfoTimestamp": "時間戳", "Menu": "選單", "MetadataManager": "媒體資訊管理器", - "MessageNoPluginConfiguration": "這個附加元件沒有選項可供更改。", + "MessageNoPluginConfiguration": "這個擴充功能不需要設定。", "NoSubtitlesHelp": "字幕不會自動讀取,但可於播放時手動選取。", "Normal": "正常", "OptionAllowContentDownloading": "允許下載及同步媒體", @@ -821,15 +821,15 @@ "LabelForgotPasswordUsernameHelp": "假如您還記得的話,請輸入您的使用者名稱。", "LabelFormat": "格式", "LabelFriendlyName": "好聽的名字", - "LabelGroupMoviesIntoCollections": "將電影分組", + "LabelGroupMoviesIntoCollections": "將電影分成系列", "LabelKodiMetadataDateFormat": "發行日期格式", "LabelIconMaxWidth": "Icon 最寬寬度", - "LabelGroupMoviesIntoCollectionsHelp": "選擇檢視電影清單時,集合中的電影將作為一個分組項目顯示。", - "LabelEncoderPreset": "預設編碼", + "LabelGroupMoviesIntoCollectionsHelp": "選擇檢視電影清單時,系列中的電影將作為一個項目顯示。", + "LabelEncoderPreset": "編碼預設", "LabelHardwareAccelerationType": "硬體加速", "LabelImportOnlyFavoriteChannels": "僅限收藏的頻道", "LabelInNetworkSignInWithEasyPassword": "啟用 簡易 PIN code 進行區域網路登入", - "LabelH264Crf": "H.264 編碼 CRF", + "LabelH264Crf": "H.264 編碼 CRF 設定", "LabelMaxStreamingBitrate": "最大串流畫質", "LabelMaxStreamingBitrateHelp": "指定最大串流位元率。", "LabelMessageText": "訊息文字", @@ -895,7 +895,7 @@ "OptionEnableM2tsMode": "啟用 M2TS 模式", "LabelKeepUpTo": "保持", "LabelKidsCategories": "兒童分類", - "LabelKodiMetadataEnablePathSubstitution": "啟用路徑取代", + "LabelKodiMetadataEnablePathSubstitution": "啟用路徑代換", "LabelKodiMetadataEnableExtraThumbs": "複製 extrafanart 到 extrathumbs 欄位", "LabelMovieCategories": "電影分類", "LabelMoviePrefix": "電影前綴", @@ -918,7 +918,7 @@ "ValueSeriesCount": "{0} 劇集", "LabelHardwareAccelerationTypeHelp": "硬體加速需要額外的設定。", "LabelHomeNetworkQuality": "區域網路畫質", - "LabelHomeScreenSectionValue": "主畫面模組 {0}", + "LabelHomeScreenSectionValue": "主畫面區段 {0}", "LabelMetadataDownloadersHelp": "啟用和排序媒體資訊來源的優先度,優先度較低的資訊來源只會用來填補缺少的資訊。", "LabelMetadataReaders": "媒體資訊讀取器", "LabelMetadataSaversHelp": "選取儲存媒體資訊的檔案格式。", @@ -927,7 +927,7 @@ "LabelValue": "數值", "OptionEnableAccessToAllChannels": "允許存取所有頻道", "OptionEnableAccessToAllLibraries": "允許存取所有媒體庫", - "OptionEnableForAllTuners": "開啟所有調諧器", + "OptionEnableForAllTuners": "為所有電視解碼器啟用", "OptionExtractChapterImage": "開啟章節圖片擷取", "OptionEnableM2tsModeHelp": "當編碼為 MPEG-TS 時啟用 M2TS 模式。", "OptionEquals": "等於", @@ -955,8 +955,8 @@ "LabelEnableBlastAliveMessagesHelp": "若此伺服器無法被其他 UPnP 裝置偵測到,請啟用此選項。", "LabelEnableDlnaClientDiscoveryIntervalHelp": "決定兩次 SSDP 搜尋之間的持續時間(以秒為單位)。", "LabelEnableDlnaPlayToHelp": "偵測您網路裡的設備並遠端控制它們。", - "LabelExtractChaptersDuringLibraryScanHelp": "當媒體庫匯入影片並掃描時,將擷取章節圖片。否則,章節圖片將在之後的排程工作中擷取,而媒體庫會更快完成掃描。", - "LabelMoviePrefixHelp": "若前綴套用到電影標題,請在此處輸入它來方便伺服器能夠正確處理。", + "LabelExtractChaptersDuringLibraryScanHelp": "掃描媒體庫並匯入影片時,同時擷取章節圖片。否則,章節圖片將在之後的排程工作中擷取,而媒體庫會更快完成掃描。", + "LabelMoviePrefixHelp": "若前綴套用到電影標題,請在此處輸入它,讓伺服器能夠正確處理。", "LabelMovieRecordingPath": "電影錄製路徑", "LabelNotificationEnabled": "啟用這個通知", "LabelProfileContainersHelp": "以逗號分隔,留空則適用於所有影片容器。", @@ -975,8 +975,8 @@ "LabelSubtitleFormatHelp": "如:SRT", "LabelSubtitlePlaybackMode": "字幕載入", "LabelTranscodingThreadCount": "轉檔執行緒數", - "LabelTunerIpAddress": "調諧器 IP 位址", - "LabelTunerType": "調諧器類型", + "LabelTunerIpAddress": "電視解碼器 IP 位址", + "LabelTunerType": "電視解碼器類型", "LabelUseNotificationServices": "使用以下服務", "LabelUserAgent": "使用者代理", "LabelUserLibrary": "使用者程式庫", @@ -1014,19 +1014,19 @@ "MessageFileReadError": "讀取檔案時發生錯誤。", "MessageForgotPasswordInNetworkRequired": "請檢查您的區域網路後再開始密碼重設流程。", "MessageForgotPasswordFileCreated": "已在伺服器上建立了以下檔案,並包含有關後續步驟說明", - "MessageNoAvailablePlugins": "沒有可用的附加元件。", + "MessageNoAvailablePlugins": "沒有可用的擴充功能。", "MessageNoServersAvailable": "無法自動偵測伺服器。", "MessageLeaveEmptyToInherit": "留空以使用上級設定或全域預設值。", - "MessageNoCollectionsAvailable": "分組能夠讓您享受個性化的影片、劇集和專輯。點擊\"+\"按鈕開始建立分組。", + "MessageNoCollectionsAvailable": "系列能夠讓您享受個性化的影片、劇集和專輯。點擊\"+\"按鈕開始建立分組。", "MessagePlayAccessRestricted": "此內容的播放受到限制,聯繫您的伺服器管理員以獲取更多訊息。", - "MessagePluginConfigurationRequiresLocalAccess": "請直接登入你的本地伺服器以設定這個附加元件。", - "MessagePluginInstallDisclaimer": "警告:安裝第三方外掛程式有一定風險。第三方外掛程式可能包含不穩定或惡意的程式,並且有可能在任何時候改變。請只安裝你信任的作者的插件,並知悉潛在的影響,包含對外部服務的查詢,更長的媒體庫塞考時間,和額外的背景處理等。", + "MessagePluginConfigurationRequiresLocalAccess": "請直接登入你的本地伺服器以設定這個擴充功能。", + "MessagePluginInstallDisclaimer": "警告:安裝第三方擴充功能有一定風險。第三方擴充功能可能包含不穩定或惡意的程式,並且有可能在任何時候改變。請只安裝你信任的作者的擴充功能,並知悉潛在的影響,包含對外部服務的存取,更長的媒體庫掃描時間,和額外的背景處理等。", "MessageReenableUser": "請參閱以下以重新啟用", "MessageUnableToConnectToServer": "無法連上所選的伺服器,請確保伺服器正在運作中。", "MessageYouHaveVersionInstalled": "你目前安裝了 {0} 版本。", "MoreFromValue": "更多來自 {0}", "News": "新聞", - "NoNewDevicesFound": "找不到裝置,要添加新調諧器,請關閉此對話框並手動輸入裝置訊息。", + "NoNewDevicesFound": "找不到裝置,要添加新電視解碼器,請關閉此對話框並手動輸入裝置訊息。", "OnlyForcedSubtitles": "僅顯示強制字幕", "OnlyImageFormats": "圖片格式(VobSub、PGS、SUB)", "OptionAllowLinkSharingHelp": "只有網頁包含的媒體訊息會被共享,媒體檔案本身不會被公開共享,共享的內容會在 {0} 天后到期。", @@ -1058,7 +1058,7 @@ "PackageInstallCancelled": "{0} (版本 {1})安裝被取消。", "PlayAllFromHere": "從這裡開始全部播放", "PleaseAddAtLeastOneFolder": "請點擊\" + \"按鈕,並在資料夾區域中新增至少一個資料夾到這個媒體庫。", - "PleaseConfirmPluginInstallation": "點擊「OK」以確認您已經閱讀了上述內容並希望繼續安裝附加元件。", + "PleaseConfirmPluginInstallation": "我已詳閱上述內容並確認繼續安裝擴充功能。", "PleaseEnterNameOrId": "請輸入一個名稱或一個外部 ID。", "PleaseRestartServerName": "請重啟 Jellyfin 於 {0}。", "PleaseSelectTwoItems": "請至少選擇 2 個項目。", @@ -1076,7 +1076,7 @@ "Raised": "浮凹", "Rate": "評等", "Recordings": "錄影", - "ServerRestartNeededAfterPluginInstall": "安裝外掛程式後,Jellyfin 伺服器需要重新啟動使其生效。", + "ServerRestartNeededAfterPluginInstall": "安裝擴充功能後,需要重新啟動 Jellyfin 使其生效。", "ShowIndicatorsFor": "顯示指標", "Sort": "排序", "Studios": "工作室", @@ -1088,43 +1088,43 @@ "Unplayed": "尚未播放", "TvLibraryHelp": "查看 {0} 電視節目命名指南 {1} 。", "LabelMonitorUsers": "監控活動", - "LabelPleaseRestart": "改動將在手動重啟用戶端後生效。", + "LabelPleaseRestart": "更動將在手動重啟用戶端後生效。", "LabelProfileCodecsHelp": "以逗號分隔。留空則適用於所有編解碼器。", "OptionPlainStorageFoldersHelp": "所有資料夾在 DIDL 中顯示為「object.container.storageFolder 」,而不是一個更具體的類型,如「object.container.person.musicArtist」。", "LabelInNetworkSignInWithEasyPasswordHelp": "你可以在你的區域網路中使用你的簡易 PIN code 登錄 Jellyfin 應用程式,僅在你使用外部網路時才需要輸入密碼,如果 PIN code 留空,那麼在你的區域網路中便不需輸入密碼。", - "LabelReleaseDate": "釋出日期", - "LabelRemoteClientBitrateLimit": "網際網路串流傳輸位元率限制(Mbps)", + "LabelReleaseDate": "發行日期", + "LabelRemoteClientBitrateLimit": "網際網路串流位元率限制(Mbps)", "LanNetworksHelp": "在執行頻寬限制時,視同區域網路上的 IP 位址或 IP/子網域遮罩項目的逗號分隔清單。若設定此項,所有其它 IP 位址將被視作在外部網路上,並且將受到外部頻寬限制。如果保留為空,則只將伺服器的子網域遮罩作本地網路。", "OptionIgnoreTranscodeByteRangeRequests": "忽略轉檔位元組範圍請求", "OptionIgnoreTranscodeByteRangeRequestsHelp": "這些請求會被接受,但會忽略的位元組範圍標頭。", "OptionLoginAttemptsBeforeLockoutHelp": "若值為 0,則表示將允許普通使用者嘗試三次、管理員嘗試五次的預設值,設定為 -1 來停用此功能。", "OptionRequirePerfectSubtitleMatchHelp": "僅下載經過測試並確認跟此影片檔案完美匹配的字幕。取消勾選這個項目可以增加找到並下載字幕的可能性,但可能會下載時間軸、翻譯不正確的字幕。", - "MessagePluginInstalled": "附加元件安裝成功,但需要重新啟動 Jellyfin 伺服器以使附加元件生效。", + "MessagePluginInstalled": "擴充功能安裝成功,但需要重新啟動 Jellyfin 伺服器以啟用擴充功能。", "MessageChangeRecordingPath": "更改錄製資料夾不會將現有錄製從舊位置遷移到新的,您需要手動移動它們。", "LabelEmbedAlbumArtDidl": "於 DIDL 中嵌入專輯封面", - "LabelEnableAutomaticPortMapHelp": "透過 UPnP 自動將路由器上的公共埠轉發到伺服器上的本地埠。這可能不適用於某些路由器型號或網路設定。在伺服器重新啟動後才會進行更改。", + "LabelEnableAutomaticPortMapHelp": "透過 UPnP 自動將路由器上的公開埠轉發到伺服器上的本地通訊埠。這可能不適用於某些路由器型號或網路設定。在伺服器重新啟動後才會生效。", "LabelEmbedAlbumArtDidlHelp": "有些裝置使用這個方式來取得專輯封面,啟用這個選項可能導致其他設備播放失敗。", "SettingsWarning": "更改這些值可能會導致不穩定或連線故障。如果您遇到任何問題,建議將它們重新更改為預設值。", "LabelEnableSingleImageInDidlLimitHelp": "若在 DIDL 中嵌入多個圖片,某些裝置可能無法正常顯示。", "SortByValue": "排序方式:{0}", "LabelLineup": "排隊", - "LabelLocalHttpServerPortNumber": "本地 HTTP 埠", - "LabelLocalHttpServerPortNumberHelp": "HTTP 伺服器的 TCP 埠。", + "LabelLocalHttpServerPortNumber": "本地 HTTP 通訊埠", + "LabelLocalHttpServerPortNumberHelp": "HTTP 伺服器的 TCP 通訊埠。", "SubtitleAppearanceSettingsAlsoPassedToCastDevices": "此設定也會影響透過此裝置投放的 Google Cast。", - "LabelLoginDisclaimer": "登入免責聲明", + "LabelLoginDisclaimer": "登入聲明", "LabelLogs": "日誌", "SubtitleDownloadersHelp": "按優先順序啟用並排列您的首選字幕下載程式。", "LabelMatchType": "匹配的類型", "SystemDlnaProfilesHelp": "系統設定檔案是唯讀的,更改系統設定檔案將被儲存到自訂的新設定檔案。", "LabelNumber": "編號", - "LabelNumberOfGuideDays": "下載電視指南日數", + "LabelNumberOfGuideDays": "下載電視指南天數", "OnlyForcedSubtitlesHelp": "僅標記為「強制」的字幕會被載入。", "PackageInstallCompleted": "{0} (版本 {1}) 安裝完成。", "OptionDisplayFolderViewHelp": "在其他媒體庫旁邊顯示資料夾,對想要一個普通的資料夾檢視很有用。", "LabelReasonForTranscoding": "轉檔原因", "LabelRecord": "錄影", "LabelRecordingPath": "預設錄影路徑", - "LabelRecordingPathHelp": "指定用於存儲轉檔的位置,留空將使用伺服器的程式根目錄。", + "LabelRecordingPathHelp": "指定用於儲存錄影的位置,留空將使用伺服器的程式資料路徑。", "LabelRemoteClientBitrateLimitHelp": "可選用的遠端位元率限制,將限制每個到遠端裝置的串流位元率。這個選項可以避免裝置請求超過你的網速的位元率。這個選項可能導致更高的負載,以將影片轉當至較低的位元率。", "SmartSubtitlesHelp": "當音訊為外語時,將載入與語言偏好匹配的字幕。", "SubtitleAppearanceSettingsDisclaimer": "這些設定不會套用在圖形字幕(如 PGS、DVD 等),或者一些有著自己的內建樣式的字幕(如 ASS/SSA)。", @@ -1153,54 +1153,54 @@ "OptionDateAddedFileTime": "使用檔案建立日期", "OptionReportByteRangeSeekingWhenTranscodingHelp": "這對一些時間跳轉緩慢的裝置是必要的。", "XmlTvNewsCategoriesHelp": "有這些類別的節目會被當作新聞節目,以「|」來分隔多個項目。", - "LabelKodiMetadataEnableExtraThumbsHelp": "為了相容 Kodi 主題,下載的圖片將被同時儲存在 extrafanart 和 extrathumbs 資料夾中。", + "LabelKodiMetadataEnableExtraThumbsHelp": "為了更好的 Kodi 主題相容性,下載的圖片將被同時儲存在 extrafanart 和 extrathumbs 資料夾中。", "LabelInternetQuality": "網路畫質", - "LabelKodiMetadataEnablePathSubstitutionHelp": "允許將圖片的路徑以伺服器路徑取代。", - "LabelKodiMetadataSaveImagePathsHelp": "若如果您的圖片檔案名稱不符合 Kodi 規範,建議啟用。", - "LabelKodiMetadataUser": "儲存這些使用者的觀看資料到 NFO 檔案中", - "LabelKodiMetadataUserHelp": "儲存觀看資料到 NFO 檔案中以便其他應用程式使用。", - "LabelMetadataReadersHelp": "排序媒體資訊來源的優先度,將會讀取第一個找到的檔案。", + "LabelKodiMetadataEnablePathSubstitutionHelp": "允許依伺服器設定代換圖片路徑。", + "LabelKodiMetadataSaveImagePathsHelp": "若如果您的圖片檔案名稱不符合 Kodi 規範,建議啟用此設定。", + "LabelKodiMetadataUser": "儲存這名使用者的觀看資料到 NFO 檔案中", + "LabelKodiMetadataUserHelp": "儲存觀看資料到 NFO 檔案中以供其他應用程式使用。", + "LabelMetadataReadersHelp": "排序本地媒體資訊來源的優先度,將會讀取第一個找到的檔案。", "LabelMetadataSavers": "媒體資訊儲存方式", "LabelModelDescription": "型號描述", "LabelModelName": "型號名稱", "LabelModelUrl": "型號網址", "LabelMusicStreamingTranscodingBitrate": "音樂轉檔位元率", "LabelMusicStreamingTranscodingBitrateHelp": "指定音樂串流時的最大位元率。", - "LabelOptionalNetworkPathHelp": "如果這個資料夾在網路上分享,提供網路分享路徑可以供其他應用程式直接存取媒體檔案,例如 {0} 或者 {1}。", + "LabelOptionalNetworkPathHelp": "如果這個資料夾在網路上共用,提供網路共用路徑可以供其他應用程式直接存取媒體檔案,例如 {0} 或者 {1}。", "LabelOriginalAspectRatio": "原始長寬比", "LabelOverview": "內容概述", - "LabelParentalRating": "分級", + "LabelParentalRating": "年齡分級", "LabelPasswordConfirm": "確認密碼", - "LabelPasswordResetProvider": "密碼重設提供者", + "LabelPasswordResetProvider": "密碼重置提供者", "LabelPasswordRecoveryPinCode": "PIN 碼", "LabelPath": "路徑", "LabelPersonRole": "角色", "LabelPersonRoleHelp": "例如:冰淇淋車司機", "LabelPlaceOfBirth": "出生地", - "LabelPlayDefaultAudioTrack": "無論如何都播放預設音軌", + "LabelPlayDefaultAudioTrack": "無論語言都播放預設音軌", "LabelPlayer": "播放器", "LabelPlayMethod": "播放方式", "LabelParentNumber": "父編號", "LabelPostProcessor": "後處理應用程式", - "LabelPostProcessorArguments": "處理器後命令行參數", + "LabelPostProcessorArguments": "後處理後命令行參數", "LabelPostProcessorArgumentsHelp": "使用 {path} 作為錄製檔案的路徑。", "LabelPreferredDisplayLanguage": "首選語言", "LabelPreferredSubtitleLanguage": "字幕語言偏好", - "LabelProtocol": "協議", + "LabelProtocol": "協定", "LabelProtocolInfo": "協議資訊", - "LabelPublicHttpPort": "公開 HTTP 埠", - "LabelPublicHttpsPort": "公開 HTTPS 埠", + "LabelPublicHttpPort": "公開 HTTP 通訊埠", + "LabelPublicHttpsPort": "公開 HTTPS 通訊埠", "LabelProtocolInfoHelp": "當響應來自裝置的 GetProtocolInfo(獲取協議訊息)請求時,該值將被使用。", - "LabelPublicHttpPortHelp": "公開通訊埠轉發射到本地 HTTP 通訊埠。", - "LabelPublicHttpsPortHelp": "公開通訊埠應轉發到本地 HTTPS 通訊埠。", - "LabelSelectFolderGroups": "自動將以下資料夾中的內容分組到視圖中,例如電影、音樂和電視", + "LabelPublicHttpPortHelp": "應該轉發到本地 HTTP 通訊埠的公開通訊埠。", + "LabelPublicHttpsPortHelp": "應轉發到本地 HTTPS 通訊埠的公開通訊埠。", + "LabelSelectFolderGroups": "自動將以下資料夾中的內容分類到視圖中,例如電影、音樂和電視", "LabelStatus": "狀態", "LiveBroadcasts": "直播", "MessageImageTypeNotSelected": "在下拉選單中選取圖片類型。", "RemoveFromCollection": "從收藏移除", "RepeatEpisodes": "重複劇集", "SaveSubtitlesIntoMediaFolders": "保存字幕到媒體所在資料夾", - "SaveSubtitlesIntoMediaFoldersHelp": "將字幕存儲在影片檔案旁邊可以讓管理更方便。", + "SaveSubtitlesIntoMediaFoldersHelp": "將字幕儲存在影片檔案旁邊可以讓管理更方便。", "ScanForNewAndUpdatedFiles": "掃描新的和有修改的文件", "Schedule": "排程", "TabNetworking": "網路", @@ -1217,8 +1217,8 @@ "XmlTvKidsCategoriesHelp": "有這些類別的節目會被當作兒童節目,以「|」來分隔多個項目。", "TabResponses": "響應", "LabelDisplaySpecialsWithinSeasons": "顯示劇集季度中的特集", - "LabelNumberOfGuideDaysHelp": "下載多日的節目指南可以幫你進一步查看節目列表並做出提前安排,但下載過程也將耗時更久。它將基於頻道數量自動選擇。", - "LabelOptionalNetworkPath": "分享的網路資料夾", + "LabelNumberOfGuideDaysHelp": "下載多日的節目指南可以幫你進一步查看節目列表並做出提前安排,但下載過程也將耗時更久。自動將基於頻道數量自動選擇。", + "LabelOptionalNetworkPath": "共用的網路資料夾", "OptionResElement": "'res' 元素", "PinCodeResetComplete": "簡易 PIN code 已被重設。", "PinCodeResetConfirmation": "你確定要重設簡易 PIN code 嗎?", @@ -1236,8 +1236,8 @@ "LabelVideoResolution": "影片解析度", "LabelStreamType": "串流類型", "LabelPlayerDimensions": "播放器尺寸", - "LabelDroppedFrames": "丟棄的幀", - "LabelCorruptedFrames": "損壞的幀", + "LabelDroppedFrames": "丟失的影格", + "LabelCorruptedFrames": "損壞的影格", "ButtonSplit": "分割", "AskAdminToCreateLibrary": "如要建立媒體庫,請聯絡管理員。", "NoCreatedLibraries": "看來您還未創任何媒體庫。{0}立刻創一個新的嗎?{1}", @@ -1266,9 +1266,9 @@ "Season": "季", "Person": "人物", "Movie": "電影", - "LabelLibraryPageSizeHelp": "設定媒體庫頁面每頁要顯示的最多媒體個數。設定為 0 來停用分頁。", + "LabelLibraryPageSizeHelp": "設定媒體庫頁面每頁要顯示的項目數量。設定為 0 來停用分頁。", "LabelLibraryPageSize": "媒體庫分頁大小", - "LabelDeinterlaceMethod": "反交錯方法", + "LabelDeinterlaceMethod": "去交錯方法", "Episode": "劇集", "DeinterlaceMethodHelp": "選擇對隔行掃描內容進行軟體轉檔時所用的反交錯方法。當硬體加速支援的硬體反交錯選項啟用時,硬體方式將取代此設定。", "BoxSet": "套裝", @@ -1284,7 +1284,7 @@ "LabelRequireHttps": "強制 HTTPS", "LabelStable": "穩定版", "LabelChromecastVersion": "Google Cast 版本", - "LabelEnableHttpsHelp": "監聽指定的 HTTPS 埠。須設定有效的證書使其生效。", + "LabelEnableHttpsHelp": "監聽指定的 HTTPS 通訊埠。須設定有效的憑證使其生效。", "LabelEnableHttps": "啟用 HTTPS", "HeaderServerAddressSettings": "伺服器位置設定", "HeaderRemoteAccessSettings": "遠端存取設定", @@ -1310,7 +1310,7 @@ "ClearQueue": "清空佇列", "StopPlayback": "停止播放", "ButtonPlayer": "播放器", - "ButtonCast": "投放到設備", + "ButtonCast": "投放到裝置", "Writers": "作者", "ViewAlbumArtist": "檢視專輯演出者", "TabRepositories": "儲存庫", @@ -1328,7 +1328,7 @@ "MessageAddRepository": "欲新增儲存庫,請點擊旁邊的按鈕來填寫相關資訊。", "LabelRepositoryNameHelp": "取一個能讓你辨識的名稱。", "LabelRepositoryName": "儲存庫名稱", - "LabelRepositoryUrl": "儲存庫 URL", + "LabelRepositoryUrl": "儲存庫網址", "HeaderNewRepository": "新增儲存庫", "MessageNoRepositories": "尚無儲存庫。", "LabelSyncPlayAccess": "同步播放存取控制", @@ -1345,8 +1345,8 @@ "HeaderSyncPlaySelectGroup": "加入群組", "HeaderDVR": "DVR", "SubtitleVerticalPositionHelp": "文字出現的行號。正數表示由上到下,負數表示由下到上。", - "MessagePluginInstallError": "安裝附加元件時發生了錯誤。", - "MessageGetInstalledPluginsError": "取得已安裝的附加元件清單時發生了錯誤。", + "MessagePluginInstallError": "安裝擴充功能時發生了錯誤。", + "MessageGetInstalledPluginsError": "取得已安裝的擴充功能清單時發生了錯誤。", "Preview": "預覽", "LabelSubtitleVerticalPosition": "垂直位置", "PreviousTrack": "上一首", @@ -1385,19 +1385,19 @@ "QuickConnectNotActive": "快速連線尚未於此伺服器上啟用", "QuickConnectNotAvailable": "聯繫伺服器管理員以啟用 Quick Connect", "QuickConnectInvalidCode": "Quick Connect 代號無效", - "KnownProxiesHelp": "連線到 Jellyfin 的代理伺服器的 IP 位址或主機名稱之列表,以逗號分隔,以使 X-Forwarded-For 標頭能正常運作。本設定儲存後需要重新啟動。", + "KnownProxiesHelp": "連線到 Jellyfin 的反向代理伺服器的 IP 位址或主機名稱之列表,以逗號分隔,以使 X-Forwarded-For 標頭能正常運作。本設定儲存後需要重新啟動。", "LabelMaxMuxingQueueSize": "最大混合器佇列大小", "VideoAudio": "影片音訊", "Video": "影片", "QuickConnectAuthorizeFail": "未知的 Quick Connect 代號", - "QuickConnectAuthorizeSuccess": "您的設備認證成功!", + "QuickConnectAuthorizeSuccess": "您的裝置認證成功!", "QuickConnectAuthorizeCode": "輸入代號 {0} 來登入", "QuickConnectActivationSuccessful": "成功啟用", "QuickConnect": "快速連接", "PosterCard": "海報卡片", "PlaybackRate": "播放速度", - "LabelQuickConnectCode": "Quick Connect 代號", - "LabelKnownProxies": "已知 Proxy", + "LabelQuickConnectCode": "Quick Connect 驗證碼", + "LabelKnownProxies": "已知代理伺服器", "LabelCurrentStatus": "目前狀態", "EnableAutoCast": "設為預設", "HeaderDeleteDevices": "刪除所有裝置", @@ -1415,11 +1415,11 @@ "LabelTonemappingAlgorithm": "選擇要使用的色調轉換算法", "AllowTonemappingHelp": "色調轉換可以將影片從 HDR 轉換成 SDR,同時保持影像細節與顏色等對於表現場景非常重要的資訊。目前僅支援 HDR10、HLG 和 Dolby Vision 影片。此一選項需要對應的 GPU 運算環境。", "EnableTonemapping": "啟用色調轉換", - "LabelOpenclDeviceHelp": "此 OpenCL 設備將用於色調轉換。點的左側為平台號碼,右側為此平台上的設備號碼。預設值為 0.0。需要有 OpenCL 硬體加速功能的 FFmpeg 應用程式。", - "LabelColorPrimaries": "三原色", + "LabelOpenclDeviceHelp": "此 OpenCL 裝置將用於色調轉換。點的左側為平台號碼,右側為此平台上的裝置號碼。預設值為 0.0。需要有 OpenCL 硬體加速功能的 FFmpeg 應用程式。", + "LabelColorPrimaries": "原色", "MediaInfoColorPrimaries": "三原色", "UseDoubleRateDeinterlacingHelp": "此設定使用去交錯時的刷新頻率,通常稱為 Bob 去交錯。它將影片的幀率加倍,以提供完整的運動效果,就類似在電視上觀看隔行掃描的影片看到的那樣。", - "LabelMaxMuxingQueueSizeHelp": "等待所有流初始化時可緩衝的最大封包數。如果在 FFmpeg 日誌中仍然遇到 \"Too many packets buffered for output stream\" 錯誤,請嘗試增加此設定值。建議值為 2048。", + "LabelMaxMuxingQueueSizeHelp": "等待所有串流初始化時可緩衝的最大封包數。如果在 FFmpeg 日誌中仍然遇到 \"Too many packets buffered for output stream\" 錯誤,請嘗試增加此設定值。建議值為 2048。", "LabelTonemappingParamHelp": "調整色調轉換演算法。建議值和預設值均為 NaN。通常將其留空。", "LabelTonemappingParam": "色調轉換參數", "LabelTonemappingPeakHelp": "用此設定值覆蓋信號/標稱/參考峰值。當顯示資訊中嵌入的峰值資訊不可靠時,或從較低範圍到較高範圍的色調轉換時,此選項很有用。建議值和預設值分別為 100 和 0。", @@ -1432,23 +1432,23 @@ "LabelAutomaticDiscovery": "啟動自動探索", "LabelAutoDiscoveryTracingHelp": "若啟用後,將會記錄自動探索連接埠的封包。", "HeaderUploadSubtitle": "上傳字幕", - "HeaderPortRanges": "Proxy 和防火牆設定", - "HeaderNetworking": "網際網路協定", + "HeaderPortRanges": "防火牆和代理伺服器設定", + "HeaderNetworking": "網路通訊協定", "HeaderDebugging": "偵錯和追蹤", "HeaderAutoDiscovery": "探索網域", "HeaderAddUser": "新增使用者", - "HeaderAddUpdateSubtitle": "新增/更新 字幕", - "LabelEnableIP6Help": "啟用IPv6功能。", - "LabelEnableIP6": "啟用IPv6", - "LabelEnableIP4Help": "啟用IPv4功能。", - "LabelEnableIP4": "啟用IPv4", - "LabelDropSubtitleHere": "將字幕檔丟到這裡,或點擊瀏覽。", + "HeaderAddUpdateSubtitle": "新增/更新字幕", + "LabelEnableIP6Help": "啟用 IPv6 功能。", + "LabelEnableIP6": "啟用 IPv6", + "LabelEnableIP4Help": "啟用 IPv4 功能。", + "LabelEnableIP4": "啟用 IPv4", + "LabelDropSubtitleHere": "拖放字幕檔丟到此處,或點擊瀏覽。", "LabelAllowedAudioChannels": "最大聲道允許數", "AllowHevcEncoding": "允許以 HEVC 格式編碼", - "PreferFmp4HlsContainerHelp": "優先使用 fMP4 作為 HLS 的預設容器,以便在支援的設備上直接串流 HEVC 和 AV1 內容。", + "PreferFmp4HlsContainerHelp": "優先使用 fMP4 作為 HLS 的預設容器,以便在支援的裝置上直接串流 HEVC 和 AV1 內容。", "PreferFmp4HlsContainer": "偏好 fMP4-HLS Media Container", "RemuxHelp2": "Remux使用最低的處理能力,達到完全無損的媒體品質。", - "RemuxHelp1": "不兼容的影片格式(MKV、AVI、WMV等),但影像串流和聲音串流都與設備兼容。在發送到設備之前,影片將被無損地重新打包。", + "RemuxHelp1": "不相容的影片格式(MKV、AVI、WMV等),但視訊和音訊都與裝置相容。在發送到裝置之前,媒體將被無損地重新打包。", "AspectRatioFill": "填滿", "AspectRatioCover": "覆蓋", "EnableFallbackFontHelp": "啟用自定義備用字體。這選項可以避免字幕渲染錯誤發生。", @@ -1468,14 +1468,14 @@ "LabelSyncPlayHaltPlayback": "停止本地播放", "LabelSSDPTracingFilterHelp": "自選 IP 地址,用於過濾記錄的 SSDP 流量。", "LabelSSDPTracingFilter": "SSDP 篩選", - "LabelPublishedServerUriHelp": "根據接口或客戶端 IP 位址,覆蓋 Jellyfin 使用的 URI。", + "LabelPublishedServerUriHelp": "根據介面或用戶端 IP 位址,覆蓋 Jellyfin 使用的 URI。", "LabelPublishedServerUri": "公開伺服器 URI", "LabelMinAudiobookResumeHelp": "將在此時間前停止播放的媒體當作尚未播放。", "LabelMaxAudiobookResumeHelp": "將剩下的部分小於此時長後停止播放的媒體當作已播畢。", "LabelIsForced": "強制", "LabelHDHomerunPortRangeHelp": "將HDHomeRun UDP 端口範圍限制至該值內。(預設值為 1024 - 65535)。", "LabelHDHomerunPortRange": "HDHomeRun 端口範圍", - "LabelH265Crf": "H.265 編碼 CRF", + "LabelH265Crf": "H.265 編碼 CRF 設定", "LabelEnableSSDPTracingHelp": "將 SSDP 追蹤詳細資料記錄至日誌。
警告:這將導致效能嚴重損失。", "LabelEnableSSDPTracing": "啟用 SSDP 追蹤", "LabelAutoDiscoveryTracing": "開啟自動追蹤。", @@ -1489,7 +1489,7 @@ "LabelVideoInfo": "影片資訊", "LabelAudioInfo": "音檔資訊", "LabelPlaybackInfo": "播放資訊", - "Framerate": "幀數", + "Framerate": "幀率", "DisablePlugin": "停用", "EnablePlugin": "啟用", "AudioBitDepthNotSupported": "不支援此音訊的位元深度", @@ -1515,7 +1515,7 @@ "Controls": "控制", "AllowVppTonemappingHelp": "完全基於 Intel 驅動程式的色調轉換。目前只針對部分硬體及 HDR10 影片有效。此一選項比 OpenCL 具有更高的優先級。", "EnableVppTonemapping": "啟用VPP色調轉換", - "EnableEnhancedNvdecDecoder": "啟用加強NVDEC解碼器", + "EnableEnhancedNvdecDecoder": "啟用增強的 NVDEC 解碼器", "MessagePlaybackError": "在您的 Google Cast 接收器上播放此檔案時發生錯誤。", "MessageChromecastConnectionError": "您的 Google Cast 接收器無法連接 Jellyfin 伺服器。請檢查連線後重試。", "YoutubeDenied": "所要求的影片無法被播放於嵌入式播放器中。", @@ -1534,9 +1534,9 @@ "LabelSlowResponseEnabled": "當伺服器應答過慢時記錄警告訊息", "LabelMinAudiobookResume": "繼續播放有聲書的最短時間", "LabelMaxAudiobookResume": "繼續播放有聲書的剩餘時間", - "LabelLocalCustomCss": "自訂CSS樣式僅使用於此客戶端。你可能會想要停用伺服器自訂CSS。", - "LabelDisableCustomCss": "停用由伺服器提供的自訂CSS標籤或品牌。", - "LabelCreateHttpPortMapHelp": "允許自動通訊埠轉發在 HTTPS 以外為 HTTP 流量建立規則。", + "LabelLocalCustomCss": "僅套用在此用戶段的客製化 CSS 樣式。你可能需要停用伺服器自訂 CSS。", + "LabelDisableCustomCss": "停用由伺服器提供的自訂CSS主題或品牌。", + "LabelCreateHttpPortMapHelp": "允許自動通訊埠轉發除了 HTTPS 以外同時為 HTTP 流量建立規則。", "HeaderContinueReading": "繼續閱讀", "DisableCustomCss": "停用伺服器提供的自訂CSS樣式", "DirectPlayHelp": "原始檔完全相容於此用戶端,並正在直接接收原始檔案。", @@ -1563,8 +1563,8 @@ "LabelSyncPlaySettingsExtraTimeOffset": "額外時間偏移", "LabelSyncPlaySettingsDescription": "變更SyncPlay設定", "HeaderSyncPlayTimeSyncSettings": "時間同步", - "HeaderSyncPlayPlaybackSettings": "回放", - "HeaderSyncPlaySettings": "SyncPlay設定", + "HeaderSyncPlayPlaybackSettings": "播放", + "HeaderSyncPlaySettings": "同步播放設定", "LabelSyncPlaySettingsSpeedToSync": "啟用SpeedToSync", "LabelSyncPlaySettingsMinDelaySkipToSyncHelp": "SkipToSync嘗試校正播放位置後的最小延遲(毫秒)。", "ErrorPlayerNotFound": "找不到這個媒體所需的播放器。", @@ -1587,8 +1587,8 @@ "Copied": "已複製", "Casual": "休閒", "AddToFavorites": "添加到收藏", - "LabelAutomaticallyAddToCollection": "自動加入合輯", - "GoogleCastUnsupported": "不支援Google Cast", + "LabelAutomaticallyAddToCollection": "自動加入系列", + "GoogleCastUnsupported": "不支援 Google Cast", "EnableRewatchingNextUpHelp": "在「接下來」中顯示已觀看的集數。", "EnableRewatchingNextUp": "在「接下來」顯示重看影片", "Digital": "數位", @@ -1596,11 +1596,11 @@ "ButtonClose": "關閉", "ButtonSpace": "空格", "TypeOptionPluralMusicVideo": "MV", - "LabelMaxDaysForNextUp": "「下一步」中的最大天數", + "LabelMaxDaysForNextUp": "「接下來」中的最大天數", "Print": "列印", "TypeOptionPluralMusicAlbum": "音樂專輯", "TypeOptionPluralMusicArtist": "音樂藝術家", - "PreferSystemNativeHwDecoder": "偏好作業系統原生 DXVA 或 VA-API 硬體解碼器", + "PreferSystemNativeHwDecoder": "偏好作業系統原生的 DXVA 或 VA-API 硬體解碼器", "AllowEmbeddedSubtitlesHelp": "停用封裝在媒體容器中的字幕。 需要對媒體庫進行完整的重新掃描。", "RememberAudioSelections": "根據上一項設定音軌", "RememberAudioSelectionsHelp": "嘗試將音軌設定為與上一個影片最接近的匹配。", @@ -1625,11 +1625,11 @@ "MixedMoviesShows": "混合電影和節目", "Interview": "採訪", "VideoBitrateNotSupported": "不支援影片的碼率", - "LabelMaxDaysForNextUpHelp": "設定一個節目在不觀看的情況下應保留在「下一個」列表中的最大天數。", + "LabelMaxDaysForNextUpHelp": "設定一個節目在未被觀看的情況下應保留在「接下來」列表中的最大天數。", "MessageUnauthorizedUser": "您目前無權訪問伺服器。 請聯繫您的伺服器管理員以獲取更多資訊。", - "ItemDetails": "物品詳情", + "ItemDetails": "詳情", "EnableCardLayout": "顯示可視化 CardBox", - "LabelAutomaticallyAddToCollectionHelp": "當至少有 2 部電影具有相同的收藏名稱時,它們將被自動添加到收藏中。", + "LabelAutomaticallyAddToCollectionHelp": "當至少有 2 部電影具有相同的系列名稱時,它們將被自動添加到系列中。", "LabelTextWeight": "字體粗細", "Bold": "粗體", "Localization": "本土化", @@ -1674,7 +1674,7 @@ "MediaInfoDvVersionMinor": "杜比視界次要版本", "MediaInfoDvProfile": "杜比視界簡介", "IgnoreDts": "忽略 DTS(解碼時間戳)", - "IgnoreDtsHelp": "停用此選項可能會解決一些問題,例如在具有分開的音訊和影片的頻道上丟失音訊。", + "IgnoreDtsHelp": "停用此選項可能會解決一些問題,例如在具有分開的音訊和視訊的頻道上丟失音訊。", "MessageRenameMediaFolder": "重新命名媒體庫將導致所有媒體資料丟失,請謹慎操作。", "OriginalAirDate": "原始播出日期", "Production": "作品", @@ -1684,22 +1684,22 @@ "MediaInfoElPresentFlag": "杜比視界 el 存在標記", "MediaInfoBlPresentFlag": "杜比視界 bl 存在標記", "MediaInfoDvBlSignalCompatibilityId": "杜比視界 bl 訊號相容性 id", - "LabelStereoDownmixAlgorithm": "立體聲混縮算法 (Stereo Downmix Algorithm)", + "LabelStereoDownmixAlgorithm": "立體聲向下混音演算法", "StereoDownmixAlgorithmHelp": "會將多聲道的音訊混縮為雙聲道的演算法。", "DownloadAll": "全部下載", "Experimental": "實驗性", - "HeaderDummyChapter": "章節影像", - "LabelEnableAudioVbr": "啟用 VBR 音訊編碼", + "HeaderDummyChapter": "章節圖片", + "LabelEnableAudioVbr": "啟用可變位元率(VBR)音訊編碼", "LabelParallelImageEncodingLimit": "並行圖片編碼限制", "LabelParallelImageEncodingLimitHelp": "允許同時進行的圖片轉檔最大數量(0為自動)。", "HeaderPerformance": "效能", - "LabelDummyChapterDuration": "頻率", + "LabelDummyChapterDuration": "間隔", "LabelDummyChapterDurationHelp": "虛擬章節之間的間隔,設定為0以停用。修改此設定不會影響現有的虛擬章節。", "LabelDummyChapterCount": "限制", "LabelDummyChapterCountHelp": "每個媒體檔案的最大的章節擷取圖片數量。", "LabelChapterImageResolution": "解析度", "LabelChapterImageResolutionHelp": "章節圖片擷取解析度。修改此設定對於現存的虛擬章節沒有影響。", - "HeaderRecordingMetadataSaving": "錄製中繼資料", + "HeaderRecordingMetadataSaving": "錄影媒體資訊", "SaveRecordingImagesHelp": "將 EPG 提供的圖片和媒體一起保存。", "SubtitleGreen": "綠色", "SubtitleLightGray": "淺灰色", @@ -1721,11 +1721,11 @@ "LabelThrottleDelaySecondsHelp": "當轉檔進度快於用戶端下載進度的距離大於這個時間(以秒為單位)時暫停轉檔。必須足夠長,以保障用戶端擁有足夠的緩衝區。只有在限制轉檔啟用時有效。", "LabelSegmentKeepSeconds": "轉檔暫存檔保留時間", "LabelSegmentKeepSecondsHelp": "已經被用戶端下載過的轉檔暫存檔應該在伺服器上保留的時間(以秒為單位)。只在刪除轉檔暫存啟用時有效。", - "GetThePlugin": "取得外掛", + "GetThePlugin": "取得擴充功能", "PreferEmbeddedExtrasTitlesOverFileNamesHelp": "額外內容通常和上級項目擁有相同的標題,勾選以使用內部標題。", "SecondarySubtitles": "次要字幕", "LabelSyncPlayNoGroups": "沒有可用的群組", - "NotificationsMovedMessage": "通知功能已經轉移至 Webhook 外掛程式中。", + "NotificationsMovedMessage": "通知功能已經轉移至 Webhook 擴充功能中。", "TonemappingModeHelp": "如果遇到高光過度曝光,請嘗試切換到 RGB 模式。", "EnableAudioNormalizationHelp": "音量標準化將增加一個增益以保持平均音量在恆定的大小(-18dB)。", "EnableAudioNormalization": "音量標準化", @@ -1740,14 +1740,14 @@ "LogLevel.Debug": "除錯", "LogLevel.None": "沒有", "Notifications": "通知", - "LabelBackdropScreensaverInterval": "螢幕保護程式間隔", - "LabelBackdropScreensaverIntervalHelp": "螢幕保護裝置切換背景的間隔。", + "LabelBackdropScreensaverInterval": "背景螢幕保護程式間隔", + "LabelBackdropScreensaverIntervalHelp": "螢幕保護程式切換背景的間隔。", "LabelSystem": "系統", "LogLevel.Information": "資訊", "LogLevel.Warning": "警告", "LogLevel.Error": "錯誤", "LogLevel.Critical": "嚴重", - "PleaseConfirmRepositoryInstallation": "如果您已閱讀上述內容,並希望繼續安裝外掛程式庫,輕點擊 OK。", + "PleaseConfirmRepositoryInstallation": "我已詳閱上述內容,並確定安裝第三方擴充功能庫。", "ResolutionMatchSource": "配對來源", "SubtitleGray": "灰色", "Select": "選擇", @@ -1756,12 +1756,12 @@ "LabelDeveloper": "開發者", "Featurette": "花絮", "Short": "短片", - "LabelEnableAudioVbrHelp": "可變位元率(VBR)比起平均位元率(ABR)能提供更好的音質。在少數情況可能造成相容性問題。", + "LabelEnableAudioVbrHelp": "可變位元率(VBR)比起平均位元率(ABR)能提供更好的音質,在少數情況可能造成相容性問題。", "MenuOpen": "打開選單", "UserMenu": "使用者選單", - "HeaderConfirmRepositoryInstallation": "確認外掛來源庫", - "MessageRepositoryInstallDisclaimer": "警告:安裝第三方外掛程式庫有風險。其中可能包不穩定或含惡意的程式,並且可能隨時變化。請只安裝你信任的作者提供的外掛程式庫。", - "LabelEnableLUFSScanHelp": "用戶端可以自動調整音訊播放,在不同音軌之間獲得相等的音量。這會使得掃描花費較多時間並消耗較多資源。", + "HeaderConfirmRepositoryInstallation": "確定安裝擴充功能庫", + "MessageRepositoryInstallDisclaimer": "警告:安裝第三方擴充功能庫有風險。其中可能包不穩定或含惡意的程式,並且可能隨時變化。請只安裝你信任的作者提供的擴充功能庫。", + "LabelEnableLUFSScanHelp": "用戶端可以自動調整音訊播放,以在不同音軌之間獲得相等的音量。這會使得掃描花費較多時間並消耗較多資源。", "AllowCollectionManagement": "允許使用者管理系列", "GridView": "網格檢視", "AllowAv1Encoding": "允許以 AV1 格式編碼", @@ -1776,7 +1776,7 @@ "UnknownError": "發生未知的錯誤。", "HearingImpairedShort": "聽障/聾啞人士字幕", "LabelIsHearingImpaired": "用於聽障、聾啞人士", - "HeaderGuestCast": "來賓演出者", + "HeaderGuestCast": "客串演員", "GoHome": "返回首頁", "LabelSelectAudioNormalization": "音量標準化", "SelectAudioNormalizationHelp": "音軌增益:調整個別音軌的增益以獲得一致的音量。專輯增益:調整專輯中全部音軌的音量。", diff --git a/src/themes/theme.ts b/src/themes/theme.ts index 4a17f6ade4..76c7f5bb8b 100644 --- a/src/themes/theme.ts +++ b/src/themes/theme.ts @@ -55,7 +55,18 @@ const theme = createTheme({ MuiButton: { defaultProps: { variant: 'contained' - } + }, + variants: [ + { + props: { + size: 'large' + }, + style: { + fontSize: '1rem', + fontWeight: 'bold' + } + } + ] }, MuiFormControl: { defaultProps: { diff --git a/src/types/playbackStopInfo.ts b/src/types/playbackStopInfo.ts new file mode 100644 index 0000000000..4826d98449 --- /dev/null +++ b/src/types/playbackStopInfo.ts @@ -0,0 +1,46 @@ +import type { + BaseItemDto, + GroupShuffleMode, + MediaSourceInfo, + MediaType, + PlayerStateInfo +} from '@jellyfin/sdk/lib/generated-client'; + +export interface BufferedRange { + start?: number; + end?: number; +} + +export interface PlayState extends PlayerStateInfo { + ShuffleMode?: GroupShuffleMode; + MaxStreamingBitrate?: number | null; + PlaybackStartTimeTicks?: number | null; + PlaybackRate?: number | null; + SecondarySubtitleStreamIndex?: number | null; + BufferedRanges?: BufferedRange[]; + PlaySessionId?: string | null; + PlaylistItemId?: string | null; +} + +export interface MediaSource extends MediaSourceInfo { + enableDirectPlay?: boolean; + DefaultSecondarySubtitleStreamIndex?: number | null; + StreamUrl?: string | null; + albumNormalizationGain?: number | null; +} + +export interface PlayerState { + PlayState: PlayState; + NowPlayingItem: BaseItemDto | null; + NextItem: BaseItemDto | null; + NextMediaType: MediaType | null; + MediaSource: MediaSource | null; +} + +export interface PlaybackStopInfo { + player: unknown; // TODO: add a proper interface + state: PlayerState; + nextItem: BaseItemDto | null; + nextMediaType: MediaType | null; +} +