using AutoScan.Interfaces; using AutoScan.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Diagnostics; namespace AutoScan.Implementations; public class DVRScanner : IDVRScanner { private readonly ILogger _logger; private readonly AutoScanOptions _options; private DateTime? _startedAt; public DVRScanner(IOptionsSnapshot options, ILoggerFactory loggerFactory) { _options = options.Value; _logger = loggerFactory.CreateLogger(nameof(DVRScanner)); } public async Task ScanVideos(CancellationToken cancellationToken = default) { if(_options.Scanner == null) { throw new ArgumentNullException(nameof(_options.Scanner)); } try { _logger.LogDebug("Scanning videos..."); var folderParam = Path.Combine(_options.MediaFolder!, "*.mp4"); var arguments = $"-i {folderParam} -c {_options.Scanner.ConfigFile} --quiet --logfile log.txt --output-dir {_options.Scanner.DetectionFolder} --thumbnails highscore"; _logger.LogDebug("Executing command: {_dvrScannerFile} {arguments}", _options.Scanner.Exe, arguments); var process = new Process { StartInfo = new ProcessStartInfo { FileName = _options.Scanner.Exe, Arguments = arguments, RedirectStandardOutput = false, RedirectStandardError = false, UseShellExecute = false, CreateNoWindow = true, } }; if(_options.Scanner.RunDry) { _logger.LogInformation("Dry run enabled, skipping execution..."); return; } CleanDetectionFiles(); _startedAt = DateTime.Now; process.Start(); // process.PriorityClass = ProcessPriorityClass.High; cancellationToken.Register(() => { _logger.LogDebug("DVR Process status: ID: {Id}, HasExited: {HasExited}, Responding: {Responding}", process.Id, process.HasExited, process.Responding); if(process.HasExited) return; _logger.LogWarning("DVR Process is still running, killing it..."); process.Kill(); }); _logger.LogDebug("DVR Process started with ID: {Id}", process.Id); await UpdateProcessUntilExits(process, cancellationToken); _logger.LogInformation("Videos scanned successfully!"); } catch (Exception ex) { _logger.LogError(ex, "An error occurred while scanning the videos"); } } private async Task UpdateProcessUntilExits(Process process, CancellationToken cancellationToken = default) { while (!process.HasExited && !cancellationToken.IsCancellationRequested) { await Task.Delay(15000, cancellationToken); var duration = DateTime.Now - _startedAt; _logger.LogTrace("[{duration}] DVR Scan running", duration); } } private void CleanDetectionFiles() { if (_options.Scanner?.DetectionFolder is null) return; if (_options.Scanner!.RunDry) return; //remove .avi files from the detection folder _logger.LogDebug("Removing .avi files from detection folder {DetectionFolder}", _options.Scanner.DetectionFolder); foreach (var file in Directory.GetFiles(_options.Scanner!.DetectionFolder!, "*")) { File.Delete(file); } } }