Browse Source

Merge remote-tracking branch 'jellyfinorigin/master' into feature/pgsql_provider

JPVenson 4 months ago
parent
commit
17003f4d76
100 changed files with 285 additions and 308 deletions
  1. 1 1
      .devcontainer/install-ffmpeg.sh
  2. 1 1
      .github/ISSUE_TEMPLATE/issue report.yml
  3. 4 4
      .github/workflows/ci-codeql-analysis.yml
  4. 2 2
      .github/workflows/ci-compat.yml
  5. 2 2
      .github/workflows/ci-openapi.yml
  6. 2 1
      .github/workflows/ci-tests.yml
  7. 1 1
      .github/workflows/commands.yml
  8. 1 1
      .github/workflows/issue-template-check.yml
  9. 1 1
      Directory.Packages.props
  10. 1 1
      Emby.Naming/TV/SeriesResolver.cs
  11. 7 7
      Emby.Server.Implementations/HttpServer/WebSocketConnection.cs
  12. 2 2
      Emby.Server.Implementations/HttpServer/WebSocketManager.cs
  13. 2 2
      Emby.Server.Implementations/IO/ManagedFileSystem.cs
  14. 3 2
      Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs
  15. 11 10
      Emby.Server.Implementations/Library/LibraryManager.cs
  16. 4 4
      Emby.Server.Implementations/Library/MediaSourceManager.cs
  17. 13 17
      Emby.Server.Implementations/Library/UserViewManager.cs
  18. 2 1
      Emby.Server.Implementations/Localization/Core/fr-CA.json
  19. 7 1
      Emby.Server.Implementations/Localization/Core/lv.json
  20. 3 1
      Emby.Server.Implementations/Localization/Core/zh-HK.json
  21. 2 2
      Emby.Server.Implementations/Localization/LocalizationManager.cs
  22. 7 7
      Emby.Server.Implementations/Plugins/PluginManager.cs
  23. 2 2
      Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs
  24. 1 1
      Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs
  25. 2 2
      Emby.Server.Implementations/Session/SessionManager.cs
  26. 3 3
      Emby.Server.Implementations/Session/SessionWebSocketListener.cs
  27. 1 1
      Emby.Server.Implementations/Updates/InstallationManager.cs
  28. 1 1
      Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
  29. 1 1
      Jellyfin.Api/Controllers/AudioController.cs
  30. 6 6
      Jellyfin.Api/Controllers/DynamicHlsController.cs
  31. 1 1
      Jellyfin.Api/Controllers/UniversalAudioController.cs
  32. 3 3
      Jellyfin.Api/Controllers/UserLibraryController.cs
  33. 4 20
      Jellyfin.Api/Formatters/CssOutputFormatter.cs
  34. 1 14
      Jellyfin.Api/Formatters/XmlOutputFormatter.cs
  35. 3 5
      Jellyfin.Api/Helpers/DynamicHlsHelper.cs
  36. 1 1
      Jellyfin.Api/Helpers/StreamingHelpers.cs
  37. 1 1
      Jellyfin.Api/Models/MediaInfoDtos/OpenLiveStreamDto.cs
  38. 1 1
      Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs
  39. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/AncestorId.cs
  40. 2 2
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/AttachmentStreamInfo.cs
  41. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/BaseItemMetadataField.cs
  42. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/BaseItemTrailerType.cs
  43. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/ItemValue.cs
  44. 2 2
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/Libraries/CollectionItem.cs
  45. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/Libraries/Series.cs
  46. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/PeopleBaseItemMap.cs
  47. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/ProgramAudioEntity.cs
  48. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/Entities/TrickplayInfo.cs
  49. 1 1
      Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs
  50. 9 9
      Jellyfin.Server.Implementations/Item/BaseItemRepository.cs
  51. 1 1
      Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs
  52. 1 1
      Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs
  53. 9 7
      Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs
  54. 1 1
      Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs
  55. 1 1
      MediaBrowser.Common/Configuration/IConfigurationManager.cs
  56. 2 1
      MediaBrowser.Common/Net/NetworkUtils.cs
  57. 2 2
      MediaBrowser.Controller/Devices/IDeviceManager.cs
  58. 1 1
      MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs
  59. 3 3
      MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
  60. 10 12
      MediaBrowser.Controller/Entities/BaseItem.cs
  61. 6 11
      MediaBrowser.Controller/Entities/Folder.cs
  62. 1 1
      MediaBrowser.Controller/Entities/TV/Season.cs
  63. 1 1
      MediaBrowser.Controller/Library/IMediaSourceManager.cs
  64. 38 38
      MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
  65. 6 6
      MediaBrowser.Controller/MediaSegments/IMediaSegmentManager.cs
  66. 0 0
      MediaBrowser.Controller/MediaSegments/IMediaSegmentProvider.cs
  67. 2 2
      MediaBrowser.Controller/Net/IWebSocketConnection.cs
  68. 1 1
      MediaBrowser.Controller/Session/ISessionManager.cs
  69. 1 1
      MediaBrowser.Controller/Session/SessionInfo.cs
  70. 1 1
      MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs
  71. 1 1
      MediaBrowser.Controller/Streaming/StreamState.cs
  72. 1 1
      MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
  73. 1 1
      MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs
  74. 1 1
      MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs
  75. 3 3
      MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs
  76. 3 3
      MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs
  77. 3 3
      MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
  78. 2 2
      MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs
  79. 3 3
      MediaBrowser.Model/Configuration/ServerConfiguration.cs
  80. 2 2
      MediaBrowser.Model/Dlna/ConditionProcessor.cs
  81. 1 1
      MediaBrowser.Model/Dlna/DirectPlayProfile.cs
  82. 4 4
      MediaBrowser.Model/Dlna/StreamBuilder.cs
  83. 4 4
      MediaBrowser.Model/Drawing/ImageFormatExtensions.cs
  84. 1 1
      MediaBrowser.Model/Dto/SessionInfoDto.cs
  85. 1 1
      MediaBrowser.Model/Entities/HardwareAccelerationType.cs
  86. 1 1
      MediaBrowser.Model/Entities/MediaStream.cs
  87. 1 1
      MediaBrowser.Model/Entities/MetadataProvider.cs
  88. 3 3
      MediaBrowser.Model/Entities/ProviderIdsExtensions.cs
  89. 1 1
      MediaBrowser.Model/Globalization/ILocalizationManager.cs
  90. 2 2
      MediaBrowser.Model/IO/IFileSystem.cs
  91. 2 1
      MediaBrowser.Model/Net/MimeTypes.cs
  92. 6 1
      MediaBrowser.Model/Plugins/PluginStatus.cs
  93. 1 1
      MediaBrowser.Model/Session/TranscodingInfo.cs
  94. 1 1
      MediaBrowser.Model/System/PublicSystemInfo.cs
  95. 2 2
      MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
  96. 5 7
      MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs
  97. 3 3
      MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs
  98. 2 2
      MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs
  99. 2 2
      MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
  100. 1 1
      MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs

+ 1 - 1
.devcontainer/install-ffmpeg.sh

@@ -1,6 +1,6 @@
 #!/bin/bash
 
-## configure the following for a manuall install of a specific version from the repo
+## configure the following for a manual install of a specific version from the repo
 
 # wget https://repo.jellyfin.org/releases/server/ubuntu/versions/jellyfin-ffmpeg/6.0.1-1/jellyfin-ffmpeg6_6.0.1-1-jammy_amd64.deb -O ffmpeg.deb
 

+ 1 - 1
.github/ISSUE_TEMPLATE/issue report.yml

@@ -14,7 +14,7 @@ body:
       label: "This issue respects the following points:"
       description: All conditions are **required**. Failure to comply with any of these conditions may cause your issue to be closed without comment.
       options:
-        - label: This is a **bug**, not a question or a configuration issue; Please visit our forum or chat rooms first to troubleshoot with volunteers, before creating a report. The links can be found [here](https://jellyfin.org/contact/).
+        - label: This is a **bug**, not a question or a configuration issue; Please visit our [forum or chat rooms](https://jellyfin.org/contact/) first to troubleshoot with volunteers, before creating a report.
           required: true
         - label: This issue is **not** already reported on [GitHub](https://github.com/jellyfin/jellyfin/issues?q=is%3Aopen+is%3Aissue) _(I've searched it)_.
           required: true

+ 4 - 4
.github/workflows/ci-codeql-analysis.yml

@@ -22,16 +22,16 @@ jobs:
     - name: Checkout repository
       uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
     - name: Setup .NET
-      uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0
+      uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0
       with:
         dotnet-version: '9.0.x'
 
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
+      uses: github/codeql-action/init@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
       with:
         languages: ${{ matrix.language }}
         queries: +security-extended
     - name: Autobuild
-      uses: github/codeql-action/autobuild@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
+      uses: github/codeql-action/autobuild@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
     - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@f6091c0113d1dcf9b98e269ee48e8a7e51b7bdd4 # v3.28.5
+      uses: github/codeql-action/analyze@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8

+ 2 - 2
.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@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0
+        uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0
         with:
           dotnet-version: '9.0.x'
 
@@ -47,7 +47,7 @@ jobs:
           fetch-depth: 0
 
       - name: Setup .NET
-        uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0
+        uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0
         with:
           dotnet-version: '9.0.x'
 

+ 2 - 2
.github/workflows/ci-openapi.yml

@@ -21,7 +21,7 @@ jobs:
           ref: ${{ github.event.pull_request.head.sha }}
           repository: ${{ github.event.pull_request.head.repo.full_name }}
       - name: Setup .NET
-        uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0
+        uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0
         with:
           dotnet-version: '9.0.x'
       - name: Generate openapi.json
@@ -55,7 +55,7 @@ jobs:
           ANCESTOR_REF=$(git merge-base upstream/${{ github.base_ref }} origin/$HEAD_REF)
           git checkout --progress --force $ANCESTOR_REF
       - name: Setup .NET
-        uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0
+        uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0
         with:
           dotnet-version: '9.0.x'
       - name: Generate openapi.json

+ 2 - 1
.github/workflows/ci-tests.yml

@@ -16,12 +16,13 @@ jobs:
     strategy:
       matrix:
         os: ["ubuntu-latest", "macos-latest", "windows-latest"]
+      fail-fast: false
 
     runs-on: "${{ matrix.os }}"
     steps:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
 
-      - uses: actions/setup-dotnet@87b7050bc53ea08284295505d98d2aa94301e852 # v4.2.0
+      - uses: actions/setup-dotnet@3951f0dfe7a07e2313ec93c75700083e2005cbab # v4.3.0
         with:
           dotnet-version: ${{ env.SDK_VERSION }}
 

+ 1 - 1
.github/workflows/commands.yml

@@ -132,7 +132,7 @@ jobs:
         with:
           repository: jellyfin/jellyfin-triage-script
       - name: install python
-        uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
+        uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
         with:
           python-version: '3.12'
           cache: 'pip'

+ 1 - 1
.github/workflows/issue-template-check.yml

@@ -14,7 +14,7 @@ jobs:
         with:
           repository: jellyfin/jellyfin-triage-script
       - name: install python
-        uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
+        uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
         with:
           python-version: '3.12'
           cache: 'pip'

+ 1 - 1
Directory.Packages.props

@@ -80,7 +80,7 @@
     <PackageVersion Include="System.Text.Json" Version="9.0.1" />
     <PackageVersion Include="System.Threading.Tasks.Dataflow" Version="9.0.1" />
     <PackageVersion Include="TagLibSharp" Version="2.3.0" />
-    <PackageVersion Include="z440.atl.core" Version="6.13.0" />
+    <PackageVersion Include="z440.atl.core" Version="6.14.0" />
     <PackageVersion Include="TMDbLib" Version="2.2.0" />
     <PackageVersion Include="UTF.Unknown" Version="2.5.1" />
     <PackageVersion Include="Xunit.Priority" Version="1.1.6" />

+ 1 - 1
Emby.Naming/TV/SeriesResolver.cs

@@ -12,7 +12,7 @@ namespace Emby.Naming.TV
         /// <summary>
         /// Regex that matches strings of at least 2 characters separated by a dot or underscore.
         /// Used for removing separators between words, i.e turns "The_show" into "The show" while
-        /// preserving namings like "S.H.O.W".
+        /// preserving names like "S.H.O.W".
         /// </summary>
         [GeneratedRegex(@"((?<a>[^\._]{2,})[\._]*)|([\._](?<b>[^\._]{2,}))")]
         private static partial Regex SeriesNameRegex();

+ 7 - 7
Emby.Server.Implementations/HttpServer/WebSocketConnection.cs

@@ -82,17 +82,17 @@ namespace Emby.Server.Implementations.HttpServer
         public WebSocketState State => _socket.State;
 
         /// <inheritdoc />
-        public Task SendAsync(OutboundWebSocketMessage message, CancellationToken cancellationToken)
+        public async Task SendAsync(OutboundWebSocketMessage message, CancellationToken cancellationToken)
         {
             var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions);
-            return _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken);
+            await _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);
         }
 
         /// <inheritdoc />
