| | | 1 | | using Anichron.Core.Domain; |
| | | 2 | | using Anichron.Worker.Ingestion.Pipeline; |
| | | 3 | | using Anichron.Worker.Ingestion.Proxy; |
| | | 4 | | |
| | | 5 | | namespace Anichron.Worker.Ingestion.Middlewares; |
| | | 6 | | |
| | 20 | 7 | | internal sealed partial class VideoProxyMiddleware( |
| | 20 | 8 | | IEnumerable<IVideoProxyGenerator> generators, |
| | 20 | 9 | | IProxyDirectoryStrategy proxyDirectoryStrategy, |
| | 20 | 10 | | ProxyStagingWriter stagingWriter, |
| | 20 | 11 | | ILogger<VideoProxyMiddleware> logger) : IIngestionMiddleware |
| | | 12 | | { |
| | 0 | 13 | | public int Order => IngestionOrder.VideoProxy; |
| | | 14 | | public bool CanInvoke(IngestionContext context) |
| | 3 | 15 | | => context.Item.PrimaryMediaType == MediaType.Video; |
| | | 16 | | |
| | | 17 | | public async Task InvokeAsync(IngestionContext context, IngestionDelegate next, CancellationToken ct) |
| | 17 | 18 | | { |
| | | 19 | | // Ordering guarantees ContentHashingMiddleware ran first; suppression is safe. |
| | 17 | 20 | | var proxyDirectoryName = proxyDirectoryStrategy.GetDirectory(context.Config.Id, context.ContentHash!); |
| | | 21 | | |
| | | 22 | | // Sequential: concurrent FFmpeg processes would saturate the GPU. |
| | 17 | 23 | | var pending = generators.ToArray(); |
| | 89 | 24 | | foreach (var generator in pending) |
| | 20 | 25 | | await ProcessGeneratorAsync(generator); |
| | | 26 | | |
| | 15 | 27 | | Log.ProxiesGenerated(logger, pending.Length, context.Item.RelativePath); |
| | 15 | 28 | | 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); |
| | 15 | 37 | | } |
| | | 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 | | } |