diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs
index 64df4c4f04..62cb593351 100644
--- a/Jellyfin.Api/Controllers/LibraryController.cs
+++ b/Jellyfin.Api/Controllers/LibraryController.cs
@@ -131,6 +131,8 @@ public class LibraryController : BaseJellyfinApiController
     /// <param name="itemId">The item id.</param>
     /// <param name="userId">Optional. Filter by user id, and attach user data.</param>
     /// <param name="inheritFromParent">Optional. Determines whether or not parent items should be searched for theme media.</param>
+    /// <param name="sortBy">Optional. Specify one or more sort orders, comma delimited. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime.</param>
+    /// <param name="sortOrder">Optional. Sort Order - Ascending, Descending.</param>
     /// <response code="200">Theme songs returned.</response>
     /// <response code="404">Item not found.</response>
     /// <returns>The item theme songs.</returns>
@@ -141,7 +143,9 @@ public class LibraryController : BaseJellyfinApiController
     public ActionResult<ThemeMediaResult> GetThemeSongs(
         [FromRoute, Required] Guid itemId,
         [FromQuery] Guid? userId,
-        [FromQuery] bool inheritFromParent = false)
+        [FromQuery] bool inheritFromParent = false,
+        [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemSortBy[]? sortBy = null,
+        [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[]? sortOrder = null)
     {
         userId = RequestHelpers.GetUserId(User, userId);
         var user = userId.IsNullOrEmpty()
@@ -158,11 +162,15 @@ public class LibraryController : BaseJellyfinApiController
             return NotFound();
         }
 
+        sortOrder ??= [];
+        sortBy ??= [];
+        var orderBy = RequestHelpers.GetOrderBy(sortBy, sortOrder);
+
         IReadOnlyList<BaseItem> themeItems;
 
         while (true)
         {
-            themeItems = item.GetThemeSongs();
+            themeItems = item.GetThemeSongs(user, orderBy);
 
             if (themeItems.Count > 0 || !inheritFromParent)
             {
@@ -197,6 +205,8 @@ public class LibraryController : BaseJellyfinApiController
     /// <param name="itemId">The item id.</param>
     /// <param name="userId">Optional. Filter by user id, and attach user data.</param>
     /// <param name="inheritFromParent">Optional. Determines whether or not parent items should be searched for theme media.</param>
+    /// <param name="sortBy">Optional. Specify one or more sort orders, comma delimited. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime.</param>
+    /// <param name="sortOrder">Optional. Sort Order - Ascending, Descending.</param>
     /// <response code="200">Theme videos returned.</response>
     /// <response code="404">Item not found.</response>
     /// <returns>The item theme videos.</returns>
@@ -207,7 +217,9 @@ public class LibraryController : BaseJellyfinApiController
     public ActionResult<ThemeMediaResult> GetThemeVideos(
         [FromRoute, Required] Guid itemId,
         [FromQuery] Guid? userId,
-        [FromQuery] bool inheritFromParent = false)
+        [FromQuery] bool inheritFromParent = false,
+        [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemSortBy[]? sortBy = null,
+        [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[]? sortOrder = null)
     {
         userId = RequestHelpers.GetUserId(User, userId);
         var user = userId.IsNullOrEmpty()
@@ -223,11 +235,15 @@ public class LibraryController : BaseJellyfinApiController
             return NotFound();
         }
 
+        sortOrder ??= [];
+        sortBy ??= [];
+        var orderBy = RequestHelpers.GetOrderBy(sortBy, sortOrder);
+
         IEnumerable<BaseItem> themeItems;
 
         while (true)
         {
-            themeItems = item.GetThemeVideos();
+            themeItems = item.GetThemeVideos(user, orderBy);
 
             if (themeItems.Any() || !inheritFromParent)
             {
@@ -262,6 +278,8 @@ public class LibraryController : BaseJellyfinApiController
     /// <param name="itemId">The item id.</param>
     /// <param name="userId">Optional. Filter by user id, and attach user data.</param>
     /// <param name="inheritFromParent">Optional. Determines whether or not parent items should be searched for theme media.</param>
+    /// <param name="sortBy">Optional. Specify one or more sort orders, comma delimited. Options: Album, AlbumArtist, Artist, Budget, CommunityRating, CriticRating, DateCreated, DatePlayed, PlayCount, PremiereDate, ProductionYear, SortName, Random, Revenue, Runtime.</param>
+    /// <param name="sortOrder">Optional. Sort Order - Ascending, Descending.</param>
     /// <response code="200">Theme songs and videos returned.</response>
     /// <response code="404">Item not found.</response>
     /// <returns>The item theme videos.</returns>
@@ -271,17 +289,23 @@ public class LibraryController : BaseJellyfinApiController
     public ActionResult<AllThemeMediaResult> GetThemeMedia(
         [FromRoute, Required] Guid itemId,
         [FromQuery] Guid? userId,
-        [FromQuery] bool inheritFromParent = false)
+        [FromQuery] bool inheritFromParent = false,
+        [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemSortBy[]? sortBy = null,
+        [FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[]? sortOrder = null)
     {
         var themeSongs = GetThemeSongs(
             itemId,
             userId,
-            inheritFromParent);
+            inheritFromParent,
+            sortBy,
+            sortOrder);
 
         var themeVideos = GetThemeVideos(
             itemId,
             userId,
-            inheritFromParent);
+            inheritFromParent,
+            sortBy,
+            sortOrder);
 
         if (themeSongs.Result is StatusCodeResult { StatusCode: StatusCodes.Status404NotFound }
             || themeVideos.Result is StatusCodeResult { StatusCode: StatusCodes.Status404NotFound })
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 68ae67d053..7b6f364f7d 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -2544,14 +2544,24 @@ namespace MediaBrowser.Controller.Entities
                 StringComparison.OrdinalIgnoreCase);
         }
 
-        public IReadOnlyList<BaseItem> GetThemeSongs()
+        public IReadOnlyList<BaseItem> GetThemeSongs(User user = null)
         {
-            return GetExtras().Where(e => e.ExtraType == Model.Entities.ExtraType.ThemeSong).ToArray();
+            return GetThemeSongs(user, Array.Empty<(ItemSortBy, SortOrder)>());
         }
 
-        public IReadOnlyList<BaseItem> GetThemeVideos()
+        public IReadOnlyList<BaseItem> GetThemeSongs(User user, IEnumerable<(ItemSortBy SortBy, SortOrder SortOrder)> orderBy)
         {
-            return GetExtras().Where(e => e.ExtraType == Model.Entities.ExtraType.ThemeVideo).ToArray();
+            return LibraryManager.Sort(GetExtras().Where(e => e.ExtraType == Model.Entities.ExtraType.ThemeSong), user, orderBy).ToArray();
+        }
+
+        public IReadOnlyList<BaseItem> GetThemeVideos(User user = null)
+        {
+            return GetThemeVideos(user, Array.Empty<(ItemSortBy, SortOrder)>());
+        }
+
+        public IReadOnlyList<BaseItem> GetThemeVideos(User user, IEnumerable<(ItemSortBy SortBy, SortOrder SortOrder)> orderBy)
+        {
+            return LibraryManager.Sort(GetExtras().Where(e => e.ExtraType == Model.Entities.ExtraType.ThemeVideo), user, orderBy).ToArray();
         }
 
         /// <summary>
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 4af000557e..3a1d0c070b 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -744,7 +744,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 var filterValue = query.HasThemeSong.Value;
 
-                var themeCount = item.GetThemeSongs().Count;
+                var themeCount = item.GetThemeSongs(user).Count;
                 var ok = filterValue ? themeCount > 0 : themeCount == 0;
 
                 if (!ok)
@@ -757,7 +757,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 var filterValue = query.HasThemeVideo.Value;
 
-                var themeCount = item.GetThemeVideos().Count;
+                var themeCount = item.GetThemeVideos(user).Count;
                 var ok = filterValue ? themeCount > 0 : themeCount == 0;
 
                 if (!ok)