-        public Task SendAsync<T>(OutboundWebSocketMessage<T> message, CancellationToken cancellationToken)
+        public async Task SendAsync<T>(OutboundWebSocketMessage<T> message, CancellationToken cancellationToken)
         {
             var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions);
-            return _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken);
+            await _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);
         }
 
         /// <inheritdoc />
@@ -224,12 +224,12 @@ namespace Emby.Server.Implementations.HttpServer
             return ret;
         }
 
-        private Task SendKeepAliveResponse()
+        private async Task SendKeepAliveResponse()
         {
             LastKeepAliveDate = DateTime.UtcNow;
-            return SendAsync(
+            await SendAsync(
                 new OutboundKeepAliveMessage(),
-                CancellationToken.None);
+                CancellationToken.None).ConfigureAwait(false);
         }
 
         /// <inheritdoc />

+ 2 - 2
Emby.Server.Implementations/HttpServer/WebSocketManager.cs

@@ -84,7 +84,7 @@ namespace Emby.Server.Implementations.HttpServer
         /// Processes the web socket message received.
         /// </summary>
         /// <param name="result">The result.</param>
-        private Task ProcessWebSocketMessageReceived(WebSocketMessageInfo result)
+        private async Task ProcessWebSocketMessageReceived(WebSocketMessageInfo result)
         {
             var tasks = new Task[_webSocketListeners.Length];
             for (var i = 0; i < _webSocketListeners.Length; ++i)
@@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.HttpServer
                 tasks[i] = _webSocketListeners[i].ProcessMessageAsync(result);
             }
 
-            return Task.WhenAll(tasks);
+            await Task.WhenAll(tasks).ConfigureAwait(false);
         }
     }
 }

+ 2 - 2
Emby.Server.Implementations/IO/ManagedFileSystem.cs

@@ -561,7 +561,7 @@ namespace Emby.Server.Implementations.IO
         {
             var enumerationOptions = GetEnumerationOptions(recursive);
 
-            // On linux and osx the search pattern is case sensitive
+            // On linux and macOS the search pattern is case-sensitive
             // If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method
             if ((enableCaseSensitiveExtensions || _isEnvironmentCaseInsensitive) && extensions is not null && extensions.Count == 1)
             {
@@ -618,7 +618,7 @@ namespace Emby.Server.Implementations.IO
         {
             var enumerationOptions = GetEnumerationOptions(recursive);
 
-            // On linux and osx the search pattern is case sensitive
+            // On linux and macOS the search pattern is case-sensitive
             // If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method
             if ((enableCaseSensitiveExtensions || _isEnvironmentCaseInsensitive) && extensions is not null && extensions.Length == 1)
             {

+ 3 - 2
Emby.Server.Implementations/Images/BaseDynamicImageProvider.cs

@@ -7,6 +7,7 @@ using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
+using System.Net.Mime;
 using System.Threading;
 using System.Threading.Tasks;
 using MediaBrowser.Common.Configuration;
@@ -116,9 +117,9 @@ namespace Emby.Server.Implementations.Images
 
             var mimeType = MimeTypes.GetMimeType(outputPath);
 
-            if (string.Equals(mimeType, "application/octet-stream", StringComparison.OrdinalIgnoreCase))
+            if (string.Equals(mimeType, MediaTypeNames.Application.Octet, StringComparison.OrdinalIgnoreCase))
             {
-                mimeType = "image/png";
+                mimeType = MediaTypeNames.Image.Png;
             }
 
             await ProviderManager.SaveImage(item, outputPath, mimeType, imageType, null, false, cancellationToken).ConfigureAwait(false);

+ 11 - 10
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -755,14 +755,7 @@ namespace Emby.Server.Implementations.Library
 
             if (folder.Id.IsEmpty())
             {
-                if (string.IsNullOrEmpty(folder.Path))
-                {
-                    folder.Id = GetNewItemId(folder.GetType().Name, folder.GetType());
-                }
-                else
-                {
-                    folder.Id = GetNewItemId(folder.Path, folder.GetType());
-                }
+                folder.Id = GetNewItemId(folder.Path, folder.GetType());
             }
 
             var dbItem = GetItemById(folder.Id) as BasePluginFolder;
@@ -1057,9 +1050,17 @@ namespace Emby.Server.Implementations.Library
                 cancellationToken: cancellationToken).ConfigureAwait(false);
 
             // Quickly scan CollectionFolders for changes
-            foreach (var folder in GetUserRootFolder().Children.OfType<Folder>())
+            foreach (var child in GetUserRootFolder().Children.OfType<Folder>())
             {
-                await folder.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+                // If the user has somehow deleted the collection directory, remove the metadata from the database.
+                if (child is CollectionFolder collectionFolder && !Directory.Exists(collectionFolder.Path))
+                {
+                    _itemRepository.DeleteItem(collectionFolder.Id);
+                }
+                else
+                {
+                    await child.RefreshMetadata(cancellationToken).ConfigureAwait(false);
+                }
             }
         }
 

+ 4 - 4
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Library
     public class MediaSourceManager : IMediaSourceManager, IDisposable
     {
         // Do not use a pipe here because Roku http requests to the server will fail, without any explicit error message.
-        private const char LiveStreamIdDelimeter = '_';
+        private const char LiveStreamIdDelimiter = '_';
 
         private readonly IServerApplicationHost _appHost;
         private readonly IItemRepository _itemRepo;
@@ -314,7 +314,7 @@ namespace Emby.Server.Implementations.Library
 
         private static void SetKeyProperties(IMediaSourceProvider provider, MediaSourceInfo mediaSource)
         {
-            var prefix = provider.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + LiveStreamIdDelimeter;
+            var prefix = provider.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + LiveStreamIdDelimiter;
 
             if (!string.IsNullOrEmpty(mediaSource.OpenToken) && !mediaSource.OpenToken.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
             {
@@ -867,11 +867,11 @@ namespace Emby.Server.Implementations.Library
         {
             ArgumentException.ThrowIfNullOrEmpty(key);
 
-            var keys = key.Split(LiveStreamIdDelimeter, 2);
+            var keys = key.Split(LiveStreamIdDelimiter, 2);
 
             var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), keys[0], StringComparison.OrdinalIgnoreCase));
 
-            var splitIndex = key.IndexOf(LiveStreamIdDelimeter, StringComparison.Ordinal);
+            var splitIndex = key.IndexOf(LiveStreamIdDelimiter, StringComparison.Ordinal);
             var keyId = key.Substring(splitIndex + 1);
 
             return (provider, keyId);

+ 13 - 17
Emby.Server.Implementations/Library/UserViewManager.cs

@@ -309,39 +309,40 @@ namespace Emby.Server.Implementations.Library
                 }
             }
 
-            var mediaTypes = new List<MediaType>();
+            MediaType[] mediaTypes = [];
 
             if (includeItemTypes.Length == 0)
             {
+                HashSet<MediaType> tmpMediaTypes = [];
                 foreach (var parent in parents.OfType<ICollectionFolder>())
                 {
                     switch (parent.CollectionType)
                     {
                         case CollectionType.books:
-                            mediaTypes.Add(MediaType.Book);
-                            mediaTypes.Add(MediaType.Audio);
+                            tmpMediaTypes.Add(MediaType.Book);
+                            tmpMediaTypes.Add(MediaType.Audio);
                             break;
                         case CollectionType.music:
-                            mediaTypes.Add(MediaType.Audio);
+                            tmpMediaTypes.Add(MediaType.Audio);
                             break;
                         case CollectionType.photos:
-                            mediaTypes.Add(MediaType.Photo);
-                            mediaTypes.Add(MediaType.Video);
+                            tmpMediaTypes.Add(MediaType.Photo);
+                            tmpMediaTypes.Add(MediaType.Video);
                             break;
                         case CollectionType.homevideos:
-                            mediaTypes.Add(MediaType.Photo);
-                            mediaTypes.Add(MediaType.Video);
+                            tmpMediaTypes.Add(MediaType.Photo);
+                            tmpMediaTypes.Add(MediaType.Video);
                             break;
                         default:
-                            mediaTypes.Add(MediaType.Video);
+                            tmpMediaTypes.Add(MediaType.Video);
                             break;
                     }
                 }
 
-                mediaTypes = mediaTypes.Distinct().ToList();
+                mediaTypes = tmpMediaTypes.ToArray();
             }
 
-            var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Count == 0
+            var excludeItemTypes = includeItemTypes.Length == 0 && mediaTypes.Length == 0
                 ? new[]
                 {
                     BaseItemKind.Person,
@@ -367,14 +368,9 @@ namespace Emby.Server.Implementations.Library
                 Limit = limit * 5,
                 IsPlayed = isPlayed,
                 DtoOptions = options,
-                MediaTypes = mediaTypes.ToArray()
+                MediaTypes = mediaTypes
             };
 
-            if (parents.Count == 0)
-            {
-                return _libraryManager.GetItemList(query, false);
-            }
-
             return _libraryManager.GetItemList(query, parents);
         }
     }

+ 2 - 1
Emby.Server.Implementations/Localization/Core/fr-CA.json

@@ -135,5 +135,6 @@
     "TaskDownloadMissingLyricsDescription": "Téléchargement des paroles des chansons",
     "TaskMoveTrickplayImagesDescription": "Déplace les fichiers trickplay existants en fonction des paramètres de la bibliothèque.",
     "TaskDownloadMissingLyrics": "Télécharger les paroles des chansons manquantes",
-    "TaskMoveTrickplayImages": "Changer l'emplacement des images Trickplay"
+    "TaskMoveTrickplayImages": "Changer l'emplacement des images Trickplay",
+    "TaskExtractMediaSegmentsDescription": "Extrait ou obtient des segments de média à partir des plugins compatibles avec MediaSegment."
 }

+ 7 - 1
Emby.Server.Implementations/Localization/Core/lv.json

@@ -129,5 +129,11 @@
     "TaskAudioNormalization": "Audio normalizācija",
     "TaskCleanCollectionsAndPlaylistsDescription": "Noņem vairs neeksistējošus vienumus no kolekcijām un atskaņošanas sarakstiem.",
     "TaskAudioNormalizationDescription": "Skanē failus priekš audio normālizācijas informācijas.",
-    "TaskCleanCollectionsAndPlaylists": "Notīrīt kolekcijas un atskaņošanas sarakstus"
+    "TaskCleanCollectionsAndPlaylists": "Notīrīt kolekcijas un atskaņošanas sarakstus",
+    "TaskExtractMediaSegments": "Multivides segmenta skenēšana",
+    "TaskExtractMediaSegmentsDescription": "Izvelk vai iegūst multivides segmentus no MediaSegment iespējotiem spraudņiem.",
+    "TaskMoveTrickplayImages": "Trickplay attēlu pārvietošana",
+    "TaskMoveTrickplayImagesDescription": "Pārvieto esošos trickplay failus atbilstoši bibliotēkas iestatījumiem.",
+    "TaskDownloadMissingLyrics": "Lejupielādēt trūkstošos vārdus",
+    "TaskDownloadMissingLyricsDescription": "Lejupielādēt vārdus dziesmām"
 }

+ 3 - 1
Emby.Server.Implementations/Localization/Core/zh-HK.json

@@ -134,5 +134,7 @@
     "TaskCleanCollectionsAndPlaylists": "整理媒體與播放清單",
     "TaskAudioNormalization": "音訊同等化",
     "TaskAudioNormalizationDescription": "掃描檔案裏的音訊同等化資料。",
-    "TaskCleanCollectionsAndPlaylistsDescription": "從資料庫及播放清單中移除已不存在的項目。"
+    "TaskCleanCollectionsAndPlaylistsDescription": "從資料庫及播放清單中移除已不存在的項目。",
+    "TaskMoveTrickplayImagesDescription": "根據媒體庫設定移動現有的 Trickplay 檔案。",
+    "TaskMoveTrickplayImages": "轉移 Trickplay 影像位置"
 }

+ 2 - 2
Emby.Server.Implementations/Localization/LocalizationManager.cs

@@ -231,13 +231,13 @@ namespace Emby.Server.Implementations.Localization
                 ratings.Add(new ParentalRating("21", 21));
             }
 
-            // A lot of countries don't excplicitly have a seperate rating for adult content
+            // A lot of countries don't explicitly have a separate rating for adult content
             if (ratings.All(x => x.Value != 1000))
             {
                 ratings.Add(new ParentalRating("XXX", 1000));
             }
 
