From 77ff451e60fa1fee31da1f5987e6e47a22244bb8 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sun, 1 Feb 2026 21:19:20 +0100 Subject: [PATCH 01/22] Only save unique values of ProductionLocations, Studios, Tags, Artists and AlbumArtists --- .../Controllers/ItemUpdateController.cs | 10 +++---- .../Item/BaseItemRepository.cs | 27 ++++++++++--------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Jellyfin.Api/Controllers/ItemUpdateController.cs b/Jellyfin.Api/Controllers/ItemUpdateController.cs index 605d2aeec2..b127433962 100644 --- a/Jellyfin.Api/Controllers/ItemUpdateController.cs +++ b/Jellyfin.Api/Controllers/ItemUpdateController.cs @@ -270,7 +270,7 @@ public class ItemUpdateController : BaseJellyfinApiController if (request.Studios is not null) { - item.Studios = Array.ConvertAll(request.Studios, x => x.Name); + item.Studios = Array.ConvertAll(request.Studios, x => x.Name).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); } if (request.DateCreated.HasValue) @@ -287,7 +287,7 @@ public class ItemUpdateController : BaseJellyfinApiController item.CustomRating = request.CustomRating; var currentTags = item.Tags; - var newTags = request.Tags; + var newTags = request.Tags.Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); var removedTags = currentTags.Except(newTags).ToList(); var addedTags = newTags.Except(currentTags).ToList(); item.Tags = newTags; @@ -373,7 +373,7 @@ public class ItemUpdateController : BaseJellyfinApiController if (request.ProductionLocations is not null) { - item.ProductionLocations = request.ProductionLocations; + item.ProductionLocations = request.ProductionLocations.Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); } item.PreferredMetadataCountryCode = request.PreferredMetadataCountryCode; @@ -421,7 +421,7 @@ public class ItemUpdateController : BaseJellyfinApiController { if (item is IHasAlbumArtist hasAlbumArtists) { - hasAlbumArtists.AlbumArtists = Array.ConvertAll(request.AlbumArtists, i => i.Name.Trim()); + hasAlbumArtists.AlbumArtists = Array.ConvertAll(request.AlbumArtists, i => i.Name.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); } } @@ -429,7 +429,7 @@ public class ItemUpdateController : BaseJellyfinApiController { if (item is IHasArtist hasArtists) { - hasArtists.Artists = Array.ConvertAll(request.ArtistItems, i => i.Name.Trim()); + hasArtists.Artists = Array.ConvertAll(request.ArtistItems, i => i.Name.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); } } diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs index 5bb4494dd2..cd28c6e43e 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs @@ -683,14 +683,15 @@ public sealed class BaseItemRepository .SelectMany(f => f.Values) .Distinct() .ToArray(); + + var types = allListedItemValues.Select(e => e.MagicNumber).Distinct().ToArray(); + var values = allListedItemValues.Select(e => e.Value).Distinct().ToArray(); + var allListedItemValuesSet = allListedItemValues.ToHashSet(); + var existingValues = context.ItemValues - .Select(e => new - { - item = e, - Key = e.Type + "+" + e.Value - }) - .Where(f => allListedItemValues.Select(e => $"{(int)e.MagicNumber}+{e.Value}").Contains(f.Key)) - .Select(e => e.item) + .Where(e => types.Contains(e.Type) && values.Contains(e.Value)) + .AsEnumerable() + .Where(e => allListedItemValuesSet.Contains((e.Type, e.Value))) .ToArray(); var missingItemValues = allListedItemValues.Except(existingValues.Select(f => (MagicNumber: f.Type, f.Value))).Select(f => new ItemValue() { @@ -1050,7 +1051,7 @@ public sealed class BaseItemRepository entity.TotalBitrate = dto.TotalBitrate; entity.ExternalId = dto.ExternalId; entity.Size = dto.Size; - entity.Genres = string.Join('|', dto.Genres); + entity.Genres = string.Join('|', dto.Genres.Distinct(StringComparer.OrdinalIgnoreCase)); entity.DateCreated = dto.DateCreated == DateTime.MinValue ? null : dto.DateCreated; entity.DateModified = dto.DateModified == DateTime.MinValue ? null : dto.DateModified; entity.ChannelId = dto.ChannelId; @@ -1077,9 +1078,9 @@ public sealed class BaseItemRepository } entity.ExtraIds = dto.ExtraIds is not null ? string.Join('|', dto.ExtraIds) : null; - entity.ProductionLocations = dto.ProductionLocations is not null ? string.Join('|', dto.ProductionLocations.Where(p => !string.IsNullOrWhiteSpace(p))) : null; - entity.Studios = dto.Studios is not null ? string.Join('|', dto.Studios) : null; - entity.Tags = dto.Tags is not null ? string.Join('|', dto.Tags) : null; + entity.ProductionLocations = dto.ProductionLocations is not null ? string.Join('|', dto.ProductionLocations.Where(p => !string.IsNullOrWhiteSpace(p)).Distinct(StringComparer.OrdinalIgnoreCase)) : null; + entity.Studios = dto.Studios is not null ? string.Join('|', dto.Studios.Distinct(StringComparer.OrdinalIgnoreCase)) : null; + entity.Tags = dto.Tags is not null ? string.Join('|', dto.Tags.Distinct(StringComparer.OrdinalIgnoreCase)) : null; entity.LockedFields = dto.LockedFields is not null ? dto.LockedFields .Select(e => new BaseItemMetadataField() { @@ -1122,12 +1123,12 @@ public sealed class BaseItemRepository if (dto is IHasArtist hasArtists) { - entity.Artists = hasArtists.Artists is not null ? string.Join('|', hasArtists.Artists) : null; + entity.Artists = hasArtists.Artists is not null ? string.Join('|', hasArtists.Artists.Distinct(StringComparer.OrdinalIgnoreCase)) : null; } if (dto is IHasAlbumArtist hasAlbumArtists) { - entity.AlbumArtists = hasAlbumArtists.AlbumArtists is not null ? string.Join('|', hasAlbumArtists.AlbumArtists) : null; + entity.AlbumArtists = hasAlbumArtists.AlbumArtists is not null ? string.Join('|', hasAlbumArtists.AlbumArtists.Distinct(StringComparer.OrdinalIgnoreCase)) : null; } if (dto is LiveTvProgram program) From 1dacb69d80d0fd65f8c45dd54ab278bc8fb28ed1 Mon Sep 17 00:00:00 2001 From: Shadowghost Date: Sun, 1 Feb 2026 21:51:36 +0100 Subject: [PATCH 02/22] Fix Genre Uniqueness --- Jellyfin.Api/Controllers/ItemUpdateController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Api/Controllers/ItemUpdateController.cs b/Jellyfin.Api/Controllers/ItemUpdateController.cs index b127433962..4faec060d8 100644 --- a/Jellyfin.Api/Controllers/ItemUpdateController.cs +++ b/Jellyfin.Api/Controllers/ItemUpdateController.cs @@ -249,7 +249,7 @@ public class ItemUpdateController : BaseJellyfinApiController item.IndexNumber = request.IndexNumber; item.ParentIndexNumber = request.ParentIndexNumber; item.Overview = request.Overview; - item.Genres = request.Genres; + item.Genres = request.Genres.Distinct(StringComparer.OrdinalIgnoreCase).ToArray(); if (item is Episode episode) { From 106f33227a20f1785b7a6c59ef6d4b68a5a8a880 Mon Sep 17 00:00:00 2001 From: theguymadmax Date: Sat, 14 Feb 2026 00:32:07 -0500 Subject: [PATCH 03/22] Use artist images for music library thumbnail --- .../Images/CollectionFolderImageProvider.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs index a25373326f..095934f896 100644 --- a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs +++ b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs @@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Images includeItemTypes = new[] { BaseItemKind.Series }; break; case CollectionType.music: - includeItemTypes = new[] { BaseItemKind.MusicAlbum }; + includeItemTypes = new[] { BaseItemKind.MusicArtist }; // Music albums usually don't have dedicated backdrops, so use artist instead break; case CollectionType.musicvideos: includeItemTypes = new[] { BaseItemKind.MusicVideo }; diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 7586b99e77..cb38b61119 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -22,7 +22,6 @@ using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Chapters; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dto; -using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; @@ -2129,17 +2128,6 @@ namespace MediaBrowser.Controller.Entities }; } - // Music albums usually don't have dedicated backdrops, so return one from the artist instead - if (GetType() == typeof(MusicAlbum) && imageType == ImageType.Backdrop) - { - var artist = FindParent(); - - if (artist is not null) - { - return artist.GetImages(imageType).ElementAtOrDefault(imageIndex); - } - } - return GetImages(imageType) .ElementAtOrDefault(imageIndex); } From ccf2d15d5dbb3457a712668ba3e4cc54119fe736 Mon Sep 17 00:00:00 2001 From: Evan Champion <110177090+evan314159@users.noreply.github.com> Date: Sat, 21 Feb 2026 20:59:57 +0800 Subject: [PATCH 04/22] AIFF support: add .aifc as audio file type, remove .aiff as image file type --- Emby.Naming/Common/NamingOptions.cs | 1 + src/Jellyfin.Drawing/ImageProcessor.cs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs index f61ca7e129..9103174d2c 100644 --- a/Emby.Naming/Common/NamingOptions.cs +++ b/Emby.Naming/Common/NamingOptions.cs @@ -225,6 +225,7 @@ namespace Emby.Naming.Common ".afc", ".amf", ".aif", + ".aifc", ".aiff", ".alac", ".amr", diff --git a/src/Jellyfin.Drawing/ImageProcessor.cs b/src/Jellyfin.Drawing/ImageProcessor.cs index 46e5213a8c..6ffb022842 100644 --- a/src/Jellyfin.Drawing/ImageProcessor.cs +++ b/src/Jellyfin.Drawing/ImageProcessor.cs @@ -85,7 +85,6 @@ public sealed class ImageProcessor : IImageProcessor, IDisposable "jpeg", "jpg", "png", - "aiff", "cr2", "crw", "nef", From 2068be12219a9bc046b455dbce369a10f69dadf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 22:50:41 +0000 Subject: [PATCH 05/22] Update GitHub Artifact Actions --- .github/workflows/ci-compat.yml | 8 ++++---- .github/workflows/ci-openapi.yml | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-compat.yml b/.github/workflows/ci-compat.yml index 8e3717b332..159492770d 100644 --- a/.github/workflows/ci-compat.yml +++ b/.github/workflows/ci-compat.yml @@ -26,7 +26,7 @@ jobs: dotnet build Jellyfin.Server -o ./out - name: Upload Head - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: abi-head retention-days: 14 @@ -65,7 +65,7 @@ jobs: dotnet build Jellyfin.Server -o ./out - name: Upload Head - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: abi-base retention-days: 14 @@ -85,13 +85,13 @@ jobs: steps: - name: Download abi-head - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: abi-head path: abi-head - name: Download abi-base - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: abi-base path: abi-base diff --git a/.github/workflows/ci-openapi.yml b/.github/workflows/ci-openapi.yml index 3d04ac5e0b..e267836bdd 100644 --- a/.github/workflows/ci-openapi.yml +++ b/.github/workflows/ci-openapi.yml @@ -29,7 +29,7 @@ jobs: run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests" - name: Upload openapi.json - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: openapi-head retention-days: 14 @@ -66,7 +66,7 @@ jobs: run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests" - name: Upload openapi.json - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: openapi-base retention-days: 14 @@ -85,13 +85,13 @@ jobs: - openapi-base steps: - name: Download openapi-head - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: openapi-head path: openapi-head - name: Download openapi-base - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: openapi-base path: openapi-base @@ -119,7 +119,7 @@ jobs: run: |- echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV - name: Download openapi-head - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: openapi-head path: openapi-head @@ -180,7 +180,7 @@ jobs: run: |- echo "JELLYFIN_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV - name: Download openapi-head - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 with: name: openapi-head path: openapi-head From bc316b3dc855e93d4d11e2c0d73d70326c38b889 Mon Sep 17 00:00:00 2001 From: NoFear0411 <9083405+NoFear0411@users.noreply.github.com> Date: Sun, 1 Mar 2026 00:00:05 +0400 Subject: [PATCH 06/22] Fix near-1:1 SAR values falsely flagged as anamorphic Encoders sometimes produce sample aspect ratios like 3201:3200 (0.03% off square) for content that has effectively square pixels. The exact string comparison against "1:1" marks these as anamorphic, which triggers unnecessary transcoding on clients that require non-anamorphic video. Parse the SAR ratio numerically and treat values within 1% of 1:1 as square pixels. This threshold is well clear of the nearest real anamorphic SAR (PAL 4:3 at 16:15 = 6.67% off). --- .../Probing/ProbeResultNormalizer.cs | 28 ++++++++++++++++++- .../Probing/ProbeResultNormalizerTests.cs | 18 ++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index dbe5322897..471df369ba 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -863,7 +863,7 @@ namespace MediaBrowser.MediaEncoding.Probing { stream.IsAnamorphic = false; } - else if (string.Equals(streamInfo.SampleAspectRatio, "1:1", StringComparison.Ordinal)) + else if (IsNearSquarePixelSar(streamInfo.SampleAspectRatio)) { stream.IsAnamorphic = false; } @@ -1154,6 +1154,32 @@ namespace MediaBrowser.MediaEncoding.Probing return Math.Abs(d1 - d2) <= variance; } + /// + /// Determines whether a sample aspect ratio represents square (or near-square) pixels. + /// Some encoders produce SARs like 3201:3200 for content that is effectively 1:1, + /// which would be falsely classified as anamorphic by an exact string comparison. + /// A 1% tolerance safely covers encoder rounding artifacts while preserving detection + /// of genuine anamorphic content (closest standard is PAL 4:3 at 16:15 = 6.67% off). + /// + internal static bool IsNearSquarePixelSar(string sar) + { + if (string.IsNullOrEmpty(sar)) + { + return false; + } + + var parts = sar.Split(':'); + if (parts.Length == 2 + && double.TryParse(parts[0], CultureInfo.InvariantCulture, out var num) + && double.TryParse(parts[1], CultureInfo.InvariantCulture, out var den) + && den > 0) + { + return IsClose(num / den, 1.0, 0.01); + } + + return string.Equals(sar, "1:1", StringComparison.Ordinal); + } + /// /// Gets a frame rate from a string value in ffprobe output /// This could be a number or in the format of 2997/125. diff --git a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs index 8a2f84734e..40f853699b 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs @@ -39,6 +39,23 @@ namespace Jellyfin.MediaEncoding.Tests.Probing public void GetFrameRate_Success(string value, float? expected) => Assert.Equal(expected, ProbeResultNormalizer.GetFrameRate(value)); + [Theory] + [InlineData("1:1", true)] // exact square pixels + [InlineData("3201:3200", true)] // 0.03% off — encoder rounding artifact (4K HEVC) + [InlineData("1215:1216", true)] // 0.08% off — encoder rounding artifact + [InlineData("1001:1000", true)] // 0.1% off — encoder rounding artifact + [InlineData("16:15", false)] // 6.67% off — PAL DVD 4:3, genuinely anamorphic + [InlineData("8:9", false)] // 11.1% off — NTSC DVD 4:3 + [InlineData("32:27", false)] // 18.5% off — NTSC DVD 16:9 + [InlineData("10:11", false)] // 9.1% off — DV NTSC + [InlineData("64:45", false)] // 42.2% off — PAL DVD 16:9 + [InlineData("4:3", false)] // 33.3% off — classic anamorphic + [InlineData("0:1", false)] // invalid/unknown SAR + [InlineData("", false)] // empty + [InlineData(null, false)] // null + public void IsNearSquarePixelSar_DetectsCorrectly(string sar, bool expected) + => Assert.Equal(expected, ProbeResultNormalizer.IsNearSquarePixelSar(sar)); + [Fact] public void GetMediaInfo_MetaData_Success() { @@ -123,6 +140,7 @@ namespace Jellyfin.MediaEncoding.Tests.Probing Assert.Equal(358, res.VideoStream.Height); Assert.Equal(720, res.VideoStream.Width); Assert.Equal("2.40:1", res.VideoStream.AspectRatio); + Assert.True(res.VideoStream.IsAnamorphic); // SAR 32:27 — genuinely anamorphic NTSC DVD 16:9 Assert.Equal("yuv420p", res.VideoStream.PixelFormat); Assert.Equal(31d, res.VideoStream.Level); Assert.Equal(1, res.VideoStream.RefFrames); From d55f082579933cad112a6fed6caa6130bf0d838c Mon Sep 17 00:00:00 2001 From: JPVenson Date: Sun, 1 Mar 2026 11:50:37 +0100 Subject: [PATCH 07/22] Merge pull request #16281 from jellyfin/JPVenson-patch-1 Revise note on hosting web client for development --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e546e7f115..46f531ff45 100644 --- a/README.md +++ b/README.md @@ -94,13 +94,12 @@ git clone https://github.com/jellyfin/jellyfin.git The server is configured to host the static files required for the [web client](https://github.com/jellyfin/jellyfin-web) in addition to serving the backend by default. Before you can run the server, you will need to get a copy of the web client since they are not included in this repository directly. -Note that it is also possible to [host the web client separately](#hosting-the-web-client-separately) from the web server with some additional configuration, in which case you can skip this step. +Note that it is recommended for development to [host the web client separately](#hosting-the-web-client-separately) from the web server with some additional configuration, in which case you can skip this step. -There are three options to get the files for the web client. +There are two options to get the files for the web client. -1. Download one of the finished builds from the [Azure DevOps pipeline](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=27). You can download the build for a specific release by looking at the [branches tab](https://dev.azure.com/jellyfin-project/jellyfin/_build?definitionId=27&_a=summary&repositoryFilter=6&view=branches) of the pipelines page. -2. Build them from source following the instructions on the [jellyfin-web repository](https://github.com/jellyfin/jellyfin-web) -3. Get the pre-built files from an existing installation of the server. For example, with a Windows server installation the client files are located at `C:\Program Files\Jellyfin\Server\jellyfin-web` +1. Build them from source following the instructions on the [jellyfin-web repository](https://github.com/jellyfin/jellyfin-web) +2. Get the pre-built files from an existing installation of the server. For example, with a Windows server installation the client files are located at `C:\Program Files\Jellyfin\Server\jellyfin-web` ### Running The Server From d2f733f9a4d91a09ab887d410b2778a916f27c7d Mon Sep 17 00:00:00 2001 From: MBR-0001 <55142207+MBR-0001@users.noreply.github.com> Date: Sun, 1 Mar 2026 05:57:22 -0500 Subject: [PATCH 08/22] Backport pull request #16204 from jellyfin/release-10.11.z Fix broken library subtitle download settings Original-merge: ca57166e95858f9c767b6279df6e5abfe9212700 Merged-by: Bond-009 Backported-by: Bond_009 --- .../FixLibrarySubtitleDownloadLanguages.cs | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs diff --git a/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs b/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs new file mode 100644 index 0000000000..e82123e5ac --- /dev/null +++ b/Jellyfin.Server/Migrations/Routines/FixLibrarySubtitleDownloadLanguages.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Jellyfin.Server.ServerSetupApp; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Globalization; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Jellyfin.Server.Migrations.Routines; + +/// +/// Migration to fix broken library subtitle download languages. +/// +[JellyfinMigration("2026-02-06T20:00:00", nameof(FixLibrarySubtitleDownloadLanguages))] +internal class FixLibrarySubtitleDownloadLanguages : IAsyncMigrationRoutine +{ + private readonly ILocalizationManager _localizationManager; + private readonly ILibraryManager _libraryManager; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// The Localization manager. + /// The startup logger for Startup UI integration. + /// The Library manager. + /// The logger. + public FixLibrarySubtitleDownloadLanguages( + ILocalizationManager localizationManager, + IStartupLogger startupLogger, + ILibraryManager libraryManager, + ILogger logger) + { + _localizationManager = localizationManager; + _libraryManager = libraryManager; + _logger = startupLogger.With(logger); + } + + /// + public Task PerformAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Starting to fix library subtitle download languages."); + + var virtualFolders = _libraryManager.GetVirtualFolders(false); + + foreach (var virtualFolder in virtualFolders) + { + var options = virtualFolder.LibraryOptions; + if (options.SubtitleDownloadLanguages is null || options.SubtitleDownloadLanguages.Length == 0) + { + continue; + } + + // Some virtual folders don't have a proper item id. + if (!Guid.TryParse(virtualFolder.ItemId, out var folderId)) + { + continue; + } + + var collectionFolder = _libraryManager.GetItemById(folderId); + if (collectionFolder is null) + { + _logger.LogWarning("Could not find collection folder for virtual folder '{LibraryName}' with id '{FolderId}'. Skipping.", virtualFolder.Name, folderId); + continue; + } + + var fixedLanguages = new List(); + + foreach (var language in options.SubtitleDownloadLanguages) + { + var foundLanguage = _localizationManager.FindLanguageInfo(language)?.ThreeLetterISOLanguageName; + if (foundLanguage is not null) + { + // Converted ISO 639-2/B to T (ger to deu) + if (!string.Equals(foundLanguage, language, StringComparison.OrdinalIgnoreCase)) + { + _logger.LogInformation("Converted '{Language}' to '{ResolvedLanguage}' in library '{LibraryName}'.", language, foundLanguage, virtualFolder.Name); + } + + if (fixedLanguages.Contains(foundLanguage, StringComparer.OrdinalIgnoreCase)) + { + _logger.LogInformation("Language '{Language}' already exists for library '{LibraryName}'. Skipping duplicate.", foundLanguage, virtualFolder.Name); + continue; + } + + fixedLanguages.Add(foundLanguage); + } + else + { + _logger.LogInformation("Could not resolve language '{Language}' in library '{LibraryName}'. Skipping.", language, virtualFolder.Name); + } + } + + options.SubtitleDownloadLanguages = [.. fixedLanguages]; + collectionFolder.UpdateLibraryOptions(options); + } + + _logger.LogInformation("Library subtitle download languages fixed."); + + return Task.CompletedTask; + } +} From f680495ca377b20488cc8133a054317d6daf48fc Mon Sep 17 00:00:00 2001 From: theguymadmax <171496228+theguymadmax@users.noreply.github.com> Date: Sun, 1 Mar 2026 05:57:23 -0500 Subject: [PATCH 09/22] Backport pull request #16253 from jellyfin/release-10.11.z Checkpoint WAL before moving library.db in migration Original-merge: b6a96513de5fa301db83c6adab47fe64db0ff48e Merged-by: Bond-009 Backported-by: Bond_009 --- .../Migrations/Routines/MigrateLibraryDb.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs index 70761fa7db..c6ac55b6eb 100644 --- a/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs +++ b/Jellyfin.Server/Migrations/Routines/MigrateLibraryDb.cs @@ -464,6 +464,16 @@ internal class MigrateLibraryDb : IDatabaseMigrationRoutine SqliteConnection.ClearAllPools(); + using (var checkpointConnection = new SqliteConnection($"Filename={libraryDbPath}")) + { + checkpointConnection.Open(); + using var cmd = checkpointConnection.CreateCommand(); + cmd.CommandText = "PRAGMA wal_checkpoint(TRUNCATE);"; + cmd.ExecuteNonQuery(); + } + + SqliteConnection.ClearAllPools(); + _logger.LogInformation("Move {0} to {1}.", libraryDbPath, libraryDbPath + ".old"); File.Move(libraryDbPath, libraryDbPath + ".old", true); } From d87fe973f3516e20ae4c4ecd8036286deeb4b51d Mon Sep 17 00:00:00 2001 From: NoFear0411 <9083405+NoFear0411@users.noreply.github.com> Date: Sun, 1 Mar 2026 18:51:27 +0400 Subject: [PATCH 10/22] Fix StyleCop and xUnit analyzer errors - Add missing param and returns XML doc tags (SA1611, SA1615) - Remove trailing alignment whitespace in test attributes (SA1025) - Use nullable string parameter for null test case (xUnit1012) --- .../Probing/ProbeResultNormalizer.cs | 2 ++ .../Probing/ProbeResultNormalizerTests.cs | 28 +++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 471df369ba..127bdd380d 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -1161,6 +1161,8 @@ namespace MediaBrowser.MediaEncoding.Probing /// A 1% tolerance safely covers encoder rounding artifacts while preserving detection /// of genuine anamorphic content (closest standard is PAL 4:3 at 16:15 = 6.67% off). /// + /// The sample aspect ratio string in "N:D" format. + /// true if the SAR is within 1% of 1:1; otherwise false. internal static bool IsNearSquarePixelSar(string sar) { if (string.IsNullOrEmpty(sar)) diff --git a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs index 40f853699b..8ebbd029ac 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/Probing/ProbeResultNormalizerTests.cs @@ -40,20 +40,20 @@ namespace Jellyfin.MediaEncoding.Tests.Probing => Assert.Equal(expected, ProbeResultNormalizer.GetFrameRate(value)); [Theory] - [InlineData("1:1", true)] // exact square pixels - [InlineData("3201:3200", true)] // 0.03% off — encoder rounding artifact (4K HEVC) - [InlineData("1215:1216", true)] // 0.08% off — encoder rounding artifact - [InlineData("1001:1000", true)] // 0.1% off — encoder rounding artifact - [InlineData("16:15", false)] // 6.67% off — PAL DVD 4:3, genuinely anamorphic - [InlineData("8:9", false)] // 11.1% off — NTSC DVD 4:3 - [InlineData("32:27", false)] // 18.5% off — NTSC DVD 16:9 - [InlineData("10:11", false)] // 9.1% off — DV NTSC - [InlineData("64:45", false)] // 42.2% off — PAL DVD 16:9 - [InlineData("4:3", false)] // 33.3% off — classic anamorphic - [InlineData("0:1", false)] // invalid/unknown SAR - [InlineData("", false)] // empty - [InlineData(null, false)] // null - public void IsNearSquarePixelSar_DetectsCorrectly(string sar, bool expected) + [InlineData("1:1", true)] + [InlineData("3201:3200", true)] + [InlineData("1215:1216", true)] + [InlineData("1001:1000", true)] + [InlineData("16:15", false)] + [InlineData("8:9", false)] + [InlineData("32:27", false)] + [InlineData("10:11", false)] + [InlineData("64:45", false)] + [InlineData("4:3", false)] + [InlineData("0:1", false)] + [InlineData("", false)] + [InlineData(null, false)] + public void IsNearSquarePixelSar_DetectsCorrectly(string? sar, bool expected) => Assert.Equal(expected, ProbeResultNormalizer.IsNearSquarePixelSar(sar)); [Fact] From 8715cb5b9ea7f2350c03890277ae651711717e8d Mon Sep 17 00:00:00 2001 From: Anthony Lavado Date: Sun, 1 Mar 2026 12:38:07 -0500 Subject: [PATCH 11/22] Update JetBrains logo link in README.md Update the logo to match the current branding that has been live for a while now. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 46f531ff45..7531481860 100644 --- a/README.md +++ b/README.md @@ -197,5 +197,5 @@ This project is supported by:
DigitalOcean   -JetBrains logo +JetBrains logo

From f2ed024296336cd7b63253e8d5fb2019df8724ed Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 2 Mar 2026 20:52:57 +0100 Subject: [PATCH 12/22] Update CI dependencies (#16324) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .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 66fa73d25b..00fabda93e 100644 --- a/.github/workflows/ci-codeql-analysis.yml +++ b/.github/workflows/ci-codeql-analysis.yml @@ -28,13 +28,13 @@ jobs: dotnet-version: '10.0.x' - name: Initialize CodeQL - uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/init@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/autobuild@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/analyze@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5 diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 5cb13d6947..5556bb09e9 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@ee0ae774f6d3afedcbd1683c1ab21b83670bdf8e # v5.5.1 + uses: danielpalme/ReportGenerator-GitHub-Action@2a7030e9775aab6c78e80cb66843051acdacee3e # v5.5.2 with: reports: "**/coverage.cobertura.xml" targetdir: "merged/" From e4500303bb59cd8671af8634881efd8548d8e86a Mon Sep 17 00:00:00 2001 From: Ori Date: Tue, 3 Mar 2026 11:09:13 -0500 Subject: [PATCH 13/22] Translated using Weblate (Hebrew (Israel)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/he_IL/ --- Emby.Server.Implementations/Localization/Core/he_IL.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/he_IL.json b/Emby.Server.Implementations/Localization/Core/he_IL.json index 0967ef424b..67bfbccfba 100644 --- a/Emby.Server.Implementations/Localization/Core/he_IL.json +++ b/Emby.Server.Implementations/Localization/Core/he_IL.json @@ -1 +1,4 @@ -{} +{ + "Books": "ספרים", + "NameSeasonNumber": "עונה {0}" +} From 44f7d2b854d092de86def8ee73ab285c5409190e Mon Sep 17 00:00:00 2001 From: Juan Date: Mon, 2 Mar 2026 13:15:48 -0500 Subject: [PATCH 14/22] Add missing ProducesResponseType(401) to InitiateQuickConnect The InitiateQuickConnect endpoint returns HTTP 401 Unauthorized when Quick Connect is disabled, and this was already documented in the XML response comment, but the corresponding [ProducesResponseType] attribute was missing, causing the OpenAPI/Swagger spec to omit it. Co-Authored-By: Claude Sonnet 4.6 --- Jellyfin.Api/Controllers/QuickConnectController.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Jellyfin.Api/Controllers/QuickConnectController.cs b/Jellyfin.Api/Controllers/QuickConnectController.cs index 2a15ff767c..bdb2a4d20b 100644 --- a/Jellyfin.Api/Controllers/QuickConnectController.cs +++ b/Jellyfin.Api/Controllers/QuickConnectController.cs @@ -52,6 +52,7 @@ public class QuickConnectController : BaseJellyfinApiController /// A with a secret and code for future use or an error message. [HttpPost("Initiate")] [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] public async Task> InitiateQuickConnect() { try From 5807bf1d8f98e5c8ab54e240d469a0af07210854 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 22:45:40 +0000 Subject: [PATCH 15/22] Update danielpalme/ReportGenerator-GitHub-Action action to v5.5.3 --- .github/workflows/ci-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 5556bb09e9..c5a64fd9f9 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@2a7030e9775aab6c78e80cb66843051acdacee3e # v5.5.2 + uses: danielpalme/ReportGenerator-GitHub-Action@2a82782178b2816d9d6960a7345fdd164791b323 # v5.5.3 with: reports: "**/coverage.cobertura.xml" targetdir: "merged/" From b83378d656adef9c2e0e7df101f7da84ef762fa5 Mon Sep 17 00:00:00 2001 From: Ori Date: Tue, 3 Mar 2026 21:03:13 -0500 Subject: [PATCH 16/22] Translated using Weblate (Hebrew (Israel)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/he_IL/ --- Emby.Server.Implementations/Localization/Core/he_IL.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/he_IL.json b/Emby.Server.Implementations/Localization/Core/he_IL.json index 67bfbccfba..1d688f01a3 100644 --- a/Emby.Server.Implementations/Localization/Core/he_IL.json +++ b/Emby.Server.Implementations/Localization/Core/he_IL.json @@ -1,4 +1,8 @@ { "Books": "ספרים", - "NameSeasonNumber": "עונה {0}" + "NameSeasonNumber": "עונה {0}", + "Channels": "ערוצים", + "Movies": "סרטים", + "Music": "מוזיקה", + "Collections": "אוספים" } From b444d2c66a39b7421879424f9c1ea57b3780d33b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 4 Mar 2026 16:07:01 +0000 Subject: [PATCH 17/22] Update dependency Polly to 8.6.6 --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 74d2ff8717..c47f69e3cd 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -57,7 +57,7 @@ - + From a7c95ab00954ff57ef76055bddc67eca15f36e35 Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 4 Mar 2026 15:19:55 -0500 Subject: [PATCH 18/22] Translated using Weblate (Afrikaans) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/af/ --- Emby.Server.Implementations/Localization/Core/af.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/af.json b/Emby.Server.Implementations/Localization/Core/af.json index 1dce589234..59fb33941b 100644 --- a/Emby.Server.Implementations/Localization/Core/af.json +++ b/Emby.Server.Implementations/Localization/Core/af.json @@ -135,5 +135,7 @@ "TaskExtractMediaSegments": "Media Segment Skandeer", "TaskExtractMediaSegmentsDescription": "Onttrek of verkry mediasegmente van MediaSegment-geaktiveerde inproppe.", "TaskMoveTrickplayImages": "Migreer Trickplay Beeldligging", - "TaskMoveTrickplayImagesDescription": "Skuif ontstaande trickplay lêers volgens die biblioteekinstellings." + "TaskMoveTrickplayImagesDescription": "Skuif ontstaande trickplay lêers volgens die biblioteekinstellings.", + "CleanupUserDataTask": "Gebruikers data skoon maak taak", + "CleanupUserDataTaskDescription": "Maak alle gebruikers data (kykstatus, gunstelingstatus, ens.) skoon van media wat nie meer vir ten minste 90 dae teenwoordig is nie." } From c843c71003cf0b758089a09f345e650fb0159f55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 06:38:13 +0000 Subject: [PATCH 19/22] Update actions/setup-dotnet action to v5.2.0 --- .github/workflows/ci-codeql-analysis.yml | 2 +- .github/workflows/ci-compat.yml | 4 ++-- .github/workflows/ci-openapi.yml | 4 ++-- .github/workflows/ci-tests.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-codeql-analysis.yml b/.github/workflows/ci-codeql-analysis.yml index 00fabda93e..a93b4a5354 100644 --- a/.github/workflows/ci-codeql-analysis.yml +++ b/.github/workflows/ci-codeql-analysis.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup .NET - uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/ci-compat.yml b/.github/workflows/ci-compat.yml index 159492770d..bd3751d371 100644 --- a/.github/workflows/ci-compat.yml +++ b/.github/workflows/ci-compat.yml @@ -17,7 +17,7 @@ jobs: repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Setup .NET - uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: dotnet-version: '10.0.x' @@ -47,7 +47,7 @@ jobs: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/ci-openapi.yml b/.github/workflows/ci-openapi.yml index e267836bdd..ffb4b78149 100644 --- a/.github/workflows/ci-openapi.yml +++ b/.github/workflows/ci-openapi.yml @@ -22,7 +22,7 @@ jobs: repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Setup .NET - uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: dotnet-version: '10.0.x' - name: Generate openapi.json @@ -59,7 +59,7 @@ jobs: git checkout --progress --force $ANCESTOR_REF - name: Setup .NET - uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0 + uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: dotnet-version: '10.0.x' - name: Generate openapi.json diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index c5a64fd9f9..7586e826b9 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - uses: actions/setup-dotnet@baa11fbfe1d6520db94683bd5c7a3818018e4309 # v5.1.0 + - uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0 with: dotnet-version: ${{ env.SDK_VERSION }} From bc05ecd543ba8b51704012d64e637b039502f146 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 5 Mar 2026 23:57:22 +0000 Subject: [PATCH 20/22] Update github/codeql-action action to v4.32.6 --- .github/workflows/ci-codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-codeql-analysis.yml b/.github/workflows/ci-codeql-analysis.yml index a93b4a5354..9eadf7632d 100644 --- a/.github/workflows/ci-codeql-analysis.yml +++ b/.github/workflows/ci-codeql-analysis.yml @@ -28,13 +28,13 @@ jobs: dotnet-version: '10.0.x' - name: Initialize CodeQL - uses: github/codeql-action/init@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5 + uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 with: languages: ${{ matrix.language }} queries: +security-extended - name: Autobuild - uses: github/codeql-action/autobuild@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5 + uses: github/codeql-action/autobuild@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c793b717bc78562f491db7b0e93a3a178b099162 # v4.32.5 + uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6 From 0ebf6a6db6dbd3d3148c8075427de0516b274537 Mon Sep 17 00:00:00 2001 From: crimsonspecter <246959308+crimsonspecter@users.noreply.github.com> Date: Fri, 6 Mar 2026 16:58:07 -0500 Subject: [PATCH 21/22] Backport pull request #16341 from jellyfin/release-10.11.z Fix hls segment length adjustment for remuxed content Original-merge: 09ba04662acf256ec0a22f56de7e02d65d0805f6 Merged-by: Bond-009 Backported-by: Bond_009 --- Jellyfin.Api/Controllers/DynamicHlsController.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs index f80b36c390..acd5dd64ec 100644 --- a/Jellyfin.Api/Controllers/DynamicHlsController.cs +++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs @@ -1403,8 +1403,8 @@ public class DynamicHlsController : BaseJellyfinApiController double fps = state.TargetFramerate ?? 0.0f; int segmentLength = state.SegmentLength * 1000; - // If framerate is fractional (i.e. 23.976), we need to slightly adjust segment length - if (Math.Abs(fps - Math.Floor(fps + 0.001f)) > 0.001) + // If video is transcoded and framerate is fractional (i.e. 23.976), we need to slightly adjust segment length + if (!EncodingHelper.IsCopyCodec(state.OutputVideoCodec) && Math.Abs(fps - Math.Floor(fps + 0.001f)) > 0.001) { double nearestIntFramerate = Math.Ceiling(fps); segmentLength = (int)Math.Ceiling(segmentLength * (nearestIntFramerate / fps)); From d6e2fcb233c0fd8f0b1a9af03293081d0c95bb4f Mon Sep 17 00:00:00 2001 From: Denislav Denev Date: Mon, 9 Mar 2026 20:32:08 -0400 Subject: [PATCH 22/22] Translated using Weblate (Bulgarian) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/bg/ --- Emby.Server.Implementations/Localization/Core/bg-BG.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/bg-BG.json b/Emby.Server.Implementations/Localization/Core/bg-BG.json index 92b8e5d565..054c7357e1 100644 --- a/Emby.Server.Implementations/Localization/Core/bg-BG.json +++ b/Emby.Server.Implementations/Localization/Core/bg-BG.json @@ -15,7 +15,7 @@ "Favorites": "Любими", "Folders": "Папки", "Genres": "Жанрове", - "HeaderAlbumArtists": "Изпълнители на албуми", + "HeaderAlbumArtists": "Изпълнители на албума", "HeaderContinueWatching": "Продължаване на гледането", "HeaderFavoriteAlbums": "Любими албуми", "HeaderFavoriteArtists": "Любими изпълнители",