diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 40aee063eb..9affe235db 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -99,6 +99,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Prometheus.DotNetRuntime;
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
+using IConfigurationManager = MediaBrowser.Common.Configuration.IConfigurationManager;
using WebSocketManager = Emby.Server.Implementations.HttpServer.WebSocketManager;
namespace Emby.Server.Implementations
diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
index 18e60b2101..56ccb21ee7 100644
--- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
+++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs
@@ -12,6 +12,7 @@ using MediaBrowser.Controller;
using MediaBrowser.Controller.Plugins;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
+using IConfigurationManager = MediaBrowser.Common.Configuration.IConfigurationManager;
namespace Emby.Server.Implementations.EntryPoints
{
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
index 3ae9e256b2..767b941366 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs
@@ -84,15 +84,13 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return Task.CompletedTask;
}
- public Task Close()
+ public async Task Close()
{
EnableStreamSharing = false;
Logger.LogInformation("Closing {Type}", GetType().Name);
- LiveStreamCancellationTokenSource.Cancel();
-
- return Task.CompletedTask;
+ await LiveStreamCancellationTokenSource.CancelAsync().ConfigureAwait(false);
}
public Stream GetStream()
diff --git a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
index bd3e7d9e3e..2853e69b01 100644
--- a/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
+++ b/Jellyfin.Api/Auth/CustomAuthenticationHandler.cs
@@ -27,13 +27,12 @@ namespace Jellyfin.Api.Auth
/// Options monitor.
/// The logger.
/// The url encoder.
- /// The system clock.
public CustomAuthenticationHandler(
IAuthService authService,
IOptionsMonitor options,
ILoggerFactory logger,
- UrlEncoder encoder,
- ISystemClock clock) : base(options, logger, encoder, clock)
+ UrlEncoder encoder)
+ : base(options, logger, encoder)
{
_authService = authService;
_logger = logger.CreateLogger();
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index 1e6580ed15..7d1a54eced 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -2080,30 +2080,30 @@ public class ImageController : BaseJellyfinApiController
foreach (var (key, value) in headers)
{
- Response.Headers.Add(key, value);
+ Response.Headers.Append(key, value);
}
Response.ContentType = imageContentType ?? MediaTypeNames.Text.Plain;
- Response.Headers.Add(HeaderNames.Age, Convert.ToInt64((DateTime.UtcNow - dateImageModified).TotalSeconds).ToString(CultureInfo.InvariantCulture));
- Response.Headers.Add(HeaderNames.Vary, HeaderNames.Accept);
+ Response.Headers.Append(HeaderNames.Age, Convert.ToInt64((DateTime.UtcNow - dateImageModified).TotalSeconds).ToString(CultureInfo.InvariantCulture));
+ Response.Headers.Append(HeaderNames.Vary, HeaderNames.Accept);
if (disableCaching)
{
- Response.Headers.Add(HeaderNames.CacheControl, "no-cache, no-store, must-revalidate");
- Response.Headers.Add(HeaderNames.Pragma, "no-cache, no-store, must-revalidate");
+ Response.Headers.Append(HeaderNames.CacheControl, "no-cache, no-store, must-revalidate");
+ Response.Headers.Append(HeaderNames.Pragma, "no-cache, no-store, must-revalidate");
}
else
{
if (cacheDuration.HasValue)
{
- Response.Headers.Add(HeaderNames.CacheControl, "public, max-age=" + cacheDuration.Value.TotalSeconds);
+ Response.Headers.Append(HeaderNames.CacheControl, "public, max-age=" + cacheDuration.Value.TotalSeconds);
}
else
{
- Response.Headers.Add(HeaderNames.CacheControl, "public");
+ Response.Headers.Append(HeaderNames.CacheControl, "public");
}
- Response.Headers.Add(HeaderNames.LastModified, dateImageModified.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss \"GMT\"", CultureInfo.InvariantCulture));
+ Response.Headers.Append(HeaderNames.LastModified, dateImageModified.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss \"GMT\"", CultureInfo.InvariantCulture));
// if the image was not modified since "ifModifiedSinceHeader"-header, return a HTTP status code 304 not modified
if (!(dateImageModified > ifModifiedSinceHeader) && cacheDuration.HasValue)
diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
index 24082fcff1..a8df628f0d 100644
--- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
+++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
@@ -147,7 +147,7 @@ public class DynamicHlsHelper
cancellationTokenSource.Token)
.ConfigureAwait(false);
- _httpContextAccessor.HttpContext.Response.Headers.Add(HeaderNames.Expires, "0");
+ _httpContextAccessor.HttpContext.Response.Headers.Append(HeaderNames.Expires, "0");
if (isHeadRequest)
{
return new FileContentResult(Array.Empty(), MimeTypes.GetMimeType("playlist.m3u8"));
@@ -568,7 +568,7 @@ public class DynamicHlsHelper
&& state.VideoStream is not null
&& state.VideoStream.Level.HasValue)
{
- levelString = state.VideoStream.Level.ToString() ?? string.Empty;
+ levelString = state.VideoStream.Level.Value.ToString(CultureInfo.InvariantCulture) ?? string.Empty;
}
else
{
diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs
index 6fbbceeabb..7d9a389312 100644
--- a/Jellyfin.Api/Helpers/StreamingHelpers.cs
+++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs
@@ -279,15 +279,15 @@ public static class StreamingHelpers
var profile = state.DeviceProfile;
StringValues transferMode = request.Headers["transferMode.dlna.org"];
- responseHeaders.Add("transferMode.dlna.org", string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode.ToString());
- responseHeaders.Add("realTimeInfo.dlna.org", "DLNA.ORG_TLAG=*");
+ responseHeaders.Append("transferMode.dlna.org", string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode.ToString());
+ responseHeaders.Append("realTimeInfo.dlna.org", "DLNA.ORG_TLAG=*");
if (state.RunTimeTicks.HasValue)
{
if (string.Equals(request.Headers["getMediaInfo.sec"], "1", StringComparison.OrdinalIgnoreCase))
{
var ms = TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalMilliseconds;
- responseHeaders.Add("MediaInfo.sec", string.Format(
+ responseHeaders.Append("MediaInfo.sec", string.Format(
CultureInfo.InvariantCulture,
"SEC_Duration={0};",
Convert.ToInt32(ms)));
@@ -305,7 +305,7 @@ public static class StreamingHelpers
if (!state.IsVideoRequest)
{
- responseHeaders.Add("contentFeatures.dlna.org", ContentFeatureBuilder.BuildAudioHeader(
+ responseHeaders.Append("contentFeatures.dlna.org", ContentFeatureBuilder.BuildAudioHeader(
profile,
state.OutputContainer,
audioCodec,
@@ -321,7 +321,7 @@ public static class StreamingHelpers
{
var videoCodec = state.ActualOutputVideoCodec;
- responseHeaders.Add(
+ responseHeaders.Append(
"contentFeatures.dlna.org",
ContentFeatureBuilder.BuildVideoHeader(profile, state.OutputContainer, videoCodec, audioCodec, state.OutputWidth, state.OutputHeight, state.TargetVideoBitDepth, state.OutputVideoBitrate, state.TargetTimestamp, isStaticallyStreamed, state.RunTimeTicks, state.TargetVideoProfile, state.TargetVideoRangeType, state.TargetVideoLevel, state.TargetFramerate, state.TargetPacketLength, state.TranscodeSeekInfo, state.IsTargetAnamorphic, state.IsTargetInterlaced, state.TargetRefFrames, state.TargetVideoStreamCount, state.TargetAudioStreamCount, state.TargetVideoCodecTag, state.IsTargetAVC).FirstOrDefault() ?? string.Empty);
}
@@ -404,12 +404,12 @@ public static class StreamingHelpers
var runtimeSeconds = TimeSpan.FromTicks(state.RunTimeTicks!.Value).TotalSeconds.ToString(CultureInfo.InvariantCulture);
var startSeconds = TimeSpan.FromTicks(startTimeTicks ?? 0).TotalSeconds.ToString(CultureInfo.InvariantCulture);
- responseHeaders.Add("TimeSeekRange.dlna.org", string.Format(
+ responseHeaders.Append("TimeSeekRange.dlna.org", string.Format(
CultureInfo.InvariantCulture,
"npt={0}-{1}/{1}",
startSeconds,
runtimeSeconds));
- responseHeaders.Add("X-AvailableSeekRange", string.Format(
+ responseHeaders.Append("X-AvailableSeekRange", string.Format(
CultureInfo.InvariantCulture,
"1 npt={0}-{1}",
startSeconds,
diff --git a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
index c16a586d60..5b407e4a95 100644
--- a/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
+++ b/Jellyfin.Api/Helpers/TranscodingJobHelper.cs
@@ -280,6 +280,7 @@ public class TranscodingJobHelper : IDisposable
if (job.CancellationTokenSource?.IsCancellationRequested == false)
{
+#pragma warning disable CA1849 // Can't await in lock block
job.CancellationTokenSource.Cancel();
}
}
@@ -291,7 +292,6 @@ public class TranscodingJobHelper : IDisposable
lock (job.ProcessLock!)
{
-#pragma warning disable CA1849 // Can't await in lock block
job.TranscodingThrottler?.Stop().GetAwaiter().GetResult();
var process = job.Process;
diff --git a/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs b/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs
index 59e6956c71..d59e4e5e38 100644
--- a/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs
+++ b/Jellyfin.Networking/HappyEyeballs/HttpClientExtension.cs
@@ -65,7 +65,7 @@ namespace Jellyfin.Networking.HappyEyeballs
// See https://github.com/dotnet/corefx/pull/29792/files#r189415885 for more details.
if (await Task.WhenAny(tryConnectAsyncIPv6, Task.Delay(200, cancelIPv6.Token)).ConfigureAwait(false) == tryConnectAsyncIPv6 && tryConnectAsyncIPv6.IsCompletedSuccessfully)
{
- cancelIPv6.Cancel();
+ await cancelIPv6.CancelAsync().ConfigureAwait(false);
return tryConnectAsyncIPv6.GetAwaiter().GetResult();
}
@@ -76,7 +76,7 @@ namespace Jellyfin.Networking.HappyEyeballs
{
if (tryConnectAsyncIPv6.IsCompletedSuccessfully)
{
- cancelIPv4.Cancel();
+ await cancelIPv4.CancelAsync().ConfigureAwait(false);
return tryConnectAsyncIPv6.GetAwaiter().GetResult();
}
@@ -86,7 +86,7 @@ namespace Jellyfin.Networking.HappyEyeballs
{
if (tryConnectAsyncIPv4.IsCompletedSuccessfully)
{
- cancelIPv6.Cancel();
+ await cancelIPv6.CancelAsync().ConfigureAwait(false);
return tryConnectAsyncIPv4.GetAwaiter().GetResult();
}
diff --git a/Jellyfin.Networking/Manager/NetworkManager.cs b/Jellyfin.Networking/Manager/NetworkManager.cs
index 3c03d137be..dbf7127a68 100644
--- a/Jellyfin.Networking/Manager/NetworkManager.cs
+++ b/Jellyfin.Networking/Manager/NetworkManager.cs
@@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
+using IConfigurationManager = MediaBrowser.Common.Configuration.IConfigurationManager;
namespace Jellyfin.Networking.Manager
{
@@ -422,7 +423,7 @@ namespace Jellyfin.Networking.Manager
{
// Parse config values into filter collection
var remoteIPFilter = config.RemoteIPFilter;
- if (remoteIPFilter.Any() && !string.IsNullOrWhiteSpace(remoteIPFilter.First()))
+ if (remoteIPFilter.Length != 0 && !string.IsNullOrWhiteSpace(remoteIPFilter[0]))
{
// Parse all IPs with netmask to a subnet
var remoteAddressFilter = new List();
@@ -540,7 +541,7 @@ namespace Jellyfin.Networking.Manager
}
else if (NetworkUtils.TryParseToSubnet(identifier, out var result) && result is not null)
{
- var data = new IPData(result.BaseAddress, result);
+ var data = new IPData(result.Value.BaseAddress, result);
publishedServerUrls.Add(
new PublishedServerUriOverride(
data,
@@ -606,11 +607,11 @@ namespace Jellyfin.Networking.Manager
var parts = details.Split(',');
if (NetworkUtils.TryParseToSubnet(parts[0], out var subnet))
{
- var address = subnet.BaseAddress;
+ var address = subnet.Value.BaseAddress;
var index = int.Parse(parts[1], CultureInfo.InvariantCulture);
if (address.AddressFamily == AddressFamily.InterNetwork || address.AddressFamily == AddressFamily.InterNetworkV6)
{
- var data = new IPData(address, subnet, parts[2])
+ var data = new IPData(address, subnet.Value, parts[2])
{
Index = index
};
@@ -880,7 +881,7 @@ namespace Jellyfin.Networking.Manager
{
if (NetworkUtils.TryParseToSubnet(address, out var subnet))
{
- return IPAddress.IsLoopback(subnet.BaseAddress) || (_lanSubnets.Any(x => x.Contains(subnet.BaseAddress)) && !_excludedSubnets.Any(x => x.Contains(subnet.BaseAddress)));
+ return IPAddress.IsLoopback(subnet.Value.BaseAddress) || (_lanSubnets.Any(x => x.Contains(subnet.Value.BaseAddress)) && !_excludedSubnets.Any(x => x.Contains(subnet.Value.BaseAddress)));
}
if (NetworkUtils.TryParseHost(address, out var addresses, IsIPv4Enabled, IsIPv6Enabled))
diff --git a/Jellyfin.Server.Implementations/Security/AuthorizationContext.cs b/Jellyfin.Server.Implementations/Security/AuthorizationContext.cs
index 77f8f7071b..6bda12c5b4 100644
--- a/Jellyfin.Server.Implementations/Security/AuthorizationContext.cs
+++ b/Jellyfin.Server.Implementations/Security/AuthorizationContext.cs
@@ -60,7 +60,7 @@ namespace Jellyfin.Server.Implementations.Security
}
private async Task GetAuthorizationInfoFromDictionary(
- IReadOnlyDictionary? auth,
+ Dictionary? auth,
IHeaderDictionary headers,
IQueryCollection queryString)
{
diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs
index edae4cfc5e..075f4cb3a1 100644
--- a/Jellyfin.Server.Implementations/Users/UserManager.cs
+++ b/Jellyfin.Server.Implementations/Users/UserManager.cs
@@ -775,7 +775,7 @@ namespace Jellyfin.Server.Implementations.Users
return providers;
}
- private IList GetPasswordResetProviders(User user)
+ private IPasswordResetProvider[] GetPasswordResetProviders(User user)
{
var passwordResetProviderId = user.PasswordResetProviderId;
var providers = _passwordResetProviders.Where(i => i.IsEnabled).ToArray();
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index 753029f2cd..92c483c0fe 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -30,12 +30,14 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Cors.Infrastructure;
+using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using AuthenticationSchemes = Jellyfin.Api.Constants.AuthenticationSchemes;
+using IPNetwork = System.Net.IPNetwork;
namespace Jellyfin.Server.Extensions
{
@@ -277,9 +279,9 @@ namespace Jellyfin.Server.Extensions
}
else if (NetworkUtils.TryParseToSubnet(allowedProxies[i], out var subnet))
{
- if (subnet is not null)
+ if (subnet.HasValue)
{
- AddIPAddress(config, options, subnet.BaseAddress, subnet.PrefixLength);
+ AddIPAddress(config, options, subnet.Value.BaseAddress, subnet.Value.PrefixLength);
}
}
else if (NetworkUtils.TryParseHost(allowedProxies[i], out var addresses, config.EnableIPv4, config.EnableIPv6))
@@ -310,7 +312,7 @@ namespace Jellyfin.Server.Extensions
}
else
{
- options.KnownNetworks.Add(new IPNetwork(addr, prefixLength));
+ options.KnownNetworks.Add(new Microsoft.AspNetCore.HttpOverrides.IPNetwork(addr, prefixLength));
}
}
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs b/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs
index ac50474010..247e1d8450 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateRatingLevels.cs
@@ -78,11 +78,7 @@ namespace Jellyfin.Server.Migrations.Routines
}
else
{
- var ratingValue = _localizationManager.GetRatingLevel(ratingString).ToString();
- if (string.IsNullOrEmpty(ratingValue))
- {
- ratingValue = "NULL";
- }
+ var ratingValue = _localizationManager.GetRatingLevel(ratingString)?.ToString(CultureInfo.InvariantCulture) ?? "NULL";
using var statement = connection.PrepareStatement("UPDATE TypedBaseItems SET InheritedParentalRatingValue = @Value WHERE OfficialRating = @Rating;");
statement.TryBind("@Value", ratingValue);
diff --git a/MediaBrowser.Common/Net/NetworkUtils.cs b/MediaBrowser.Common/Net/NetworkUtils.cs
index 452cb694ed..7ae99336f1 100644
--- a/MediaBrowser.Common/Net/NetworkUtils.cs
+++ b/MediaBrowser.Common/Net/NetworkUtils.cs
@@ -180,7 +180,7 @@ public static partial class NetworkUtils
{
if (TryParseToSubnet(values[a], out var innerResult, negated))
{
- tmpResult.Add(innerResult);
+ tmpResult.Add(innerResult.Value);
}
}
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 6621ae2842..46fd1ae478 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -20,6 +20,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
using Microsoft.Extensions.Configuration;
+using IConfigurationManager = MediaBrowser.Common.Configuration.IConfigurationManager;
namespace MediaBrowser.Controller.MediaEncoding
{
diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
index be1e8a1726..020e69eced 100644
--- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
+++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs
@@ -516,7 +516,7 @@ namespace MediaBrowser.MediaEncoding.Probing
private void ProcessPairs(string key, List pairs, MediaInfo info)
{
- IList peoples = new List();
+ List peoples = new List();
if (string.Equals(key, "studio", StringComparison.OrdinalIgnoreCase))
{
info.Studios = pairs.Select(p => p.Value)
@@ -1182,7 +1182,7 @@ namespace MediaBrowser.MediaEncoding.Probing
info.Size = string.IsNullOrEmpty(data.Format.Size) ? null : long.Parse(data.Format.Size, CultureInfo.InvariantCulture);
}
- private void SetAudioInfoFromTags(MediaInfo audio, IReadOnlyDictionary tags)
+ private void SetAudioInfoFromTags(MediaInfo audio, Dictionary tags)
{
var people = new List();
if (tags.TryGetValue("composer", out var composer) && !string.IsNullOrWhiteSpace(composer))
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 666e787951..252ac1303f 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -835,11 +835,6 @@ namespace MediaBrowser.Model.Dlna
playlistItem.SetOption(qualifier, "profile", videoStream.Profile.ToLowerInvariant());
}
- if (videoStream is not null && videoStream.Level != 0)
- {
- playlistItem.SetOption(qualifier, "level", videoStream.Level.ToString() ?? string.Empty);
- }
-
// Prefer matching audio codecs, could do better here
var audioCodecs = ContainerProfile.SplitValue(audioCodec);
@@ -866,16 +861,16 @@ namespace MediaBrowser.Model.Dlna
// Copy matching audio codec options
playlistItem.AudioSampleRate = audioStream.SampleRate;
- playlistItem.SetOption(qualifier, "audiochannels", audioStream.Channels.ToString() ?? string.Empty);
+ playlistItem.SetOption(qualifier, "audiochannels", audioStream.Channels?.ToString(CultureInfo.InvariantCulture) ?? string.Empty);
if (!string.IsNullOrEmpty(audioStream.Profile))
{
playlistItem.SetOption(audioStream.Codec, "profile", audioStream.Profile.ToLowerInvariant());
}
- if (audioStream.Level != 0)
+ if (audioStream.Level.HasValue)
{
- playlistItem.SetOption(audioStream.Codec, "level", audioStream.Level.ToString() ?? string.Empty);
+ playlistItem.SetOption(audioStream.Codec, "level", audioStream.Level.Value.ToString(CultureInfo.InvariantCulture));
}
}
diff --git a/MediaBrowser.Providers/Lyric/LrcLyricParser.cs b/MediaBrowser.Providers/Lyric/LrcLyricParser.cs
index 7f1ecd7435..a10ff198b4 100644
--- a/MediaBrowser.Providers/Lyric/LrcLyricParser.cs
+++ b/MediaBrowser.Providers/Lyric/LrcLyricParser.cs
@@ -125,7 +125,7 @@ public class LrcLyricParser : ILyricParser
///
/// The metadata from the LRC file.
/// A lyricMetadata object with mapped property data.
- private static LyricMetadata MapMetadataValues(IDictionary metaData)
+ private static LyricMetadata MapMetadataValues(Dictionary metaData)
{
LyricMetadata lyricMetadata = new();
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index dab36625e5..1a5dbd7a55 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -175,7 +175,7 @@ namespace MediaBrowser.Providers.Manager
IDynamicImageProvider provider,
ImageRefreshOptions refreshOptions,
TypeOptions savedOptions,
- ICollection downloadedImages,
+ List downloadedImages,
RefreshResult result,
CancellationToken cancellationToken)
{
@@ -263,7 +263,7 @@ namespace MediaBrowser.Providers.Manager
ImageRefreshOptions refreshOptions,
TypeOptions savedOptions,
int backdropLimit,
- ICollection downloadedImages,
+ List downloadedImages,
RefreshResult result,
CancellationToken cancellationToken)
{
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
index b4b1895f51..d1c0ddb375 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
@@ -82,8 +82,8 @@ namespace MediaBrowser.Providers.MediaInfo
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
- var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ??
- imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1) ??
+ var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).Contains("front", StringComparison.OrdinalIgnoreCase)) ??
+ imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).Contains("cover", StringComparison.OrdinalIgnoreCase)) ??
imageStreams.FirstOrDefault();
var imageStreamIndex = imageStream?.Index;
diff --git a/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs b/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs
index 909cbb9b9c..f846aa5dec 100644
--- a/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs
+++ b/MediaBrowser.Providers/MediaInfo/MediaInfoResolver.cs
@@ -183,7 +183,7 @@ namespace MediaBrowser.Providers.MediaInfo
files.AddRange(directoryService.GetFilePaths(internalMetadataPath, clearCache, true));
}
- if (!files.Any())
+ if (files.Count == 0)
{
return Array.Empty();
}
diff --git a/MediaBrowser.Providers/Music/AlbumMetadataService.cs b/MediaBrowser.Providers/Music/AlbumMetadataService.cs
index 0ddb2ad67b..e4f34776b9 100644
--- a/MediaBrowser.Providers/Music/AlbumMetadataService.cs
+++ b/MediaBrowser.Providers/Music/AlbumMetadataService.cs
@@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Music
.ToArray();
var id = item.GetProviderId(provider);
- if (ids.Any())
+ if (ids.Length != 0)
{
var firstId = ids[0];
if (!string.IsNullOrEmpty(firstId)
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs
index 7f73afc53a..8a516e1ce7 100644
--- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbAlbumImageProvider.cs
@@ -73,7 +73,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
return Enumerable.Empty();
}
- private IEnumerable GetImages(AudioDbAlbumProvider.Album item)
+ private List GetImages(AudioDbAlbumProvider.Album item)
{
var list = new List();
diff --git a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs
index 2232dfa0d7..4e7757cd26 100644
--- a/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs
+++ b/MediaBrowser.Providers/Plugins/AudioDb/AudioDbArtistImageProvider.cs
@@ -78,7 +78,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
return Enumerable.Empty();
}
- private IEnumerable GetImages(AudioDbArtistProvider.Artist item)
+ private List GetImages(AudioDbArtistProvider.Artist item)
{
var list = new List();
diff --git a/MediaBrowser.Providers/TV/SeriesMetadataService.cs b/MediaBrowser.Providers/TV/SeriesMetadataService.cs
index e01c0f4830..01c07d6332 100644
--- a/MediaBrowser.Providers/TV/SeriesMetadataService.cs
+++ b/MediaBrowser.Providers/TV/SeriesMetadataService.cs
@@ -121,7 +121,7 @@ namespace MediaBrowser.Providers.TV
var seasonNumber = virtualSeason.IndexNumber;
// If there's a physical season with the same number or no episodes in the season, delete it
if ((seasonNumber.HasValue && physicalSeasonNumbers.Contains(seasonNumber.Value))
- || !virtualSeason.GetEpisodes().Any())
+ || virtualSeason.GetEpisodes().Count == 0)
{
Logger.LogInformation("Removing virtual season {SeasonNumber} in series {SeriesName}", virtualSeason.IndexNumber, series.Name);
diff --git a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
index bf66a31458..1399ac307a 100644
--- a/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/BaseNfoSaver.cs
@@ -314,11 +314,11 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
var codec = stream.Codec;
- if ((stream.CodecTag ?? string.Empty).IndexOf("xvid", StringComparison.OrdinalIgnoreCase) != -1)
+ if ((stream.CodecTag ?? string.Empty).Contains("xvid", StringComparison.OrdinalIgnoreCase))
{
codec = "xvid";
}
- else if ((stream.CodecTag ?? string.Empty).IndexOf("divx", StringComparison.OrdinalIgnoreCase) != -1)
+ else if ((stream.CodecTag ?? string.Empty).Contains("divx", StringComparison.OrdinalIgnoreCase))
{
codec = "divx";
}
diff --git a/jellyfin.ruleset b/jellyfin.ruleset
index 870cf253f2..10225e3af8 100644
--- a/jellyfin.ruleset
+++ b/jellyfin.ruleset
@@ -140,6 +140,9 @@
+
+
+
diff --git a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
index 479e6ffdc8..720d987f13 100644
--- a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
+++ b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
@@ -11,8 +11,6 @@ namespace Jellyfin.MediaEncoding.Keyframes.FfProbe;
///
public static class FfProbeKeyframeExtractor
{
- private const string DefaultArguments = "-fflags +genpts -v error -skip_frame nokey -show_entries format=duration -show_entries stream=duration -show_entries packet=pts_time,flags -select_streams v -of csv \"{0}\"";
-
///
/// Extracts the keyframes using the ffprobe executable at the specified path.
///
@@ -26,7 +24,10 @@ public static class FfProbeKeyframeExtractor
StartInfo = new ProcessStartInfo
{
FileName = ffProbePath,
- Arguments = string.Format(CultureInfo.InvariantCulture, DefaultArguments, filePath),
+ Arguments = string.Format(
+ CultureInfo.InvariantCulture,
+ "-fflags +genpts -v error -skip_frame nokey -show_entries format=duration -show_entries stream=duration -show_entries packet=pts_time,flags -select_streams v -of csv \"{0}\"",
+ filePath),
CreateNoWindow = true,
UseShellExecute = false,