-            // A lot of countries don't excplicitly have a seperate rating for banned content
+            // A lot of countries don't explicitly have a separate rating for banned content
             if (ratings.All(x => x.Value != 1001))
             {
                 ratings.Add(new ParentalRating("Banned", 1001));

+ 7 - 7
Emby.Server.Implementations/Plugins/PluginManager.cs

@@ -119,7 +119,7 @@ namespace Emby.Server.Implementations.Plugins
             // Now load the assemblies..
             foreach (var plugin in _plugins)
             {
-                UpdatePluginSuperceedStatus(plugin);
+                UpdatePluginSupersededStatus(plugin);
 
                 if (plugin.IsEnabledAndSupported == false)
                 {
@@ -214,7 +214,7 @@ namespace Emby.Server.Implementations.Plugins
                     continue;
                 }
 
-                UpdatePluginSuperceedStatus(plugin);
+                UpdatePluginSupersededStatus(plugin);
                 if (!plugin.IsEnabledAndSupported)
                 {
                     continue;
@@ -624,9 +624,9 @@ namespace Emby.Server.Implementations.Plugins
             }
         }
 
-        private void UpdatePluginSuperceedStatus(LocalPlugin plugin)
+        private void UpdatePluginSupersededStatus(LocalPlugin plugin)
         {
-            if (plugin.Manifest.Status != PluginStatus.Superceded)
+            if (plugin.Manifest.Status != PluginStatus.Superseded)
             {
                 return;
             }
@@ -876,7 +876,7 @@ namespace Emby.Server.Implementations.Plugins
         }
 
         /// <summary>
-        /// Changes the status of the other versions of the plugin to "Superceded".
+        /// Changes the status of the other versions of the plugin to "Superseded".
         /// </summary>
         /// <param name="plugin">The <see cref="LocalPlugin"/> that's master.</param>
         private void ProcessAlternative(LocalPlugin plugin)
@@ -896,11 +896,11 @@ namespace Emby.Server.Implementations.Plugins
                 return;
             }
 
-            if (plugin.Manifest.Status == PluginStatus.Active && !ChangePluginState(previousVersion, PluginStatus.Superceded))
+            if (plugin.Manifest.Status == PluginStatus.Active && !ChangePluginState(previousVersion, PluginStatus.Superseded))
             {
                 _logger.LogError("Unable to enable version {Version} of {Name}", previousVersion.Version, previousVersion.Name);
             }
-            else if (plugin.Manifest.Status == PluginStatus.Superceded && !ChangePluginState(previousVersion, PluginStatus.Active))
+            else if (plugin.Manifest.Status == PluginStatus.Superseded && !ChangePluginState(previousVersion, PluginStatus.Active))
             {
                 _logger.LogError("Unable to supercede version {Version} of {Name}", previousVersion.Version, previousVersion.Name);
             }

+ 2 - 2
Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs

@@ -543,7 +543,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
             {
                 DisposeTriggers();
 
-                var wassRunning = State == TaskState.Running;
+                var wasRunning = State == TaskState.Running;
                 var startTime = CurrentExecutionStartTime;
 
                 var token = CurrentCancellationTokenSource;
@@ -596,7 +596,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
                     }
                 }
 
-                if (wassRunning)
+                if (wasRunning)
                 {
                     OnTaskCompleted(startTime, DateTime.UtcNow, TaskCompletionStatus.Aborted, null);
                 }

+ 1 - 1
Emby.Server.Implementations/ScheduledTasks/Tasks/PluginUpdateTask.cs

@@ -88,7 +88,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
                 }
                 catch (OperationCanceledException)
                 {
-                    // InstallPackage has it's own inner cancellation token, so only throw this if it's ours
+                    // InstallPackage has its own inner cancellation token, so only throw this if it's ours
                     if (cancellationToken.IsCancellationRequested)
                     {
                         throw;

+ 2 - 2
Emby.Server.Implementations/Session/SessionManager.cs

@@ -1304,7 +1304,7 @@ namespace Emby.Server.Implementations.Session
 
             if (item is null)
             {
-                _logger.LogError("A non-existent item Id {0} was passed into TranslateItemForPlayback", id);
+                _logger.LogError("A nonexistent item Id {0} was passed into TranslateItemForPlayback", id);
                 return Array.Empty<BaseItem>();
             }
 
@@ -1357,7 +1357,7 @@ namespace Emby.Server.Implementations.Session
 
             if (item is null)
             {
-                _logger.LogError("A non-existent item Id {0} was passed into TranslateItemForInstantMix", id);
+                _logger.LogError("A nonexistent item Id {0} was passed into TranslateItemForInstantMix", id);
                 return new List<BaseItem>();
             }
 

+ 3 - 3
Emby.Server.Implementations/Session/SessionWebSocketListener.cs

@@ -276,11 +276,11 @@ namespace Emby.Server.Implementations.Session
         /// </summary>
         /// <param name="webSocket">The WebSocket.</param>
         /// <returns>Task.</returns>
-        private Task SendForceKeepAlive(IWebSocketConnection webSocket)
+        private async Task SendForceKeepAlive(IWebSocketConnection webSocket)
         {
-            return webSocket.SendAsync(
+            await webSocket.SendAsync(
                 new ForceKeepAliveMessage(WebSocketLostTimeout),
-                CancellationToken.None);
+                CancellationToken.None).ConfigureAwait(false);
         }
     }
 }

+ 1 - 1
Emby.Server.Implementations/Updates/InstallationManager.cs

@@ -187,7 +187,7 @@ namespace Emby.Server.Implementations.Updates
                                 await _pluginManager.PopulateManifest(package, version.VersionNumber, plugin.Path, plugin.Manifest.Status).ConfigureAwait(false);
                             }
 
-                            // Remove versions with a target ABI greater then the current application version.
+                            // Remove versions with a target ABI greater than the current application version.
                             if (Version.TryParse(version.TargetAbi, out var targetAbi) && _applicationHost.ApplicationVersion < targetAbi)
                             {
                                 package.Versions.RemoveAt(i);

+ 1 - 1
Jellyfin.Api/Auth/CustomAuthenticationHandler.cs

@@ -58,7 +58,7 @@ namespace Jellyfin.Api.Auth
 
                 var claims = new[]
                 {
-                    new Claim(ClaimTypes.Name, authorizationInfo.User?.Username ?? string.Empty),
+                    new Claim(ClaimTypes.Name, authorizationInfo.User.Username),
                     new Claim(ClaimTypes.Role, role),
                     new Claim(InternalClaimTypes.UserId, authorizationInfo.UserId.ToString("N", CultureInfo.InvariantCulture)),
                     new Claim(InternalClaimTypes.DeviceId, authorizationInfo.DeviceId),

+ 1 - 1
Jellyfin.Api/Controllers/AudioController.cs

@@ -238,7 +238,7 @@ public class AudioController : BaseJellyfinApiController
     /// <param name="maxVideoBitDepth">Optional. The maximum video bit depth.</param>
     /// <param name="requireAvc">Optional. Whether to require avc.</param>
     /// <param name="deInterlace">Optional. Whether to deinterlace the video.</param>
-    /// <param name="requireNonAnamorphic">Optional. Whether to require a non anamporphic stream.</param>
+    /// <param name="requireNonAnamorphic">Optional. Whether to require a non anamorphic stream.</param>
     /// <param name="transcodingMaxAudioChannels">Optional. The maximum number of audio channels to transcode.</param>
     /// <param name="cpuCoreLimit">Optional. The limit of how many cpu cores to use.</param>
     /// <param name="liveStreamId">The live stream id.</param>

+ 6 - 6
Jellyfin.Api/Controllers/DynamicHlsController.cs

@@ -459,7 +459,7 @@ public class DynamicHlsController : BaseJellyfinApiController
         [FromQuery] int? videoStreamIndex,
         [FromQuery] EncodingContext? context,
         [FromQuery] Dictionary<string, string> streamOptions,
-        [FromQuery] bool enableAdaptiveBitrateStreaming = true,
+        [FromQuery] bool enableAdaptiveBitrateStreaming = false,
         [FromQuery] bool enableTrickplay = true,
         [FromQuery] bool enableAudioVbrEncoding = true,
         [FromQuery] bool alwaysBurnInSubtitleWhenTranscoding = false)
@@ -634,7 +634,7 @@ public class DynamicHlsController : BaseJellyfinApiController
         [FromQuery] int? videoStreamIndex,
         [FromQuery] EncodingContext? context,
         [FromQuery] Dictionary<string, string> streamOptions,
-        [FromQuery] bool enableAdaptiveBitrateStreaming = true,
+        [FromQuery] bool enableAdaptiveBitrateStreaming = false,
         [FromQuery] bool enableAudioVbrEncoding = true)
     {
         var streamingRequest = new HlsAudioRequestDto
@@ -1778,7 +1778,7 @@ public class DynamicHlsController : BaseJellyfinApiController
         }
         else if (state.AudioStream?.CodecTag is not null && state.AudioStream.CodecTag.Equals("ac-4", StringComparison.Ordinal))
         {
-            // ac-4 audio tends to hava a super weird sample rate that will fail most encoders
+            // ac-4 audio tends to have a super weird sample rate that will fail most encoders
             // force resample it to 48KHz
             args += " -ar 48000";
         }
@@ -2056,16 +2056,16 @@ public class DynamicHlsController : BaseJellyfinApiController
         }
     }
 
-    private Task DeleteLastFile(string playlistPath, string segmentExtension, int retryCount)
+    private async Task DeleteLastFile(string playlistPath, string segmentExtension, int retryCount)
     {
         var file = GetLastTranscodingFile(playlistPath, segmentExtension, _fileSystem);
 
         if (file is null)
         {
-            return Task.CompletedTask;
+            return;
         }
 
-        return DeleteFile(file.FullName, retryCount);
+        await DeleteFile(file.FullName, retryCount).ConfigureAwait(false);
     }
 
     private async Task DeleteFile(string path, int retryCount)

+ 1 - 1
Jellyfin.Api/Controllers/UniversalAudioController.cs

@@ -222,7 +222,7 @@ public class UniversalAudioController : BaseJellyfinApiController
                 TranscodeReasons = mediaSource.TranscodeReasons == 0 ? null : mediaSource.TranscodeReasons.ToString(),
                 Context = EncodingContext.Static,
                 StreamOptions = new Dictionary<string, string>(),
-                EnableAdaptiveBitrateStreaming = true,
+                EnableAdaptiveBitrateStreaming = false,
                 EnableAudioVbrEncoding = enableAudioVbrEncoding
             };
 

+ 3 - 3
Jellyfin.Api/Controllers/UserLibraryController.cs

