Fix warnings

This commit is contained in:
Bond_009 2023-10-24 00:10:31 +02:00
parent 99e0d46ad9
commit b62b0ec2b5
29 changed files with 67 additions and 69 deletions

View file

@ -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

View file

@ -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
{

View file

@ -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()

View file

@ -27,13 +27,12 @@ namespace Jellyfin.Api.Auth
/// <param name="options">Options monitor.</param>
/// <param name="logger">The logger.</param>
/// <param name="encoder">The url encoder.</param>
/// <param name="clock">The system clock.</param>
public CustomAuthenticationHandler(
IAuthService authService,
IOptionsMonitor<AuthenticationSchemeOptions> options,
ILoggerFactory logger,
UrlEncoder encoder,
ISystemClock clock) : base(options, logger, encoder, clock)
UrlEncoder encoder)
: base(options, logger, encoder)
{
_authService = authService;
_logger = logger.CreateLogger<CustomAuthenticationHandler>();

View file

@ -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)

View file

@ -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<byte>(), 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
{

View file

@ -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,

View file

@ -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;

View file

@ -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();
}

View file

@ -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<IPNetwork>();
@ -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))

View file

@ -60,7 +60,7 @@ namespace Jellyfin.Server.Implementations.Security
}
private async Task<AuthorizationInfo> GetAuthorizationInfoFromDictionary(
IReadOnlyDictionary<string, string>? auth,
Dictionary<string, string>? auth,
IHeaderDictionary headers,
IQueryCollection queryString)
{

View file

@ -775,7 +775,7 @@ namespace Jellyfin.Server.Implementations.Users
return providers;
}
private IList<IPasswordResetProvider> GetPasswordResetProviders(User user)
private IPasswordResetProvider[] GetPasswordResetProviders(User user)
{
var passwordResetProviderId = user.PasswordResetProviderId;
var providers = _passwordResetProviders.Where(i => i.IsEnabled).ToArray();

View file

@ -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));
}
}

View file

@ -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);

View file

@ -180,7 +180,7 @@ public static partial class NetworkUtils
{
if (TryParseToSubnet(values[a], out var innerResult, negated))
{
tmpResult.Add(innerResult);
tmpResult.Add(innerResult.Value);
}
}

View file

@ -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
{

View file

@ -516,7 +516,7 @@ namespace MediaBrowser.MediaEncoding.Probing
private void ProcessPairs(string key, List<NameValuePair> pairs, MediaInfo info)
{
IList<BaseItemPerson> peoples = new List<BaseItemPerson>();
List<BaseItemPerson> peoples = new List<BaseItemPerson>();
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<string, string> tags)
private void SetAudioInfoFromTags(MediaInfo audio, Dictionary<string, string> tags)
{
var people = new List<BaseItemPerson>();
if (tags.TryGetValue("composer", out var composer) && !string.IsNullOrWhiteSpace(composer))

View file

@ -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));
}
}

View file

@ -125,7 +125,7 @@ public class LrcLyricParser : ILyricParser
/// </summary>
/// <param name="metaData">The metadata from the LRC file.</param>
/// <returns>A lyricMetadata object with mapped property data.</returns>
private static LyricMetadata MapMetadataValues(IDictionary<string, string> metaData)
private static LyricMetadata MapMetadataValues(Dictionary<string, string> metaData)
{
LyricMetadata lyricMetadata = new();

View file

@ -175,7 +175,7 @@ namespace MediaBrowser.Providers.Manager
IDynamicImageProvider provider,
ImageRefreshOptions refreshOptions,
TypeOptions savedOptions,
ICollection<ImageType> downloadedImages,
List<ImageType> downloadedImages,
RefreshResult result,
CancellationToken cancellationToken)
{
@ -263,7 +263,7 @@ namespace MediaBrowser.Providers.Manager
ImageRefreshOptions refreshOptions,
TypeOptions savedOptions,
int backdropLimit,
ICollection<ImageType> downloadedImages,
List<ImageType> downloadedImages,
RefreshResult result,
CancellationToken cancellationToken)
{

View file

@ -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;

View file

@ -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<ExternalPathParserResult>();
}

View file

@ -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)

View file

@ -73,7 +73,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
return Enumerable.Empty<RemoteImageInfo>();
}
private IEnumerable<RemoteImageInfo> GetImages(AudioDbAlbumProvider.Album item)
private List<RemoteImageInfo> GetImages(AudioDbAlbumProvider.Album item)
{
var list = new List<RemoteImageInfo>();

View file

@ -78,7 +78,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb
return Enumerable.Empty<RemoteImageInfo>();
}
private IEnumerable<RemoteImageInfo> GetImages(AudioDbArtistProvider.Artist item)
private List<RemoteImageInfo> GetImages(AudioDbArtistProvider.Artist item)
{
var list = new List<RemoteImageInfo>();

View file

@ -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);

View file

@ -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";
}

View file

@ -140,6 +140,9 @@
<Rule Id="CA1812" Action="Info" />
<!-- disable warning CA1822: Member does not access instance data and can be marked as static -->
<Rule Id="CA1822" Action="Info" />
<!-- TODO: Enable -->
<!-- CA1861: Prefer 'static readonly' fields over constant array arguments if the called method is called repeatedly and is not mutating the passed array -->
<Rule Id="CA1861" Action="Info" />
<!-- disable warning CA2000: Dispose objects before losing scope -->
<Rule Id="CA2000" Action="Info" />
<!-- disable warning CA2253: Named placeholders should not be numeric values -->

View file

@ -11,8 +11,6 @@ namespace Jellyfin.MediaEncoding.Keyframes.FfProbe;
/// </summary>
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}\"";
/// <summary>
/// Extracts the keyframes using the ffprobe executable at the specified path.
/// </summary>
@ -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,