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:
-
+
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": "Любими изпълнители",