@@ -634,10 +634,10 @@ public class UserLibraryController : BaseJellyfinApiController
     {
         if (item is Person)
         {
-            var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview) && item.HasImage(ImageType.Primary);
-            var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 3;
+            var hasMetadata = !string.IsNullOrWhiteSpace(item.Overview) && item.HasImage(ImageType.Primary);
+            var performFullRefresh = !hasMetadata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 3;
 
-            if (!hasMetdata)
+            if (!hasMetadata)
             {
                 var options = new MetadataRefreshOptions(new DirectoryService(_fileSystem))
                 {

+ 4 - 20
Jellyfin.Api/Formatters/CssOutputFormatter.cs

@@ -1,6 +1,4 @@
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
+using System.Net.Mime;
 using Microsoft.AspNetCore.Mvc.Formatters;
 
 namespace Jellyfin.Api.Formatters;
@@ -8,28 +6,14 @@ namespace Jellyfin.Api.Formatters;
 /// <summary>
 /// Css output formatter.
 /// </summary>
-public class CssOutputFormatter : TextOutputFormatter
+public sealed class CssOutputFormatter : StringOutputFormatter
 {
     /// <summary>
     /// Initializes a new instance of the <see cref="CssOutputFormatter"/> class.
     /// </summary>
     public CssOutputFormatter()
     {
-        SupportedMediaTypes.Add("text/css");
-
-        SupportedEncodings.Add(Encoding.UTF8);
-        SupportedEncodings.Add(Encoding.Unicode);
-    }
-
-    /// <summary>
-    /// Write context object to stream.
-    /// </summary>
-    /// <param name="context">Writer context.</param>
-    /// <param name="selectedEncoding">Unused. Writer encoding.</param>
-    /// <returns>Write stream task.</returns>
-    public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
-    {
-        var stringResponse = context.Object?.ToString();
-        return stringResponse is null ? Task.CompletedTask : context.HttpContext.Response.WriteAsync(stringResponse);
+        SupportedMediaTypes.Clear();
+        SupportedMediaTypes.Add(MediaTypeNames.Text.Css);
     }
 }

+ 1 - 14
Jellyfin.Api/Formatters/XmlOutputFormatter.cs

@@ -1,7 +1,4 @@
 using System.Net.Mime;
-using System.Text;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc.Formatters;
 
 namespace Jellyfin.Api.Formatters;
@@ -9,7 +6,7 @@ namespace Jellyfin.Api.Formatters;
 /// <summary>
 /// Xml output formatter.
 /// </summary>
-public class XmlOutputFormatter : TextOutputFormatter
+public sealed class XmlOutputFormatter : StringOutputFormatter
 {
     /// <summary>
     /// Initializes a new instance of the <see cref="XmlOutputFormatter"/> class.
@@ -18,15 +15,5 @@ public class XmlOutputFormatter : TextOutputFormatter
     {
         SupportedMediaTypes.Clear();
         SupportedMediaTypes.Add(MediaTypeNames.Text.Xml);
-
-        SupportedEncodings.Add(Encoding.UTF8);
-        SupportedEncodings.Add(Encoding.Unicode);
-    }
-
-    /// <inheritdoc />
-    public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
-    {
-        var stringResponse = context.Object?.ToString();
-        return stringResponse is null ? Task.CompletedTask : context.HttpContext.Response.WriteAsync(stringResponse);
     }
 }

+ 3 - 5
Jellyfin.Api/Helpers/DynamicHlsHelper.cs

@@ -267,7 +267,7 @@ public class DynamicHlsHelper
 
         if (EnableAdaptiveBitrateStreaming(state, isLiveStream, enableAdaptiveBitrateStreaming, _httpContextAccessor.HttpContext.GetNormalizedRemoteIP()))
         {
-            var requestedVideoBitrate = state.VideoRequest is null ? 0 : state.VideoRequest.VideoBitRate ?? 0;
+            var requestedVideoBitrate = state.VideoRequest?.VideoBitRate ?? 0;
 
             // By default, vary by just 200k
             var variation = GetBitrateVariation(totalBitrate);
@@ -526,9 +526,7 @@ public class DynamicHlsHelper
             return false;
         }
 
-        // Having problems in android
-        return false;
-        // return state.VideoRequest.VideoBitRate.HasValue;
+        return state.VideoRequest?.VideoBitRate.HasValue ?? false;
     }
 
     private void AddSubtitles(StreamState state, IEnumerable<MediaStream> subtitles, StringBuilder builder, ClaimsPrincipal user)
@@ -616,7 +614,7 @@ public class DynamicHlsHelper
             && state.VideoStream is not null
             && state.VideoStream.Level.HasValue)
         {
-            levelString = state.VideoStream.Level.Value.ToString(CultureInfo.InvariantCulture) ?? string.Empty;
+            levelString = state.VideoStream.Level.Value.ToString(CultureInfo.InvariantCulture);
         }
         else
         {

+ 1 - 1
Jellyfin.Api/Helpers/StreamingHelpers.cs

@@ -210,7 +210,7 @@ public static class StreamingHelpers
                     && state.VideoRequest.VideoBitRate.Value >= state.VideoStream.BitRate.Value)
                 {
                     // Don't downscale the resolution if the width/height/MaxWidth/MaxHeight is not requested,
-                    // and the requested video bitrate is higher than source video bitrate.
+                    // and the requested video bitrate is greater than source video bitrate.
                     if (state.VideoStream.Width.HasValue || state.VideoStream.Height.HasValue)
                     {
                         state.VideoRequest.MaxWidth = state.VideoStream?.Width;

+ 1 - 1
Jellyfin.Api/Models/MediaInfoDtos/OpenLiveStreamDto.cs

@@ -61,7 +61,7 @@ public class OpenLiveStreamDto
     public bool? EnableDirectPlay { get; set; }
 
     /// <summary>
-    /// Gets or sets a value indicating whether to enale direct stream.
+    /// Gets or sets a value indicating whether to enable direct stream.
     /// </summary>
     public bool? EnableDirectStream { get; set; }
 

+ 1 - 1
Jellyfin.Api/Models/MediaInfoDtos/PlaybackInfoDto.cs

@@ -4,7 +4,7 @@ using MediaBrowser.Model.Dlna;
 namespace Jellyfin.Api.Models.MediaInfoDtos;
 
 /// <summary>
-/// Plabyback info dto.
+/// Playback info dto.
 /// </summary>
 public class PlaybackInfoDto
 {

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/AncestorId.cs

@@ -3,7 +3,7 @@ using System;
 namespace Jellyfin.Data.Entities;
 
 /// <summary>
-/// Represents the relational informations for an <see cref="BaseItemEntity"/>.
+/// Represents the relational information for an <see cref="BaseItemEntity"/>.
 /// </summary>
 public class AncestorId
 {

+ 2 - 2
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/AttachmentStreamInfo.cs

@@ -3,7 +3,7 @@ using System;
 namespace Jellyfin.Data.Entities;
 
 /// <summary>
-/// Provides informations about an Attachment to an <see cref="BaseItemEntity"/>.
+/// Provides information about an Attachment to an <see cref="BaseItemEntity"/>.
 /// </summary>
 public class AttachmentStreamInfo
 {
@@ -18,7 +18,7 @@ public class AttachmentStreamInfo
     public required BaseItemEntity Item { get; set; }
 
     /// <summary>
-    /// Gets or Sets The index within the source file.
+    /// Gets or Sets the index within the source file.
     /// </summary>
     public required int Index { get; set; }
 

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/BaseItemMetadataField.cs

@@ -8,7 +8,7 @@ namespace Jellyfin.Data.Entities;
 public class BaseItemMetadataField
 {
     /// <summary>
-    /// Gets or Sets Numerical ID of this enumeratable.
+    /// Gets or Sets Numerical ID of this enumerable.
     /// </summary>
     public required int Id { get; set; }
 

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/BaseItemTrailerType.cs

@@ -8,7 +8,7 @@ namespace Jellyfin.Data.Entities;
 public class BaseItemTrailerType
 {
     /// <summary>
-    /// Gets or Sets Numerical ID of this enumeratable.
+    /// Gets or Sets Numerical ID of this enumerable.
     /// </summary>
     public required int Id { get; set; }
 

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/ItemValue.cs

@@ -24,7 +24,7 @@ public class ItemValue
     public required string Value { get; set; }
 
     /// <summary>
-    /// Gets or Sets the sanatised Value.
+    /// Gets or Sets the sanitized Value.
     /// </summary>
     public required string CleanValue { get; set; }
 

+ 2 - 2
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/Libraries/CollectionItem.cs

@@ -43,7 +43,7 @@ namespace Jellyfin.Data.Entities.Libraries
         /// Gets or sets the next item in the collection.
         /// </summary>
         /// <remarks>
-        /// TODO check if this properly updated Dependant and has the proper principal relationship.
+        /// TODO check if this properly updated Dependent and has the proper principal relationship.
         /// </remarks>
         public virtual CollectionItem? Next { get; set; }
 
@@ -51,7 +51,7 @@ namespace Jellyfin.Data.Entities.Libraries
         /// Gets or sets the previous item in the collection.
         /// </summary>
         /// <remarks>
-        /// TODO check if this properly updated Dependant and has the proper principal relationship.
+        /// TODO check if this properly updated Dependent and has the proper principal relationship.
         /// </remarks>
         public virtual CollectionItem? Previous { get; set; }
 

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/Libraries/Series.cs

@@ -4,7 +4,7 @@ using System.Collections.Generic;
 namespace Jellyfin.Data.Entities.Libraries
 {
     /// <summary>
-    /// An entity representing a a series.
+    /// An entity representing a series.
     /// </summary>
     public class Series : LibraryItem
     {

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/PeopleBaseItemMap.cs

@@ -18,7 +18,7 @@ public class PeopleBaseItemMap
     public int? ListOrder { get; set; }
 
     /// <summary>
-    /// Gets or Sets the Role name the assosiated actor played in the <see cref="BaseItemEntity"/>.
+    /// Gets or Sets the Role name the associated actor played in the <see cref="BaseItemEntity"/>.
     /// </summary>
     public string? Role { get; set; }
 

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/ProgramAudioEntity.cs

@@ -11,7 +11,7 @@ public enum ProgramAudioEntity
     Mono = 0,
 
     /// <summary>
-    /// Sterio.
+    /// Stereo.
     /// </summary>
     Stereo = 1,
 

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/Entities/TrickplayInfo.cs

@@ -66,7 +66,7 @@ public class TrickplayInfo
     public int Interval { get; set; }
 
     /// <summary>
-    /// Gets or sets peak bandwith usage in bits per second.
+    /// Gets or sets peak bandwidth usage in bits per second.
     /// </summary>
     /// <remarks>
     /// Required.

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Implementations/JellyfinDbContext.cs

@@ -269,7 +269,7 @@ public class JellyfinDbContext(DbContextOptions<JellyfinDbContext> options, ILog
         jellyfinDatabaseProvider.OnModelCreating(modelBuilder);
         base.OnModelCreating(modelBuilder);
 
-        // Configuration for each entity is in it's own class inside 'ModelConfiguration'.
+        // Configuration for each entity is in its own class inside 'ModelConfiguration'.
         modelBuilder.ApplyConfigurationsFromAssembly(typeof(JellyfinDbContext).Assembly);
     }
 }

+ 9 - 9
Jellyfin.Server.Implementations/Item/BaseItemRepository.cs

@@ -231,7 +231,7 @@ public sealed class BaseItemRepository
         }
 
         dbQuery = ApplyGroupingFilter(dbQuery, filter);
-        dbQuery = ApplyQueryPageing(dbQuery, filter);
+        dbQuery = ApplyQueryPaging(dbQuery, filter);
 
         result.Items = dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserialiseBaseItem(w, filter.SkipDeserialization)).ToArray();
         result.StartIndex = filter.StartIndex ?? 0;
@@ -250,7 +250,7 @@ public sealed class BaseItemRepository
         dbQuery = TranslateQuery(dbQuery, context, filter);
 
         dbQuery = ApplyGroupingFilter(dbQuery, filter);
-        dbQuery = ApplyQueryPageing(dbQuery, filter);
+        dbQuery = ApplyQueryPaging(dbQuery, filter);
 
         return dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserialiseBaseItem(w, filter.SkipDeserialization)).ToArray();
     }
@@ -258,7 +258,7 @@ public sealed class BaseItemRepository
     private IQueryable<BaseItemEntity> ApplyGroupingFilter(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
     {
         // This whole block is needed to filter duplicate entries on request
-        // for the time beeing it cannot be used because it would destroy the ordering
+        // for the time being it cannot be used because it would destroy the ordering
         // this results in "duplicate" responses for queries that try to lookup individual series or multiple versions but
         // for that case the invoker has to run a DistinctBy(e => e.PresentationUniqueKey) on their own
 
@@ -289,7 +289,7 @@ public sealed class BaseItemRepository
         return dbQuery;
     }
 
-    private IQueryable<BaseItemEntity> ApplyQueryPageing(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
+    private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
     {
         if (filter.Limit.HasValue || filter.StartIndex.HasValue)
         {
@@ -314,7 +314,7 @@ public sealed class BaseItemRepository
         dbQuery = TranslateQuery(dbQuery, context, filter);
         dbQuery = ApplyOrder(dbQuery, filter);
         dbQuery = ApplyGroupingFilter(dbQuery, filter);
-        dbQuery = ApplyQueryPageing(dbQuery, filter);
+        dbQuery = ApplyQueryPaging(dbQuery, filter);
         return dbQuery;
     }
 
@@ -357,7 +357,7 @@ public sealed class BaseItemRepository
     {
         ArgumentException.ThrowIfNullOrEmpty(typeName);
 
-        // TODO: this isn't great. Refactor later to be both globally handled by a dedicated service not just an static variable and be loaded eagar.
+        // TODO: this isn't great. Refactor later to be both globally handled by a dedicated service not just an static variable and be loaded eagerly.
         // currently this is done so that plugins may introduce their own type of baseitems as we dont know when we are first called, before or after plugins are loaded
         return _typeMap.GetOrAdd(typeName, k => AppDomain.CurrentDomain.GetAssemblies()
             .Select(a => a.GetType(k))
@@ -889,7 +889,7 @@ public sealed class BaseItemRepository
     /// <exception cref="InvalidOperationException">Will be thrown if an invalid serialisation is requested.</exception>
     public static BaseItemDto DeserialiseBaseItem(BaseItemEntity baseItemEntity, ILogger logger, IServerApplicationHost? appHost, bool skipDeserialization = false)
     {
-        var type = GetType(baseItemEntity.Type) ?? throw new InvalidOperationException("Cannot deserialise unkown type.");
+        var type = GetType(baseItemEntity.Type) ?? throw new InvalidOperationException("Cannot deserialise unknown type.");
         BaseItemDto? dto = null;
         if (TypeRequiresDeserialization(type) && baseItemEntity.Data is not null && !skipDeserialization)
         {
@@ -905,7 +905,7 @@ public sealed class BaseItemRepository
 
         if (dto is null)
         {
-            dto = Activator.CreateInstance(type) as BaseItemDto ?? throw new InvalidOperationException("Cannot deserialise unkown type.");
+            dto = Activator.CreateInstance(type) as BaseItemDto ?? throw new InvalidOperationException("Cannot deserialise unknown type.");
         }
 
         return Map(baseItemEntity, dto, appHost);
@@ -2065,7 +2065,7 @@ public sealed class BaseItemRepository
         if (filter.IncludeInheritedTags.Length > 0)
         {
             // Episodes do not store inherit tags from their parents in the database, and the tag may be still required by the client.
-            // In addtion to the tags for the episodes themselves, we need to manually query its parent (the season)'s tags as well.
+            // In addition to the tags for the episodes themselves, we need to manually query its parent (the season)'s tags as well.
             if (includeTypes.Length == 1 && includeTypes.FirstOrDefault() is BaseItemKind.Episode)
             {
                 baseQuery = baseQuery

+ 1 - 1
Jellyfin.Server.Implementations/MediaSegments/MediaSegmentManager.cs

@@ -22,7 +22,7 @@ using Microsoft.Extensions.Logging;
 namespace Jellyfin.Server.Implementations.MediaSegments;
 
 /// <summary>
-/// Manages media segments retrival and storage.
+/// Manages media segments retrieval and storage.
 /// </summary>
 public class MediaSegmentManager : IMediaSegmentManager
 {

+ 1 - 1
Jellyfin.Server.Implementations/Trickplay/TrickplayManager.cs

@@ -46,7 +46,7 @@ public class TrickplayManager : ITrickplayManager
     /// </summary>
     /// <param name="logger">The logger.</param>
     /// <param name="mediaEncoder">The media encoder.</param>
-    /// <param name="fileSystem">The file systen.</param>
+    /// <param name="fileSystem">The file system.</param>
     /// <param name="encodingHelper">The encoding helper.</param>
     /// <param name="libraryManager">The library manager.</param>
     /// <param name="config">The server configuration manager.</param>

+ 9 - 7
Jellyfin.Server/Infrastructure/SymlinkFollowingPhysicalFileResultExecutor.cs

@@ -67,38 +67,40 @@ namespace Jellyfin.Server.Infrastructure
         }
 
         /// <inheritdoc />
-        protected override Task WriteFileAsync(ActionContext context, PhysicalFileResult result, RangeItemHeaderValue? range, long rangeLength)
+        protected override async Task WriteFileAsync(ActionContext context, PhysicalFileResult result, RangeItemHeaderValue? range, long rangeLength)
         {
             ArgumentNullException.ThrowIfNull(context);
             ArgumentNullException.ThrowIfNull(result);
 
             if (range is not null && rangeLength == 0)
             {
-                return Task.CompletedTask;
+                return;
             }
 
             // It's a bit of wasted IO to perform this check again, but non-symlinks shouldn't use this code
             if (!IsSymLink(result.FileName))
             {
-                return base.WriteFileAsync(context, result, range, rangeLength);
+                await base.WriteFileAsync(context, result, range, rangeLength).ConfigureAwait(false);
+                return;
             }
 
             var response = context.HttpContext.Response;
 
             if (range is not null)
             {
-                return SendFileAsync(
+                await SendFileAsync(
                     result.FileName,
                     response,
                     offset: range.From ?? 0L,
-                    count: rangeLength);
+                    count: rangeLength).ConfigureAwait(false);
+                return;
             }
 
-            return SendFileAsync(
+            await SendFileAsync(
                 result.FileName,
                 response,
                 offset: 0,
-                count: null);
+                count: null).ConfigureAwait(false);
         }
 
         private async Task SendFileAsync(string filePath, HttpResponse response, long offset, long? count, CancellationToken cancellationToken = default)

+ 1 - 1
Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs

@@ -46,7 +46,7 @@ namespace Jellyfin.Server.Migrations.Routines
         public Guid Id => Guid.Parse("{EF103419-8451-40D8-9F34-D1A8E93A1679}");
 
         /// <inheritdoc/>
-        public string Name => "CreateLoggingConfigHeirarchy";
+        public string Name => "CreateLoggingConfigHierarchy";
 
         /// <inheritdoc/>
         public bool PerformOnNewInstall => false;

+ 1 - 1
MediaBrowser.Common/Configuration/IConfigurationManager.cs

@@ -61,7 +61,7 @@ namespace MediaBrowser.Common.Configuration
         object GetConfiguration(string key);
 
         /// <summary>
-        /// Gets the array of coniguration stores.
+        /// Gets the array of configuration stores.
         /// </summary>
         /// <returns>Array of ConfigurationStore.</returns>
         ConfigurationStore[] GetConfigurationStores();

+ 2 - 1
MediaBrowser.Common/Net/NetworkUtils.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
 using System.Net;
 using System.Net.Sockets;
 using System.Text.RegularExpressions;
@@ -102,7 +103,7 @@ public static partial class NetworkUtils
         Span<byte> bytes = stackalloc byte[mask.AddressFamily == AddressFamily.InterNetwork ? NetworkConstants.IPv4MaskBytes : NetworkConstants.IPv6MaskBytes];
         if (!mask.TryWriteBytes(bytes, out var bytesWritten))
         {
-            Console.WriteLine("Unable to write address bytes, only ${bytesWritten} bytes written.");
+            Console.WriteLine("Unable to write address bytes, only {0} bytes written.", bytesWritten.ToString(CultureInfo.InvariantCulture));
         }
 
         var zeroed = false;

+ 2 - 2
MediaBrowser.Controller/Devices/IDeviceManager.cs

@@ -58,7 +58,7 @@ public interface IDeviceManager
     QueryResult<Device> GetDevices(DeviceQuery query);
 
     /// <summary>
-    /// Gets device infromation based on the provided query.
+    /// Gets device information based on the provided query.
     /// </summary>
     /// <param name="query">The device query.</param>
     /// <returns>A <see cref="Task{QueryResult}"/> representing the retrieval of the device information.</returns>
@@ -109,7 +109,7 @@ public interface IDeviceManager
     DeviceOptionsDto? GetDeviceOptions(string deviceId);
 
     /// <summary>
-    /// Gets the dto for client capabilites.
+    /// Gets the dto for client capabilities.
     /// </summary>
     /// <param name="capabilities">The client capabilities.</param>
     /// <returns><see cref="ClientCapabilitiesDto"/> of the device.</returns>

+ 1 - 1
MediaBrowser.Controller/Entities/Audio/IHasAlbumArtist.cs

@@ -22,7 +22,7 @@ namespace MediaBrowser.Controller.Entities.Audio
         IReadOnlyList<string> Artists { get; set; }
     }
 
-    public static class Extentions
+    public static class Extensions
     {
         public static IEnumerable<string> GetAllArtists<T>(this T item)
             where T : IHasArtist, IHasAlbumArtist

+ 3 - 3
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -112,15 +112,15 @@ namespace MediaBrowser.Controller.Entities.Audio
             return base.IsSaveLocalMetadataEnabled();
         }
 
-        protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
+        protected override async Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMetadata, bool allowRemoveRoot, MetadataRefreshOptions refreshOptions, IDirectoryService directoryService, CancellationToken cancellationToken)
         {
             if (IsAccessedByName)
             {
                 // Should never get in here anyway
-                return Task.CompletedTask;
+                return;
             }
 
-            return base.ValidateChildrenInternal(progress, recursive, refreshChildMetadata, false, refreshOptions, directoryService, cancellationToken);
+            await base.ValidateChildrenInternal(progress, recursive, refreshChildMetadata, false, refreshOptions, directoryService, cancellationToken).ConfigureAwait(false);
         }
 
         public override List<string> GetUserDataKeys()

+ 10 - 12
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -1800,7 +1800,7 @@ namespace MediaBrowser.Controller.Entities
         /// Adds a genre to the item.
         /// </summary>
         /// <param name="name">The name.</param>
-        /// <exception cref="ArgumentNullException">Throwns if name is null.</exception>
+        /// <exception cref="ArgumentNullException">Throws if name is null.</exception>
         public void AddGenre(string name)
         {
             ArgumentException.ThrowIfNullOrEmpty(name);
@@ -1985,8 +1985,8 @@ namespace MediaBrowser.Controller.Entities
             ImageInfos = [.. ImageInfos, image];
         }
 
-        public virtual Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
-         => LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken);
+        public virtual async Task UpdateToRepositoryAsync(ItemUpdateType updateReason, CancellationToken cancellationToken)
+         => await LibraryManager.UpdateItemAsync(this, GetParent(), updateReason, cancellationToken).ConfigureAwait(false);
 
         /// <summary>
         /// Validates that images within the item are still on the filesystem.
@@ -2375,7 +2375,7 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
-        protected Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
+        protected async Task RefreshMetadataForOwnedItem(BaseItem ownedItem, bool copyTitleMetadata, MetadataRefreshOptions options, CancellationToken cancellationToken)
         {
             var newOptions = new MetadataRefreshOptions(options)
             {
@@ -2436,10 +2436,10 @@ namespace MediaBrowser.Controller.Entities
                 }
             }
 
-            return ownedItem.RefreshMetadata(newOptions, cancellationToken);
+            await ownedItem.RefreshMetadata(newOptions, cancellationToken).ConfigureAwait(false);
         }
 
-        protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
+        protected async Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken)
         {
             var newOptions = new MetadataRefreshOptions(options)
             {
@@ -2449,9 +2449,7 @@ namespace MediaBrowser.Controller.Entities
             var id = LibraryManager.GetNewItemId(path, typeof(Video));
 
             // Try to retrieve it from the db. If we don't find it, use the resolved version
-            var video = LibraryManager.GetItemById(id) as Video;
-
-            if (video is null)
+            if (LibraryManager.GetItemById(id) is not Video video)
             {
                 video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video;
 
@@ -2460,15 +2458,15 @@ namespace MediaBrowser.Controller.Entities
 
             if (video is null)
             {
-                return Task.FromResult(true);
+                return;
             }
 
             if (video.OwnerId.IsEmpty())
             {
-                video.OwnerId = this.Id;
+                video.OwnerId = Id;
             }
 
-            return RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken);
+            await RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken).ConfigureAwait(false);
         }
 
         public string GetEtag(User user)

+ 6 - 11
MediaBrowser.Controller/Entities/Folder.cs

@@ -531,13 +531,13 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
-        private Task RefreshMetadataRecursive(IList<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
+        private async Task RefreshMetadataRecursive(IList<BaseItem> children, MetadataRefreshOptions refreshOptions, bool recursive, IProgress<double> progress, CancellationToken cancellationToken)
         {
-            return RunTasks(
+            await RunTasks(
                 (baseItem, innerProgress) => RefreshChildMetadata(baseItem, refreshOptions, recursive && baseItem.IsFolder, innerProgress, cancellationToken),
                 children,
                 progress,
-                cancellationToken);
+                cancellationToken).ConfigureAwait(false);
         }
 
         private async Task RefreshAllMetadataForContainer(IMetadataContainer container, MetadataRefreshOptions refreshOptions, IProgress<double> progress, CancellationToken cancellationToken)
@@ -578,13 +578,13 @@ namespace MediaBrowser.Controller.Entities
         /// <param name="progress">The progress.</param>
         /// <param name="cancellationToken">The cancellation token.</param>
         /// <returns>Task.</returns>
-        private Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
+        private async Task ValidateSubFolders(IList<Folder> children, IDirectoryService directoryService, IProgress<double> progress, CancellationToken cancellationToken)
         {
-            return RunTasks(
+            await RunTasks(
                 (folder, innerProgress) => folder.ValidateChildrenInternal(innerProgress, true, false, false, null, directoryService, cancellationToken),
                 children,
                 progress,
-                cancellationToken);
+                cancellationToken).ConfigureAwait(false);
         }
 
         /// <summary>
@@ -1243,11 +1243,6 @@ namespace MediaBrowser.Controller.Entities
                 return false;
             }
 
-            if (request.GenreIds.Count > 0)
-            {
-                return false;
-            }
-
             if (request.VideoTypes.Length > 0)
             {
                 return false;

+ 1 - 1
MediaBrowser.Controller/Entities/TV/Season.cs

@@ -134,7 +134,7 @@ namespace MediaBrowser.Controller.Entities.TV
                 var series = Series;
                 if (series is not null)
                 {
-                    return series.PresentationUniqueKey + "-" + (IndexNumber ?? 0).ToString("000", CultureInfo.InvariantCulture);
+                    return series.PresentationUniqueKey + "-" + IndexNumber.Value.ToString("000", CultureInfo.InvariantCulture);
                 }
             }
 

+ 1 - 1
MediaBrowser.Controller/Library/IMediaSourceManager.cs

@@ -53,7 +53,7 @@ namespace MediaBrowser.Controller.Library
         IReadOnlyList<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query);
 
         /// <summary>
-        /// Gets the playack media sources.
+        /// Gets the playback media sources.
         /// </summary>
         /// <param name="item">Item to use.</param>
         /// <param name="user">User to use for operation.</param>

+ 38 - 38
MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs

@@ -61,7 +61,7 @@ namespace MediaBrowser.Controller.MediaEncoding
         private readonly Version _minFixedKernel60i915Hang = new Version(6, 0, 18);
         private readonly Version _minKernelVersionAmdVkFmtModifier = new Version(5, 15);
 
-        private readonly Version _minFFmpegImplictHwaccel = new Version(6, 0);
+        private readonly Version _minFFmpegImplicitHwaccel = new Version(6, 0);
         private readonly Version _minFFmpegHwaUnsafeOutput = new Version(6, 0);
         private readonly Version _minFFmpegOclCuTonemapMode = new Version(5, 1, 3);
         private readonly Version _minFFmpegSvtAv1Params = new Version(5, 1);
@@ -632,7 +632,7 @@ namespace MediaBrowser.Controller.MediaEncoding
         {
             if (string.IsNullOrWhiteSpace(container))
             {
-                // this may not work, but if the client is that broken we can not do anything better
+                // this may not work, but if the client is that broken we cannot do anything better
                 return "aac";
             }
 
@@ -2198,7 +2198,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 var videoFrameRate = videoStream.ReferenceFrameRate;
 
                 // Add a little tolerance to the framerate check because some videos might record a framerate
-                // that is slightly higher than the intended framerate, but the device can still play it correctly.
+                // that is slightly greater than the intended framerate, but the device can still play it correctly.
                 // 0.05 fps tolerance should be safe enough.
                 if (!videoFrameRate.HasValue || videoFrameRate.Value > requestedFramerate.Value + 0.05f)
                 {
@@ -3609,7 +3609,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 return GetSwVidFilterChain(state, options, vidEncoder);
             }
 
-            // prefered nvdec/cuvid + cuda filters + nvenc pipeline
+            // preferred nvdec/cuvid + cuda filters + nvenc pipeline
             return GetNvidiaVidFiltersPrefered(state, options, vidDecoder, vidEncoder);
         }
 
@@ -3650,8 +3650,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             var subH = state.SubtitleStream?.Height;
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doCuTranspose = !string.IsNullOrEmpty(tranposeDir) && _mediaEncoder.SupportsFilter("transpose_cuda");
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doCuTranspose = !string.IsNullOrEmpty(transposeDir) && _mediaEncoder.SupportsFilter("transpose_cuda");
             var swapWAndH = Math.Abs(rotation) == 90 && (isSwDecoder || (isNvDecoder && doCuTranspose));
             var swpInW = swapWAndH ? inH : inW;
             var swpInH = swapWAndH ? inW : inH;
@@ -3697,7 +3697,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 // hw transpose
                 if (doCuTranspose)
                 {
-                    mainFilters.Add($"transpose_cuda=dir={tranposeDir}");
+                    mainFilters.Add($"transpose_cuda=dir={transposeDir}");
                 }
 
                 var isRext = IsVideoStreamHevcRext(state);
@@ -3817,7 +3817,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 return GetSwVidFilterChain(state, options, vidEncoder);
             }
 
-            // prefered d3d11va + opencl filters + amf pipeline
+            // preferred d3d11va + opencl filters + amf pipeline
             return GetAmdDx11VidFiltersPrefered(state, options, vidDecoder, vidEncoder);
         }
 
@@ -3857,8 +3857,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             var subH = state.SubtitleStream?.Height;
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doOclTranspose = !string.IsNullOrEmpty(tranposeDir)
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doOclTranspose = !string.IsNullOrEmpty(transposeDir)
                 && _mediaEncoder.SupportsFilterWithOption(FilterOptionType.TransposeOpenclReversal);
             var swapWAndH = Math.Abs(rotation) == 90 && (isSwDecoder || (isD3d11vaDecoder && doOclTranspose));
             var swpInW = swapWAndH ? inH : inW;
@@ -3902,12 +3902,12 @@ namespace MediaBrowser.Controller.MediaEncoding
                 // map from d3d11va to opencl via d3d11-opencl interop.
                 mainFilters.Add("hwmap=derive_device=opencl:mode=read");
 
-                // hw deint <= TODO: finsh the 'yadif_opencl' filter
+                // hw deint <= TODO: finish the 'yadif_opencl' filter
 
                 // hw transpose
                 if (doOclTranspose)
                 {
-                    mainFilters.Add($"transpose_opencl=dir={tranposeDir}");
+                    mainFilters.Add($"transpose_opencl=dir={transposeDir}");
                 }
 
                 var outFormat = doOclTonemap ? string.Empty : "nv12";
@@ -4043,13 +4043,13 @@ namespace MediaBrowser.Controller.MediaEncoding
                 return GetSwVidFilterChain(state, options, vidEncoder);
             }
 
-            // prefered qsv(vaapi) + opencl filters pipeline
+            // preferred qsv(vaapi) + opencl filters pipeline
             if (isIntelVaapiOclSupported)
             {
                 return GetIntelQsvVaapiVidFiltersPrefered(state, options, vidDecoder, vidEncoder);
             }
 
-            // prefered qsv(d3d11) + opencl filters pipeline
+            // preferred qsv(d3d11) + opencl filters pipeline
             if (isIntelDx11OclSupported)
             {
                 return GetIntelQsvDx11VidFiltersPrefered(state, options, vidDecoder, vidEncoder);
@@ -4098,8 +4098,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             var subH = state.SubtitleStream?.Height;
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doVppTranspose = !string.IsNullOrEmpty(tranposeDir);
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doVppTranspose = !string.IsNullOrEmpty(transposeDir);
             var swapWAndH = Math.Abs(rotation) == 90 && (isSwDecoder || ((isD3d11vaDecoder || isQsvDecoder) && doVppTranspose));
             var swpInW = swapWAndH ? inH : inW;
             var swpInH = swapWAndH ? inW : inH;
@@ -4192,7 +4192,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
                 if (!string.IsNullOrEmpty(hwScaleFilter) && doVppTranspose)
                 {
-                    hwScaleFilter += $":transpose={tranposeDir}";
+                    hwScaleFilter += $":transpose={transposeDir}";
                 }
 
                 if (!string.IsNullOrEmpty(hwScaleFilter) && isMjpegEncoder)
@@ -4385,8 +4385,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             var subH = state.SubtitleStream?.Height;
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doVppTranspose = !string.IsNullOrEmpty(tranposeDir);
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doVppTranspose = !string.IsNullOrEmpty(transposeDir);
             var swapWAndH = Math.Abs(rotation) == 90 && (isSwDecoder || ((isVaapiDecoder || isQsvDecoder) && doVppTranspose));
             var swpInW = swapWAndH ? inH : inW;
             var swpInH = swapWAndH ? inW : inH;
@@ -4446,7 +4446,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 // hw transpose(vaapi vpp)
                 if (isVaapiDecoder && doVppTranspose)
                 {
-                    mainFilters.Add($"transpose_vaapi=dir={tranposeDir}");
+                    mainFilters.Add($"transpose_vaapi=dir={transposeDir}");
                 }
 
                 var outFormat = doTonemap ? (((isQsvDecoder && doVppTranspose) || isRext) ? "p010" : string.Empty) : "nv12";
@@ -4456,7 +4456,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
                 if (!string.IsNullOrEmpty(hwScaleFilter) && isQsvDecoder && doVppTranspose)
                 {
-                    hwScaleFilter += $":transpose={tranposeDir}";
+                    hwScaleFilter += $":transpose={transposeDir}";
                 }
 
                 if (!string.IsNullOrEmpty(hwScaleFilter) && isMjpegEncoder)
@@ -4657,14 +4657,14 @@ namespace MediaBrowser.Controller.MediaEncoding
                 return swFilterChain;
             }
 
-            // prefered vaapi + opencl filters pipeline
+            // preferred vaapi + opencl filters pipeline
             if (_mediaEncoder.IsVaapiDeviceInteliHD)
             {
                 // Intel iHD path, with extra vpp tonemap and overlay support.
                 return GetIntelVaapiFullVidFiltersPrefered(state, options, vidDecoder, vidEncoder);
             }
 
-            // prefered vaapi + vulkan filters pipeline
+            // preferred vaapi + vulkan filters pipeline
             if (_mediaEncoder.IsVaapiDeviceAmd
                 && isVaapiVkSupported
                 && _mediaEncoder.IsVaapiDeviceSupportVulkanDrmInterop
@@ -4716,8 +4716,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             var subH = state.SubtitleStream?.Height;
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doVaVppTranspose = !string.IsNullOrEmpty(tranposeDir);
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doVaVppTranspose = !string.IsNullOrEmpty(transposeDir);
             var swapWAndH = Math.Abs(rotation) == 90 && (isSwDecoder || (isVaapiDecoder && doVaVppTranspose));
             var swpInW = swapWAndH ? inH : inW;
             var swpInH = swapWAndH ? inW : inH;
@@ -4772,7 +4772,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 // hw transpose
                 if (doVaVppTranspose)
                 {
-                    mainFilters.Add($"transpose_vaapi=dir={tranposeDir}");
+                    mainFilters.Add($"transpose_vaapi=dir={transposeDir}");
                 }
 
                 var outFormat = doTonemap ? (isRext ? "p010" : string.Empty) : "nv12";
@@ -4949,8 +4949,8 @@ namespace MediaBrowser.Controller.MediaEncoding
                     || string.Equals(state.SubtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase));
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doVkTranspose = isVaapiDecoder && !string.IsNullOrEmpty(tranposeDir);
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doVkTranspose = isVaapiDecoder && !string.IsNullOrEmpty(transposeDir);
             var swapWAndH = Math.Abs(rotation) == 90 && (isSwDecoder || (isVaapiDecoder && doVkTranspose));
             var swpInW = swapWAndH ? inH : inW;
             var swpInH = swapWAndH ? inW : inH;
@@ -5043,13 +5043,13 @@ namespace MediaBrowser.Controller.MediaEncoding
             // vk transpose
             if (doVkTranspose)
             {
-                if (string.Equals(tranposeDir, "reversal", StringComparison.OrdinalIgnoreCase))
+                if (string.Equals(transposeDir, "reversal", StringComparison.OrdinalIgnoreCase))
                 {
                     mainFilters.Add("flip_vulkan");
                 }
                 else
                 {
-                    mainFilters.Add($"transpose_vulkan=dir={tranposeDir}");
+                    mainFilters.Add($"transpose_vulkan=dir={transposeDir}");
                 }
             }
 
@@ -5417,8 +5417,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             var usingHwSurface = isVtDecoder && (_mediaEncoder.EncoderVersion >= _minFFmpegWorkingVtHwSurface);
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doVtTranspose = !string.IsNullOrEmpty(tranposeDir) && _mediaEncoder.SupportsFilter("transpose_vt");
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doVtTranspose = !string.IsNullOrEmpty(transposeDir) && _mediaEncoder.SupportsFilter("transpose_vt");
             var swapWAndH = Math.Abs(rotation) == 90 && doVtTranspose;
             var swpInW = swapWAndH ? inH : inW;
             var swpInH = swapWAndH ? inW : inH;
@@ -5462,7 +5462,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             // hw transpose
             if (doVtTranspose)
             {
-                mainFilters.Add($"transpose_vt=dir={tranposeDir}");
+                mainFilters.Add($"transpose_vt=dir={transposeDir}");
             }
 
             if (doVtTonemap)
@@ -5577,7 +5577,7 @@ namespace MediaBrowser.Controller.MediaEncoding
                 return GetSwVidFilterChain(state, options, vidEncoder);
             }
 
-            // prefered rkmpp + rkrga + opencl filters pipeline
+            // preferred rkmpp + rkrga + opencl filters pipeline
             if (isRkmppOclSupported)
             {
                 return GetRkmppVidFiltersPrefered(state, options, vidDecoder, vidEncoder);
@@ -5625,8 +5625,8 @@ namespace MediaBrowser.Controller.MediaEncoding
             var subH = state.SubtitleStream?.Height;
 
             var rotation = state.VideoStream?.Rotation ?? 0;
-            var tranposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
-            var doRkVppTranspose = !string.IsNullOrEmpty(tranposeDir);
+            var transposeDir = rotation == 0 ? string.Empty : GetVideoTransposeDirection(state);
+            var doRkVppTranspose = !string.IsNullOrEmpty(transposeDir);
             var swapWAndH = Math.Abs(rotation) == 90 && (isSwDecoder || (isRkmppDecoder && doRkVppTranspose));
             var swpInW = swapWAndH ? inH : inW;
             var swpInH = swapWAndH ? inW : inH;
@@ -5697,7 +5697,7 @@ namespace MediaBrowser.Controller.MediaEncoding
 
                     if (!string.IsNullOrEmpty(hwScaleFilter) && doRkVppTranspose)
                     {
-                        hwScaleFilter += $":transpose={tranposeDir}";
+                        hwScaleFilter += $":transpose={transposeDir}";
                     }
 
                     // try enabling AFBC to save DDR bandwidth
@@ -6171,7 +6171,7 @@ namespace MediaBrowser.Controller.MediaEncoding
             var ffmpegVersion = _mediaEncoder.EncoderVersion;
 
             // Set the av1 codec explicitly to trigger hw accelerator, otherwise libdav1d will be used.
-            var isAv1 = ffmpegVersion < _minFFmpegImplictHwaccel
+            var isAv1 = ffmpegVersion < _minFFmpegImplicitHwaccel
                 && string.Equals(videoCodec, "av1", StringComparison.OrdinalIgnoreCase);
 
             // Allow profile mismatch if decoding H.264 baseline with d3d11va and vaapi hwaccels.

+ 6 - 6
MediaBrowser.Controller/MediaSegements/IMediaSegmentManager.cs → MediaBrowser.Controller/MediaSegments/IMediaSegmentManager.cs

@@ -46,20 +46,20 @@ public interface IMediaSegmentManager
     Task DeleteSegmentAsync(Guid segmentId);
 
     /// <summary>
-    /// Obtains all segments accociated with the itemId.
+    /// Obtains all segments associated with the itemId.
     /// </summary>
     /// <param name="itemId">The id of the <see cref="BaseItem"/>.</param>
-    /// <param name="typeFilter">filteres all media segments of the given type to be included. If null all types are included.</param>
-    /// <param name="filterByProvider">When set filteres the segments to only return those that which providers are currently enabled on their library.</param>
+    /// <param name="typeFilter">filters all media segments of the given type to be included. If null all types are included.</param>
+    /// <param name="filterByProvider">When set filters the segments to only return those that which providers are currently enabled on their library.</param>
     /// <returns>An enumerator of <see cref="MediaSegmentDto"/>'s.</returns>
     Task<IEnumerable<MediaSegmentDto>> GetSegmentsAsync(Guid itemId, IEnumerable<MediaSegmentType>? typeFilter, bool filterByProvider = true);
 
     /// <summary>
-    /// Obtains all segments accociated with the itemId.
+    /// Obtains all segments associated with the itemId.
     /// </summary>
     /// <param name="item">The <see cref="BaseItem"/>.</param>
-    /// <param name="typeFilter">filteres all media segments of the given type to be included. If null all types are included.</param>
-    /// <param name="filterByProvider">When set filteres the segments to only return those that which providers are currently enabled on their library.</param>
+    /// <param name="typeFilter">filters all media segments of the given type to be included. If null all types are included.</param>
+    /// <param name="filterByProvider">When set filters the segments to only return those that which providers are currently enabled on their library.</param>
     /// <returns>An enumerator of <see cref="MediaSegmentDto"/>'s.</returns>
     Task<IEnumerable<MediaSegmentDto>> GetSegmentsAsync(BaseItem item, IEnumerable<MediaSegmentType>? typeFilter, bool filterByProvider = true);
 

+ 0 - 0
MediaBrowser.Controller/MediaSegements/IMediaSegmentProvider.cs → MediaBrowser.Controller/MediaSegments/IMediaSegmentProvider.cs


+ 2 - 2
MediaBrowser.Controller/Net/IWebSocketConnection.cs

@@ -24,9 +24,9 @@ namespace MediaBrowser.Controller.Net
         DateTime LastActivityDate { get; }
 
         /// <summary>
-        /// Gets or sets the date of last Keeplive received.
+        /// Gets or sets the date of last Keepalive received.
         /// </summary>
-        /// <value>The date of last Keeplive received.</value>
+        /// <value>The date of last Keepalive received.</value>
         DateTime LastKeepAliveDate { get; set; }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Controller/Session/ISessionManager.cs

@@ -324,7 +324,7 @@ namespace MediaBrowser.Controller.Session
         Task<SessionInfo> GetSessionByAuthenticationToken(Device info, string deviceId, string remoteEndpoint, string appVersion);
 
         /// <summary>
-        /// Logouts the specified access token.
+        /// Logs out the specified access token.
         /// </summary>
         /// <param name="accessToken">The access token.</param>
         /// <returns>A <see cref="Task"/> representing the log out process.</returns>

+ 1 - 1
MediaBrowser.Controller/Session/SessionInfo.cs

@@ -286,7 +286,7 @@ namespace MediaBrowser.Controller.Session
         /// <summary>
         /// Gets or sets the playlist item id.
         /// </summary>
-        /// <value>The splaylist item id.</value>
+        /// <value>The playlist item id.</value>
         public string PlaylistItemId { get; set; }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Controller/Sorting/IUserBaseItemComparer.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Controller.Library;
 namespace MediaBrowser.Controller.Sorting
 {
     /// <summary>
-    /// Represents a BaseItem comparer that requires a User to perform it's comparison.
+    /// Represents a BaseItem comparer that requires a User to perform its comparison.
     /// </summary>
     public interface IUserBaseItemComparer : IBaseItemComparer
     {

+ 1 - 1
MediaBrowser.Controller/Streaming/StreamState.cs

@@ -51,7 +51,7 @@ public class StreamState : EncodingJobInfo, IDisposable
     public VideoRequestDto? VideoRequest => Request as VideoRequestDto;
 
     /// <summary>
-    /// Gets or sets the direct stream provicer.
+    /// Gets or sets the direct stream provider.
     /// </summary>
     /// <remarks>
     /// Deprecated.

+ 1 - 1
MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs

@@ -320,7 +320,7 @@ namespace MediaBrowser.LocalMetadata.Images
                 {
                     AddImage(files, images, name + "-fanart", ImageType.Backdrop, imagePrefix);
 
-                    // Support without the prefix if it's in it's own folder
+                    // Support without the prefix if it's in its own folder
                     if (!isInMixedFolder)
                     {
                         AddImage(files, images, name + "-fanart", ImageType.Backdrop);

+ 1 - 1
MediaBrowser.LocalMetadata/Parsers/BoxSetXmlParser.cs

@@ -15,7 +15,7 @@ namespace MediaBrowser.LocalMetadata.Parsers
         /// <summary>
         /// Initializes a new instance of the <see cref="BoxSetXmlParser"/> class.
         /// </summary>
-        /// <param name="logger">Instance of the <see cref="ILogger{BoxSetXmlParset}"/> interface.</param>
+        /// <param name="logger">Instance of the <see cref="ILogger{BoxSetXmlParser}"/> interface.</param>
         /// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
         public BoxSetXmlParser(ILogger<BoxSetXmlParser> logger, IProviderManager providerManager)
             : base(logger, providerManager)

+ 1 - 1
MediaBrowser.LocalMetadata/Savers/BaseXmlSaver.cs

@@ -96,7 +96,7 @@ namespace MediaBrowser.LocalMetadata.Savers
             var directory = Path.GetDirectoryName(path) ?? throw new InvalidDataException($"Provided path ({path}) is not valid.");
             Directory.CreateDirectory(directory);
 
-            // On Windows, savint the file will fail if the file is hidden or readonly
+            // On Windows, saving the file will fail if the file is hidden or readonly
             FileSystem.SetAttributes(path, false, false);
 
             var fileStreamOptions = new FileStreamOptions()

+ 3 - 3
MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs

@@ -45,16 +45,16 @@ namespace MediaBrowser.LocalMetadata.Savers
         }
 
         /// <inheritdoc />
-        protected override Task WriteCustomElementsAsync(BaseItem item, XmlWriter writer)
+        protected override async Task WriteCustomElementsAsync(BaseItem item, XmlWriter writer)
         {
             var game = (Playlist)item;
 
             if (game.PlaylistMediaType == MediaType.Unknown)
             {
-                return Task.CompletedTask;
+                return;
             }
 
-            return writer.WriteElementStringAsync(null, "PlaylistMediaType", null, game.PlaylistMediaType.ToString());
+            await writer.WriteElementStringAsync(null, "PlaylistMediaType", null, game.PlaylistMediaType.ToString()).ConfigureAwait(false);
         }
 
         /// <inheritdoc />

+ 3 - 3
MediaBrowser.MediaEncoding/BdInfo/BdInfoDirectoryInfo.cs

@@ -84,7 +84,7 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
     /// Gets the files matching a pattern.
     /// </summary>
     /// <param name="searchPattern">The search pattern.</param>
-    /// <returns>All files of the directory matchign the search pattern.</returns>
+    /// <returns>All files of the directory matching the search pattern.</returns>
     public IFileInfo[] GetFiles(string searchPattern)
     {
         return _fileSystem.GetFiles(_impl.FullName, new[] { searchPattern }, false, false)
@@ -96,8 +96,8 @@ public class BdInfoDirectoryInfo : IDirectoryInfo
     /// Gets the files matching a pattern and search options.
     /// </summary>
     /// <param name="searchPattern">The search pattern.</param>
-    /// <param name="searchOption">The search optin.</param>
-    /// <returns>All files of the directory matchign the search pattern and options.</returns>
+    /// <param name="searchOption">The search option.</param>
+    /// <returns>All files of the directory matching the search pattern and options.</returns>
     public IFileInfo[] GetFiles(string searchPattern, SearchOption searchOption)
     {
         return _fileSystem.GetFiles(

+ 3 - 3
MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs

@@ -1101,14 +1101,14 @@ namespace MediaBrowser.MediaEncoding.Encoder
 
         private void StopProcesses()
         {
-            List<ProcessWrapper> proceses;
+            List<ProcessWrapper> processes;
             lock (_runningProcessesLock)
             {
-                proceses = _runningProcesses.ToList();
+                processes = _runningProcesses.ToList();
                 _runningProcesses.Clear();
             }
 
-            foreach (var process in proceses)
+            foreach (var process in processes)
             {
                 if (!process.HasExited)
                 {

+ 2 - 2
MediaBrowser.MediaEncoding/Probing/FFProbeHelpers.cs

@@ -24,7 +24,7 @@ namespace MediaBrowser.MediaEncoding.Probing
 
             if (result.Streams is not null)
             {
-                // Convert all dictionaries to case insensitive
+                // Convert all dictionaries to case-insensitive
                 foreach (var stream in result.Streams)
                 {
                     if (stream.Tags is not null)
@@ -70,7 +70,7 @@ namespace MediaBrowser.MediaEncoding.Probing
         }
 
         /// <summary>
-        /// Converts a dictionary to case insensitive.
+        /// Converts a dictionary to case-insensitive.
         /// </summary>
         /// <param name="dict">The dict.</param>
         /// <returns>Dictionary{System.StringSystem.String}.</returns>

+ 3 - 3
MediaBrowser.Model/Configuration/ServerConfiguration.cs

@@ -83,9 +83,9 @@ public class ServerConfiguration : BaseApplicationConfiguration
     public bool QuickConnectAvailable { get; set; } = true;
 
     /// <summary>
-    /// Gets or sets a value indicating whether [enable case sensitive item ids].
+    /// Gets or sets a value indicating whether [enable case-sensitive item ids].
     /// </summary>
-    /// <value><c>true</c> if [enable case sensitive item ids]; otherwise, <c>false</c>.</value>
+    /// <value><c>true</c> if [enable case-sensitive item ids]; otherwise, <c>false</c>.</value>
     public bool EnableCaseSensitiveItemIds { get; set; } = true;
 
     public bool DisableLiveTvChannelUserDataName { get; set; } = true;
@@ -249,7 +249,7 @@ public class ServerConfiguration : BaseApplicationConfiguration
     public bool AllowClientLogUpload { get; set; } = true;
 
     /// <summary>
-    /// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation alltogether.
+    /// Gets or sets the dummy chapter duration in seconds, use 0 (zero) or less to disable generation altogether.
     /// </summary>
     /// <value>The dummy chapters duration.</value>
     public int DummyChapterDuration { get; set; }

+ 2 - 2
MediaBrowser.Model/Dlna/ConditionProcessor.cs

@@ -25,8 +25,8 @@ namespace MediaBrowser.Model.Dlna
         /// <param name="videoFramerate">The framerate.</param>
         /// <param name="packetLength">The packet length.</param>
         /// <param name="timestamp">The <see cref="TransportStreamTimestamp"/>.</param>
-        /// <param name="isAnamorphic">A value indicating whether tthe video is anamorphic.</param>
-        /// <param name="isInterlaced">A value indicating whether tthe video is interlaced.</param>
+        /// <param name="isAnamorphic">A value indicating whether the video is anamorphic.</param>
+        /// <param name="isInterlaced">A value indicating whether the video is interlaced.</param>
         /// <param name="refFrames">The reference frames.</param>
         /// <param name="numVideoStreams">The number of video streams.</param>
         /// <param name="numAudioStreams">The number of audio streams.</param>

+ 1 - 1
MediaBrowser.Model/Dlna/DirectPlayProfile.cs

@@ -59,7 +59,7 @@ public class DirectPlayProfile
     /// <returns>True if supported.</returns>
     public bool SupportsAudioCodec(string? codec)
     {
-        // Video profiles can have audio codec restrictions too, therefore incude Video as valid type.
+        // Video profiles can have audio codec restrictions too, therefore include Video as valid type.
         return (Type == DlnaProfileType.Audio || Type == DlnaProfileType.Video) && ContainerHelper.ContainsContainer(AudioCodec, codec);
     }
 }

+ 4 - 4
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -1087,12 +1087,12 @@ namespace MediaBrowser.Model.Dlna
 
             _logger.LogDebug(
                 "Transcode Result for Profile: {Profile}, Path: {Path}, PlayMethod: {PlayMethod}, AudioStreamIndex: {AudioStreamIndex}, SubtitleStreamIndex: {SubtitleStreamIndex}, Reasons: {TranscodeReason}",
-                options.Profile?.Name ?? "Anonymous Profile",
+                options.Profile.Name ?? "Anonymous Profile",
                 item.Path ?? "Unknown path",
-                playlistItem?.PlayMethod,
+                playlistItem.PlayMethod,
                 audioStream?.Index,
-                playlistItem?.SubtitleStreamIndex,
-                playlistItem?.TranscodeReasons);
+                playlistItem.SubtitleStreamIndex,
+                playlistItem.TranscodeReasons);
         }
 
         private static int GetDefaultAudioBitrate(string? audioCodec, int? audioChannels)

+ 4 - 4
MediaBrowser.Model/Drawing/ImageFormatExtensions.cs

@@ -17,12 +17,12 @@ public static class ImageFormatExtensions
     public static string GetMimeType(this ImageFormat format)
         => format switch
         {
-            ImageFormat.Bmp => "image/bmp",
+            ImageFormat.Bmp => MediaTypeNames.Image.Bmp,
             ImageFormat.Gif => MediaTypeNames.Image.Gif,
             ImageFormat.Jpg => MediaTypeNames.Image.Jpeg,
-            ImageFormat.Png => "image/png",
-            ImageFormat.Webp => "image/webp",
-            ImageFormat.Svg => "image/svg+xml",
+            ImageFormat.Png => MediaTypeNames.Image.Png,
+            ImageFormat.Webp => MediaTypeNames.Image.Webp,
+            ImageFormat.Svg => MediaTypeNames.Image.Svg,
             _ => throw new InvalidEnumArgumentException(nameof(format), (int)format, typeof(ImageFormat))
         };
 

+ 1 - 1
MediaBrowser.Model/Dto/SessionInfoDto.cs

@@ -163,7 +163,7 @@ public class SessionInfoDto
     /// <summary>
     /// Gets or sets the playlist item id.
     /// </summary>
-    /// <value>The splaylist item id.</value>
+    /// <value>The playlist item id.</value>
     public string? PlaylistItemId { get; set; }
 
     /// <summary>

+ 1 - 1
MediaBrowser.Model/Entities/HardwareAccelerationType.cs

@@ -8,7 +8,7 @@ namespace MediaBrowser.Model.Entities;
 public enum HardwareAccelerationType
 {
     /// <summary>
-    /// Software accelleration.
+    /// Software acceleration.
     /// </summary>
     none = 0,
 

+ 1 - 1
MediaBrowser.Model/Entities/MediaStream.cs

@@ -537,7 +537,7 @@ namespace MediaBrowser.Model.Entities
             get
             {
                 // In some cases AverageFrameRate for videos will be read as 1000fps even if it is not.
-                // This is probably due to a library compatability issue.
+                // This is probably due to a library compatibility issue.
                 // See https://github.com/jellyfin/jellyfin/pull/12603#discussion_r1748044018 for more info.
                 return AverageFrameRate < 1000 ? AverageFrameRate : RealFrameRate;
             }

+ 1 - 1
MediaBrowser.Model/Entities/MetadataProvider.cs

@@ -27,7 +27,7 @@ namespace MediaBrowser.Model.Entities
         Tvdb = 4,
 
         /// <summary>
-        /// The tvcom providerd.
+        /// The tvcom provider.
         /// </summary>
         Tvcom = 5,
 

+ 3 - 3
MediaBrowser.Model/Entities/ProviderIdsExtensions.cs

@@ -11,7 +11,7 @@ namespace MediaBrowser.Model.Entities;
 public static class ProviderIdsExtensions
 {
     /// <summary>
-    /// Case insensitive dictionary of <see cref="MetadataProvider"/> string representation.
+    /// Case-insensitive dictionary of <see cref="MetadataProvider"/> string representation.
     /// </summary>
     private static readonly Dictionary<string, string> _metadataProviderEnumDictionary =
         Enum.GetValues<MetadataProvider>()
@@ -107,7 +107,7 @@ public static class ProviderIdsExtensions
     /// <param name="instance">The instance.</param>
     /// <param name="name">The name, this should not contain a '=' character.</param>
     /// <param name="value">The value.</param>
-    /// <remarks>Due to how deserialization from the database works the name can not contain '='.</remarks>
+    /// <remarks>Due to how deserialization from the database works the name cannot contain '='.</remarks>
     /// <returns><c>true</c> if the provider id got set successfully; otherwise, <c>false</c>.</returns>
     public static bool TrySetProviderId(this IHasProviderIds instance, string? name, string? value)
     {
@@ -153,7 +153,7 @@ public static class ProviderIdsExtensions
     /// <param name="instance">The instance.</param>
     /// <param name="name">The name, this should not contain a '=' character.</param>
     /// <param name="value">The value.</param>
-    /// <remarks>Due to how deserialization from the database works the name can not contain '='.</remarks>
+    /// <remarks>Due to how deserialization from the database works the name cannot contain '='.</remarks>
     public static void SetProviderId(this IHasProviderIds instance, string name, string value)
     {
         ArgumentNullException.ThrowIfNull(instance);

+ 1 - 1
MediaBrowser.Model/Globalization/ILocalizationManager.cs

@@ -52,7 +52,7 @@ namespace MediaBrowser.Model.Globalization
         /// <summary>
         /// Gets the localization options.
         /// </summary>
-        /// <returns><see cref="IEnumerable{LocalizatonOption}" />.</returns>
+        /// <returns><see cref="IEnumerable{LocalizationOption}" />.</returns>
         IEnumerable<LocalizationOption> GetLocalizationOptions();
 
         /// <summary>

+ 2 - 2
MediaBrowser.Model/IO/IFileSystem.cs

@@ -145,7 +145,7 @@ namespace MediaBrowser.Model.IO
         /// Gets the directories.
         /// </summary>
         /// <param name="path">The path.</param>
-        /// <param name="recursive">If set to <c>true</c> also searches in subdirectiories.</param>
+        /// <param name="recursive">If set to <c>true</c> also searches in subdirectories.</param>
         /// <returns>All found directories.</returns>
         IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false);
 
@@ -153,7 +153,7 @@ namespace MediaBrowser.Model.IO
         /// Gets the files.
         /// </summary>
         /// <param name="path">The path in which to search.</param>
-        /// <param name="recursive">If set to <c>true</c> also searches in subdirectiories.</param>
+        /// <param name="recursive">If set to <c>true</c> also searches in subdirectories.</param>
         /// <returns>All found files.</returns>
         IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false);
 

+ 2 - 1
MediaBrowser.Model/Net/MimeTypes.cs

@@ -6,6 +6,7 @@ using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 using System.IO;
 using System.Linq;
+using System.Net.Mime;
 using Jellyfin.Extensions;
 
 namespace MediaBrowser.Model.Net
@@ -144,7 +145,7 @@ namespace MediaBrowser.Model.Net
             new("video/x-matroska", ".mkv"),
         }.ToFrozenDictionary(pair => pair.Key, pair => pair.Value, StringComparer.OrdinalIgnoreCase);
 
-        public static string GetMimeType(string path) => GetMimeType(path, "application/octet-stream");
+        public static string GetMimeType(string path) => GetMimeType(path, MediaTypeNames.Application.Octet);
 
         /// <summary>
         /// Gets the type of the MIME.

+ 6 - 1
MediaBrowser.Model/Plugins/PluginStatus.cs

@@ -34,7 +34,12 @@ namespace MediaBrowser.Model.Plugins
         Malfunctioned = -3,
 
         /// <summary>
-        /// This plugin has been superceded by another version.
+        /// This plugin has been superseded by another version.
+        /// </summary>
+        Superseded = -4,
+
+        /// <summary>
+        /// [DEPRECATED] See Superseded.
         /// </summary>
         Superceded = -4,
 

+ 1 - 1
MediaBrowser.Model/Session/TranscodingInfo.cs

@@ -5,7 +5,7 @@ using MediaBrowser.Model.Entities;
 namespace MediaBrowser.Model.Session;
 
 /// <summary>
-/// Class holding information on a runnning transcode.
+/// Class holding information on a running transcode.
 /// </summary>
 public class TranscodingInfo
 {

+ 1 - 1
MediaBrowser.Model/System/PublicSystemInfo.cs

@@ -47,7 +47,7 @@ namespace MediaBrowser.Model.System
         /// Gets or sets a value indicating whether the startup wizard is completed.
         /// </summary>
         /// <remarks>
-        /// Nullable for OpenAPI specification only to retain backwards compatibility in apiclients.
+        /// Nullable for OpenAPI specification only to retain backwards compatibility in api clients.
         /// </remarks>
         /// <value>The startup completion status.</value>]
         public bool? StartupWizardCompleted { get; set; }

+ 2 - 2
MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs

@@ -361,7 +361,7 @@ namespace MediaBrowser.Providers.MediaInfo
                 blurayVideoStream.Codec = ffmpegVideoStream.Codec;
                 blurayVideoStream.BitRate = blurayVideoStream.BitRate.GetValueOrDefault() == 0 ? ffmpegVideoStream.BitRate : blurayVideoStream.BitRate;
                 blurayVideoStream.Width = blurayVideoStream.Width.GetValueOrDefault() == 0 ? ffmpegVideoStream.Width : blurayVideoStream.Width;
-                blurayVideoStream.Height = blurayVideoStream.Height.GetValueOrDefault() == 0 ? ffmpegVideoStream.Width : blurayVideoStream.Height;
+                blurayVideoStream.Height = blurayVideoStream.Height.GetValueOrDefault() == 0 ? ffmpegVideoStream.Height : blurayVideoStream.Height;
                 blurayVideoStream.ColorRange = ffmpegVideoStream.ColorRange;
                 blurayVideoStream.ColorSpace = ffmpegVideoStream.ColorSpace;
                 blurayVideoStream.ColorTransfer = ffmpegVideoStream.ColorTransfer;
@@ -634,7 +634,7 @@ namespace MediaBrowser.Providers.MediaInfo
         {
             var runtime = video.RunTimeTicks.GetValueOrDefault();
 
-            // Only process files with a runtime higher than 0 and lower than 12h. The latter are likely corrupted.
+            // Only process files with a runtime greater than 0 and less than 12h. The latter are likely corrupted.
             if (runtime < 0 || runtime > TimeSpan.FromHours(12).Ticks)
             {
                 throw new ArgumentException(

+ 5 - 7
MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumProvider.cs

@@ -148,21 +148,19 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
             item.Overview = (overview ?? string.Empty).StripHtml();
         }
 
-        internal Task EnsureInfo(string musicBrainzReleaseGroupId, CancellationToken cancellationToken)
+        internal async Task EnsureInfo(string musicBrainzReleaseGroupId, CancellationToken cancellationToken)
         {
             var xmlPath = GetAlbumInfoPath(_config.ApplicationPaths, musicBrainzReleaseGroupId);
 
             var fileInfo = _fileSystem.GetFileSystemInfo(xmlPath);
 
-            if (fileInfo.Exists)
+            if (fileInfo.Exists
+                && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
             {
-                if ((DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
-                {
-                    return Task.CompletedTask;
-                }
+                return;
             }
 
-            return DownloadInfo(musicBrainzReleaseGroupId, cancellationToken);
+            await DownloadInfo(musicBrainzReleaseGroupId, cancellationToken).ConfigureAwait(false);
         }
 
         internal async Task DownloadInfo(string musicBrainzReleaseGroupId, CancellationToken cancellationToken)

+ 3 - 3
MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistProvider.cs

@@ -131,7 +131,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
             item.Overview = (overview ?? string.Empty).StripHtml();
         }
 
-        internal Task EnsureArtistInfo(string musicBrainzId, CancellationToken cancellationToken)
+        internal async Task EnsureArtistInfo(string musicBrainzId, CancellationToken cancellationToken)
         {
             var xmlPath = GetArtistInfoPath(_config.ApplicationPaths, musicBrainzId);
 
@@ -140,10 +140,10 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
             if (fileInfo.Exists
                 && (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 2)
             {
-                return Task.CompletedTask;
+                return;
             }
 
-            return DownloadArtistInfo(musicBrainzId, cancellationToken);
+            await DownloadArtistInfo(musicBrainzId, cancellationToken).ConfigureAwait(false);
         }
 
         internal async Task DownloadArtistInfo(string musicBrainzId, CancellationToken cancellationToken)

+ 2 - 2
MediaBrowser.Providers/Plugins/StudioImages/StudiosImageProvider.cs

@@ -101,11 +101,11 @@ namespace MediaBrowser.Providers.Plugins.StudioImages
             return string.Format(CultureInfo.InvariantCulture, "{0}/images/{1}/{2}.jpg", GetRepositoryUrl(), image, filename);
         }
 
-        private Task EnsureThumbsList(string file, CancellationToken cancellationToken)
+        private async Task EnsureThumbsList(string file, CancellationToken cancellationToken)
         {
             string url = string.Format(CultureInfo.InvariantCulture, "{0}/thumbs.txt", GetRepositoryUrl());
 
-            return EnsureList(url, file, _fileSystem, cancellationToken);
+            await EnsureList(url, file, _fileSystem, cancellationToken).ConfigureAwait(false);
         }
 
         /// <inheritdoc />

+ 2 - 2
MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs

@@ -73,7 +73,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
         protected IProviderManager ProviderManager { get; }
 
         /// <summary>
-        /// Gets a value indicating whether URLs after a closing XML tag are supporrted.
+        /// Gets a value indicating whether URLs after a closing XML tag are supported.
         /// </summary>
         protected virtual bool SupportsUrlAfterClosingXmlTag => false;
 
@@ -672,7 +672,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
                 }
 
                 var fileSystemMetadata = _directoryService.GetFile(val);
-                // non existing file returns null
+                // nonexistent file returns null
                 if (fileSystemMetadata is null || !fileSystemMetadata.Exists)
                 {
                     Logger.LogWarning("Artwork file {Path} specified in nfo file for {ItemName} does not exist.", uri, itemResult.Item.Name);

+ 1 - 1
MediaBrowser.XbmcMetadata/Savers/ArtistNfoSaver.cs

@@ -13,7 +13,7 @@ using Microsoft.Extensions.Logging;
 namespace MediaBrowser.XbmcMetadata.Savers
 {
     /// <summary>
-    /// Nfo saver for artsist.
+    /// Nfo saver for artist.
     /// </summary>
     public class ArtistNfoSaver : BaseNfoSaver
     {

Some files were not shown because too many files changed in this diff