From bf3f37e3d0d10d77a99dfb38c868de26b3b4a05d Mon Sep 17 00:00:00 2001 From: jkhsjdhjs Date: Sun, 13 Jul 2025 23:28:14 +0200 Subject: [PATCH 01/13] Add fallback for keyframe-only trickplay extraction Keyframe-only trickplay image extraction can fail for some media files. The current behavior is to skip the media file and try again on the next run, which will fail again. This adds a fallback to regular non-keyframe-only extraction for failed runs, so the extraction can complete. --- .../Encoder/MediaEncoder.cs | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 2eb647e264..c69f8e97b7 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -827,7 +827,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } /// - public Task ExtractVideoImagesOnIntervalAccelerated( + public async Task ExtractVideoImagesOnIntervalAccelerated( string inputFile, string container, MediaSourceInfo mediaSource, @@ -918,18 +918,34 @@ namespace MediaBrowser.MediaEncoding.Encoder inputArg = "-hwaccel_flags +low_priority " + inputArg; } - if (enableKeyFrameOnlyExtraction) - { - inputArg = "-skip_frame nokey " + inputArg; - } - var filterParam = encodingHelper.GetVideoProcessingFilterParam(jobState, options, vidEncoder).Trim(); if (string.IsNullOrWhiteSpace(filterParam)) { throw new InvalidOperationException("EncodingHelper returned empty or invalid filter parameters."); } - return ExtractVideoImagesOnIntervalInternal(inputArg, filterParam, vidEncoder, threads, qualityScale, priority, cancellationToken); + try + { + return await ExtractVideoImagesOnIntervalInternal( + (enableKeyFrameOnlyExtraction ? "-skip_frame nokey " : string.Empty) + inputArg, + filterParam, + vidEncoder, + threads, + qualityScale, + priority, + cancellationToken).ConfigureAwait(false); + } + catch (FfmpegException ex) + { + if (!enableKeyFrameOnlyExtraction) + { + throw; + } + + _logger.LogWarning(ex, "I-frame trickplay extraction failed, will attempt standard way. Input: {InputFile}", inputFile); + } + + return await ExtractVideoImagesOnIntervalInternal(inputArg, filterParam, vidEncoder, threads, qualityScale, priority, cancellationToken).ConfigureAwait(false); } private async Task ExtractVideoImagesOnIntervalInternal( From d6f93759ead5f58509c6c4ec5fce5a51339b43c5 Mon Sep 17 00:00:00 2001 From: jkhsjdhjs Date: Sun, 13 Jul 2025 23:37:32 +0200 Subject: [PATCH 02/13] Add myself to CONTRIBUTORS.md I have contributed previously, but forgot to add myself last time. --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 06c72c6168..4b83156b99 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -61,6 +61,7 @@ - [ikomhoog](https://github.com/ikomhoog) - [iwalton3](https://github.com/iwalton3) - [jftuga](https://github.com/jftuga) + - [jkhsjdhjs](https://github.com/jkhsjdhjs) - [jmshrv](https://github.com/jmshrv) - [joern-h](https://github.com/joern-h) - [joshuaboniface](https://github.com/joshuaboniface) From 317192c23df5c42f96fa5af65ae07b052aeaf726 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 30 Jul 2025 03:59:51 +0000 Subject: [PATCH 03/13] Update CI dependencies --- .github/workflows/ci-codeql-analysis.yml | 6 +++--- .github/workflows/ci-tests.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-codeql-analysis.yml b/.github/workflows/ci-codeql-analysis.yml index e39ec9f0ea..f30192641c 100644 --- a/.github/workflows/ci-codeql-analysis.yml +++ b/.github/workflows/ci-codeql-analysis.yml @@ -27,11 +27,11 @@ jobs: dotnet-version: '9.0.x' - name: Initialize CodeQL - uses: github/codeql-action/init@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4 + uses: github/codeql-action/init@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4 + uses: github/codeql-action/autobuild@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4e828ff8d448a8a6e532957b1811f387a63867e8 # v3.29.4 + uses: github/codeql-action/analyze@51f77329afa6477de8c49fc9c7046c15b9a4e79d # v3.29.5 diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 893ca03952..334c0f54a4 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -35,7 +35,7 @@ jobs: --verbosity minimal - name: Merge code coverage results - uses: danielpalme/ReportGenerator-GitHub-Action@82ef2bc4c83f42bbeec82a5cd9a8e3f6156b64b9 # v5.4.9 + uses: danielpalme/ReportGenerator-GitHub-Action@c1dd332d00304c5aa5d506aab698a5224a8fa24e # 5.4.11 with: reports: "**/coverage.cobertura.xml" targetdir: "merged/" From 90b4345cfd05958d6b771f1b620a666220fe2ede Mon Sep 17 00:00:00 2001 From: dikson804 Date: Tue, 29 Jul 2025 22:48:02 -0400 Subject: [PATCH 04/13] Translated using Weblate (Chinese (Traditional Han script, Hong Kong)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/zh_Hant_HK/ --- Emby.Server.Implementations/Localization/Core/zh-HK.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/zh-HK.json b/Emby.Server.Implementations/Localization/Core/zh-HK.json index 286efb7e92..39141d8416 100644 --- a/Emby.Server.Implementations/Localization/Core/zh-HK.json +++ b/Emby.Server.Implementations/Localization/Core/zh-HK.json @@ -136,5 +136,6 @@ "TaskAudioNormalizationDescription": "掃描檔案裏的音訊同等化資料。", "TaskCleanCollectionsAndPlaylistsDescription": "從資料庫及播放清單中移除已不存在的項目。", "TaskMoveTrickplayImagesDescription": "根據媒體庫設定移動現有的 Trickplay 檔案。", - "TaskMoveTrickplayImages": "轉移 Trickplay 影像位置" + "TaskMoveTrickplayImages": "轉移 Trickplay 影像位置", + "CleanupUserDataTask": "用戶資料清理工作" } From a5b4eca804f73027956b4b96d34ad766b4d215c3 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Wed, 30 Jul 2025 18:00:14 +0800 Subject: [PATCH 05/13] Add extra movflags to fMP4 to take initial audio delay into account Signed-off-by: nyanmisaka --- Jellyfin.Api/Controllers/DynamicHlsController.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index 4cac8ed678..2614fe9956 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -46,6 +46,7 @@ public class DynamicHlsController : BaseJellyfinApiController private readonly Version _minFFmpegFlacInMp4 = new Version(6, 0); private readonly Version _minFFmpegX265BframeInFmp4 = new Version(7, 0, 1); + private readonly Version _minFFmpegHlsSegmentOptions = new Version(5, 0); private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; @@ -1606,6 +1607,7 @@ public class DynamicHlsController : BaseJellyfinApiController var segmentFormat = string.Empty; var segmentContainer = outputExtension.TrimStart('.'); var inputModifier = _encodingHelper.GetInputModifier(state, _encodingOptions, segmentContainer); + var hlsArguments = $"-hls_playlist_type {(isEventPlaylist ? "event" : "vod")} -hls_list_size 0"; if (string.Equals(segmentContainer, "ts", StringComparison.OrdinalIgnoreCase)) { @@ -1621,6 +1623,11 @@ public class DynamicHlsController : BaseJellyfinApiController false => " -hls_fmp4_init_filename \"" + outputFileNameWithoutExtension + "-1" + outputExtension + "\"" }; + var useLegacySegmentOption = _mediaEncoder.EncoderVersion < _minFFmpegHlsSegmentOptions; + + // fMP4 needs this flag to write the audio packet DTS/PTS including the initial delay into MOOF::TRAF::TFDT + hlsArguments += $" {(useLegacySegmentOption ? "-hls_ts_options" : "-hls_segment_options")} movflags=+frag_discont"; + segmentFormat = "fmp4" + outputFmp4HeaderArg; } else @@ -1642,8 +1649,6 @@ public class DynamicHlsController : BaseJellyfinApiController Path.GetFileNameWithoutExtension(outputPath)); } - var hlsArguments = $"-hls_playlist_type {(isEventPlaylist ? "event" : "vod")} -hls_list_size 0"; - return string.Format( CultureInfo.InvariantCulture, "{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -copyts -avoid_negative_ts disabled -max_muxing_queue_size {6} -f hls -max_delay 5000000 -hls_time {7} -hls_segment_type {8} -start_number {9}{10} -hls_segment_filename \"{11}\" {12} -y \"{13}\"", From 6391dd95701b220a1d68342d3bb9db1a9c3713b7 Mon Sep 17 00:00:00 2001 From: Hestadgard Date: Wed, 30 Jul 2025 12:33:45 -0400 Subject: [PATCH 06/13] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)=20Translation:=20Jellyfin/Jellyfin=20Translate-?= =?UTF-8?q?URL:=20https://translate.jellyfin.org/projects/jellyfin/jellyfi?= =?UTF-8?q?n-core/nb=5FNO/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Emby.Server.Implementations/Localization/Core/nb.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/nb.json b/Emby.Server.Implementations/Localization/Core/nb.json index c00eb467f9..8baa63d89f 100644 --- a/Emby.Server.Implementations/Localization/Core/nb.json +++ b/Emby.Server.Implementations/Localization/Core/nb.json @@ -135,6 +135,6 @@ "TaskDownloadMissingLyricsDescription": "Last ned sangtekster", "TaskExtractMediaSegments": "Skann mediasegment", "TaskMoveTrickplayImages": "Migrer bildeplassering for Trickplay", - "TaskMoveTrickplayImagesDescription": "Flytter eksisterende Trickplay-filer i henhold til bibliotekseinstillingene.", + "TaskMoveTrickplayImagesDescription": "Flytter eksisterende Trickplay-filer i henhold til biblioteksinstillingene.", "TaskExtractMediaSegmentsDescription": "Trekker ut eller henter mediasegmenter fra plugins som støtter MediaSegment." } From 1d408a1503dcab28f7603bba2d0d34a2f45ab5a4 Mon Sep 17 00:00:00 2001 From: Hestadgard Date: Wed, 30 Jul 2025 12:37:11 -0400 Subject: [PATCH 07/13] Translated using Weblate (Norwegian Nynorsk) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nn/ --- Emby.Server.Implementations/Localization/Core/nn.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/nn.json b/Emby.Server.Implementations/Localization/Core/nn.json index 021f24f434..4b6b4deb61 100644 --- a/Emby.Server.Implementations/Localization/Core/nn.json +++ b/Emby.Server.Implementations/Localization/Core/nn.json @@ -119,5 +119,6 @@ "Forced": "https://betpro-dealers.com/", "Default": "Standard", "External": "Ekstern", - "HearingImpaired": "Nedsett høyrsel" + "HearingImpaired": "Nedsett høyrsel", + "TaskRefreshTrickplayImages": "Generer Trickplay-bilete" } From 711e649e354262d066d5cca6e1694aa369e59289 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Wed, 30 Jul 2025 19:41:34 +0000 Subject: [PATCH 08/13] Also migrate IsFolder --- Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs index e25c52786b..13e641c1d3 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs @@ -105,7 +105,7 @@ internal class MigrateLibraryDb : IDatabaseMigrationRoutine Audio, ExternalServiceId, IsInMixedFolder, DateLastSaved, LockedFields, Studios, Tags, TrailerTypes, OriginalTitle, PrimaryVersionId, DateLastMediaAdded, Album, LUFS, NormalizationGain, CriticRating, IsVirtualItem, SeriesName, UserDataKey, SeasonName, SeasonId, SeriesId, PresentationUniqueKey, InheritedParentalRatingValue, ExternalSeriesId, Tagline, ProviderIds, Images, ProductionLocations, ExtraIds, TotalBitrate, - ExtraType, Artists, AlbumArtists, ExternalId, SeriesPresentationUniqueKey, ShowId, OwnerId, MediaType, SortName, CleanName, UnratedType FROM TypedBaseItems + ExtraType, Artists, AlbumArtists, ExternalId, SeriesPresentationUniqueKey, ShowId, OwnerId, MediaType, SortName, CleanName, UnratedType, IsFolder FROM TypedBaseItems """; using (new TrackedMigrationStep("Loading TypedBaseItems", _logger)) { @@ -1167,6 +1167,11 @@ internal class MigrateLibraryDb : IDatabaseMigrationRoutine entity.UnratedType = unratedType; } + if (reader.TryGetBoolean(index++, out var isFolder)) + { + entity.IsFolder = isFolder; + } + var baseItem = BaseItemRepository.DeserializeBaseItem(entity, _logger, null, false); var dataKeys = baseItem.GetUserDataKeys(); userDataKeys.AddRange(dataKeys); From a1eb04dc0b1449f52bbb52be16a0fff3b8806523 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Wed, 30 Jul 2025 19:58:56 +0000 Subject: [PATCH 09/13] Add full migration for IsFolder flag --- .../Migrations/Routines/MigrateLibraryDb.cs | 3 + .../Migrations/Routines/ReseedFolderFlag.cs | 73 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs diff --git a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs index 13e641c1d3..e04a2737a6 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs @@ -90,6 +90,9 @@ internal class MigrateLibraryDb : IDatabaseMigrationRoutine operation.JellyfinDbContext.AncestorIds.ExecuteDelete(); } + // notify the other migration to just silently abort because the fix has been applied here already. + ReseedFolderFlag.RerunGuardFlag = true; + var legacyBaseItemWithUserKeys = new Dictionary(); connection.Open(); diff --git a/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs b/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs new file mode 100644 index 0000000000..d8c5cc0383 --- /dev/null +++ b/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs @@ -0,0 +1,73 @@ +#pragma warning disable RS0030 // Do not use banned APIs +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Emby.Server.Implementations.Data; +using Jellyfin.Database.Implementations; +using Jellyfin.Server.ServerSetupApp; +using MediaBrowser.Controller; +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Migrations.Routines; + +[JellyfinMigration("2025-07-30T21:50:00", nameof(ReseedFolderFlag))] +[JellyfinMigrationBackup(JellyfinDb = true)] +internal class ReseedFolderFlag : IAsyncMigrationRoutine +{ + private const string DbFilename = "library.db.old"; + + private readonly IStartupLogger _logger; + private readonly IServerApplicationPaths _paths; + private readonly IDbContextFactory _provider; + + public ReseedFolderFlag( + IStartupLogger startupLogger, + IDbContextFactory provider, + IServerApplicationPaths paths) + { + _logger = startupLogger; + _provider = provider; + _paths = paths; + } + + internal static bool RerunGuardFlag { get; set; } = false; + + public async Task PerformAsync(CancellationToken cancellationToken) + { + if (RerunGuardFlag) + { + _logger.LogInformation("Migration is skipped because it does not apply."); + return; + } + + _logger.LogInformation("Migrating the IsFolder flag from library.db.old may take a while, do not stop Jellyfin."); + + var dataPath = _paths.DataPath; + var libraryDbPath = Path.Combine(dataPath, DbFilename); + if (!File.Exists(libraryDbPath)) + { + _logger.LogError("Cannot migrate IsFolder flag from {LibraryDb} as it does not exist. This migration expects the MigrateLibraryDb to run first.", libraryDbPath); + return; + } + + var dbContext = await _provider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false); + await using (dbContext.ConfigureAwait(false)) + { + using var connection = new SqliteConnection($"Filename={libraryDbPath};Mode=ReadOnly"); + var queryResult = connection.Query( +""" + SELECT key FROM TypedBaseItems + + WHERE IsFolder = true +"""); + foreach (var entity in queryResult) + { + var id = entity.GetGuid(0); + await dbContext.BaseItems.Where(e => e.Id == id).ExecuteUpdateAsync(e => e.SetProperty(f => f.IsFolder, true), cancellationToken).ConfigureAwait(false); + } + } + } +} From ef733c5acebcb2f14428e180f83ab24e5c9b3c45 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Wed, 30 Jul 2025 20:10:26 +0000 Subject: [PATCH 10/13] use guid instead --- Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs b/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs index d8c5cc0383..371c2e8bef 100644 --- a/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs +++ b/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs @@ -59,7 +59,7 @@ internal class ReseedFolderFlag : IAsyncMigrationRoutine using var connection = new SqliteConnection($"Filename={libraryDbPath};Mode=ReadOnly"); var queryResult = connection.Query( """ - SELECT key FROM TypedBaseItems + SELECT guid FROM TypedBaseItems WHERE IsFolder = true """); From c8d2f436608c631e94461e70c3a7511031d32f58 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Wed, 30 Jul 2025 20:14:24 +0000 Subject: [PATCH 11/13] Add logging --- .../Migrations/Routines/ReseedFolderFlag.cs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs b/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs index 371c2e8bef..502763ac09 100644 --- a/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs +++ b/Jellyfin.Server/Migrations/Routines/ReseedFolderFlag.cs @@ -58,14 +58,15 @@ internal class ReseedFolderFlag : IAsyncMigrationRoutine { using var connection = new SqliteConnection($"Filename={libraryDbPath};Mode=ReadOnly"); var queryResult = connection.Query( -""" - SELECT guid FROM TypedBaseItems - - WHERE IsFolder = true -"""); - foreach (var entity in queryResult) + """ + SELECT guid FROM TypedBaseItems + WHERE IsFolder = true + """) + .Select(entity => entity.GetGuid(0)) + .ToList(); + _logger.LogInformation("Migrating the IsFolder flag for {Count} items.", queryResult.Count); + foreach (var id in queryResult) { - var id = entity.GetGuid(0); await dbContext.BaseItems.Where(e => e.Id == id).ExecuteUpdateAsync(e => e.SetProperty(f => f.IsFolder, true), cancellationToken).ConfigureAwait(false); } } From 34c9adef80bf75d5144e58107c9dd928ea7a5d51 Mon Sep 17 00:00:00 2001 From: nomener Date: Thu, 31 Jul 2025 02:57:00 -0400 Subject: [PATCH 12/13] Translated using Weblate (German) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/de/ --- Emby.Server.Implementations/Localization/Core/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/de.json b/Emby.Server.Implementations/Localization/Core/de.json index 8969b72c40..664da8249b 100644 --- a/Emby.Server.Implementations/Localization/Core/de.json +++ b/Emby.Server.Implementations/Localization/Core/de.json @@ -90,7 +90,7 @@ "UserStartedPlayingItemWithValues": "{0} hat die Wiedergabe von {1} auf {2} gestartet", "UserStoppedPlayingItemWithValues": "{0} hat die Wiedergabe von {1} auf {2} beendet", "ValueHasBeenAddedToLibrary": "{0} wurde deiner Bibliothek hinzugefügt", - "ValueSpecialEpisodeName": "Extra - {0}", + "ValueSpecialEpisodeName": "Extra – {0}", "VersionNumber": "Version {0}", "TaskDownloadMissingSubtitlesDescription": "Sucht im Internet basierend auf den Metadaten-Einstellungen nach fehlenden Untertiteln.", "TaskDownloadMissingSubtitles": "Fehlende Untertitel herunterladen", From b8fb8bd608bc775d97b9bb55e2bbe20c7f6e6db9 Mon Sep 17 00:00:00 2001 From: Hestadgard Date: Thu, 31 Jul 2025 03:31:10 -0400 Subject: [PATCH 13/13] Translated using Weblate (Norwegian Nynorsk) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/nn/ --- Emby.Server.Implementations/Localization/Core/nn.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/nn.json b/Emby.Server.Implementations/Localization/Core/nn.json index 4b6b4deb61..c37bef4635 100644 --- a/Emby.Server.Implementations/Localization/Core/nn.json +++ b/Emby.Server.Implementations/Localization/Core/nn.json @@ -120,5 +120,6 @@ "Default": "Standard", "External": "Ekstern", "HearingImpaired": "Nedsett høyrsel", - "TaskRefreshTrickplayImages": "Generer Trickplay-bilete" + "TaskRefreshTrickplayImages": "Generer Trickplay-bilete", + "TaskAudioNormalization": "Normalisering av lyd" }