Fix 12 code analysis errors in MediaEncoding projects - use LoggerMessage source generators and specific exception types

This commit is contained in:
2026-04-29 08:24:34 -04:00
parent aead802df6
commit 786c61ba09
6 changed files with 62 additions and 14 deletions
@@ -16,7 +16,7 @@ using Microsoft.Extensions.Logging;
namespace Jellyfin.MediaEncoding.Hls.Cache;
/// <inheritdoc />
public class CacheDecorator : IKeyframeExtractor
public partial class CacheDecorator : IKeyframeExtractor
{
private readonly IKeyframeRepository _keyframeRepository;
private readonly IKeyframeExtractor _keyframeExtractor;
@@ -58,11 +58,11 @@ public class CacheDecorator : IKeyframeExtractor
{
if (!_keyframeExtractor.TryExtractKeyframes(itemId, filePath, out var result))
{
_logger.LogDebug("Failed to extract keyframes using {ExtractorName}", _keyframeExtractorName);
LogKeyframeExtractionFailed(_logger, _keyframeExtractorName);
return false;
}
_logger.LogDebug("Successfully extracted keyframes using {ExtractorName}", _keyframeExtractorName);
LogKeyframeExtractionSucceeded(_logger, _keyframeExtractorName);
keyframeData = result;
_keyframeRepository.SaveKeyframeDataAsync(itemId, keyframeData, CancellationToken.None)
.GetAwaiter()
@@ -71,4 +71,10 @@ public class CacheDecorator : IKeyframeExtractor
return true;
}
[LoggerMessage(Level = LogLevel.Debug, Message = "Failed to extract keyframes using {ExtractorName}")]
private static partial void LogKeyframeExtractionFailed(ILogger logger, string extractorName);
[LoggerMessage(Level = LogLevel.Debug, Message = "Successfully extracted keyframes using {ExtractorName}")]
private static partial void LogKeyframeExtractionSucceeded(ILogger logger, string extractorName);
}
@@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging;
using Extractor = Jellyfin.MediaEncoding.Keyframes.FfProbe.FfProbeKeyframeExtractor;
/// <inheritdoc />
public class FfProbeKeyframeExtractor : IKeyframeExtractor
public partial class FfProbeKeyframeExtractor : IKeyframeExtractor
{
private readonly IMediaEncoder _mediaEncoder;
private readonly NamingOptions _namingOptions;
@@ -51,12 +51,27 @@ public class FfProbeKeyframeExtractor : IKeyframeExtractor
keyframeData = Extractor.GetKeyframeData(_mediaEncoder.ProbePath, filePath);
return keyframeData.KeyframeTicks.Count > 0;
}
catch (Exception ex)
catch (FileNotFoundException ex)
{
_logger.LogError(ex, "Extracting keyframes from {FilePath} using ffprobe failed", filePath);
LogKeyframeExtractionError(_logger, filePath, ex);
}
catch (UnauthorizedAccessException ex)
{
LogKeyframeExtractionError(_logger, filePath, ex);
}
catch (IOException ex)
{
LogKeyframeExtractionError(_logger, filePath, ex);
}
catch (InvalidDataException ex)
{
LogKeyframeExtractionError(_logger, filePath, ex);
}
keyframeData = null;
return false;
}
[LoggerMessage(Level = LogLevel.Error, Message = "Extracting keyframes from {FilePath} using ffprobe failed")]
private static partial void LogKeyframeExtractionError(ILogger logger, string filePath, Exception exception);
}
@@ -6,12 +6,13 @@ namespace Jellyfin.MediaEncoding.Hls.Extractors;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Jellyfin.MediaEncoding.Keyframes;
using Microsoft.Extensions.Logging;
using Extractor = Jellyfin.MediaEncoding.Keyframes.Matroska.MatroskaKeyframeExtractor;
/// <inheritdoc />
public class MatroskaKeyframeExtractor : IKeyframeExtractor
public partial class MatroskaKeyframeExtractor : IKeyframeExtractor
{
private readonly ILogger<MatroskaKeyframeExtractor> _logger;
@@ -41,12 +42,27 @@ public class MatroskaKeyframeExtractor : IKeyframeExtractor
keyframeData = Extractor.GetKeyframeData(filePath);
return keyframeData.KeyframeTicks.Count > 0;
}
catch (Exception ex)
catch (FileNotFoundException ex)
{
_logger.LogError(ex, "Extracting keyframes from {FilePath} using matroska metadata failed", filePath);
LogKeyframeExtractionError(_logger, filePath, ex);
}
catch (UnauthorizedAccessException ex)
{
LogKeyframeExtractionError(_logger, filePath, ex);
}
catch (IOException ex)
{
LogKeyframeExtractionError(_logger, filePath, ex);
}
catch (InvalidDataException ex)
{
LogKeyframeExtractionError(_logger, filePath, ex);
}
keyframeData = null;
return false;
}
[LoggerMessage(Level = LogLevel.Error, Message = "Extracting keyframes from {FilePath} using matroska metadata failed")]
private static partial void LogKeyframeExtractionError(ILogger logger, string filePath, Exception exception);
}
@@ -37,6 +37,8 @@ public class DynamicHlsPlaylistGenerator : IDynamicHlsPlaylistGenerator
/// <inheritdoc />
public string CreateMainPlaylist(CreateMainPlaylistRequest request)
{
ArgumentNullException.ThrowIfNull(request);
IReadOnlyList<double> segments;
// For video transcodes it is sufficient with equal length segments as ffmpeg will create new keyframes
if (request.IsRemuxingVideo
@@ -56,6 +56,8 @@ public class KeyframeExtractionScheduledTask : IScheduledTask
/// <inheritdoc />
public Task ExecuteAsync(IProgress<double> progress, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(progress);
var query = new InternalItemsQuery
{
MediaTypes = [MediaType.Video],
@@ -50,10 +50,13 @@ public static class FfProbeKeyframeExtractor
{
process.PriorityClass = ProcessPriorityClass.BelowNormal;
}
catch
catch (InvalidOperationException)
{
// We do not care if process priority setting fails
// Ideally log a warning but this does not have a logger available
// Process may have already exited - ignore
}
catch (System.ComponentModel.Win32Exception)
{
// Priority setting may not be supported on this platform - ignore
}
return ParseStream(process.StandardOutput);
@@ -67,9 +70,13 @@ public static class FfProbeKeyframeExtractor
process.Kill();
}
}
catch
catch (InvalidOperationException)
{
// We do not care if this fails
// Process may have already exited - ignore
}
catch (System.ComponentModel.Win32Exception)
{
// Process termination may fail - ignore
}
throw;