< Summary

Line coverage
82%
Covered lines: 14
Uncovered lines: 3
Coverable lines: 17
Total lines: 300
Line coverage: 82.3%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: .cctor()100%210%
File 2: .ctor(...)100%11100%
File 2: get_Order()100%210%
File 2: CanInvoke(...)100%11100%
File 2: InvokeAsync()100%22100%

File(s)

/home/runner/work/anichron/anichron/src/.artifacts/obj/Anichron.Worker/debug/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs

File '/home/runner/work/anichron/anichron/src/.artifacts/obj/Anichron.Worker/debug/Microsoft.Extensions.Logging.Generators/Microsoft.Extensions.Logging.Generators.LoggerMessageGenerator/LoggerMessage.g.cs' does not exist (any more).

/home/runner/work/anichron/anichron/src/Anichron.Worker/Ingestion/Middlewares/VideoProxyMiddleware.cs

#LineLine coverage
 1using Anichron.Core.Domain;
 2using Anichron.Worker.Ingestion.Pipeline;
 3using Anichron.Worker.Ingestion.Proxy;
 4
 5namespace Anichron.Worker.Ingestion.Middlewares;
 6
 207internal sealed partial class VideoProxyMiddleware(
 208    IEnumerable<IVideoProxyGenerator> generators,
 209    IProxyDirectoryStrategy proxyDirectoryStrategy,
 2010    ProxyStagingWriter stagingWriter,
 2011    ILogger<VideoProxyMiddleware> logger) : IIngestionMiddleware
 12{
 013    public int Order => IngestionOrder.VideoProxy;
 14    public bool CanInvoke(IngestionContext context)
 315        => context.Item.PrimaryMediaType == MediaType.Video;
 16
 17    public async Task InvokeAsync(IngestionContext context, IngestionDelegate next, CancellationToken ct)
 1718    {
 19        // Ordering guarantees ContentHashingMiddleware ran first; suppression is safe.
 1720        var proxyDirectoryName = proxyDirectoryStrategy.GetDirectory(context.Config.Id, context.ContentHash!);
 21
 22        // Sequential: concurrent FFmpeg processes would saturate the GPU.
 1723        var pending = generators.ToArray();
 8924        foreach (var generator in pending)
 2025            await ProcessGeneratorAsync(generator);
 26
 1527        Log.ProxiesGenerated(logger, pending.Length, context.Item.RelativePath);
 1528        await next(context, ct);
 29
 30        Task ProcessGeneratorAsync(IVideoProxyGenerator generator)
 31            => stagingWriter.WriteAsync(
 32                context,
 33                $"{proxyDirectoryName}/{generator.FileName}",
 34                generator.ProxyType,
 35                (temporaryPath, token) => generator.TranscodeAsync(context.Item.AbsolutePath, temporaryPath, token),
 36                ct);
 1537    }
 38
 39    private static partial class Log
 40    {
 41        [LoggerMessage(Level = LogLevel.Information, Message = "Generated {Count} video proxy file(s) for {RelativePath}
 42        public static partial void ProxiesGenerated(ILogger logger, int count, string relativePath);
 43    }
 44}