using AutoScan.Interfaces; using AutoScan.Options; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Diagnostics; namespace AutoScan.Implementations; public class Snapshoter : ISnapshoter { private readonly IDVRConnector _dvrConnector; private readonly AutoScanOptions _options; private readonly ILogger _logger; public Snapshoter(IDVRConnector dvrConnector, IOptions options, ILogger logger) { _dvrConnector = dvrConnector; _options = options.Value; _logger = logger; } public async Task TakeSnapshot() { try { if (_options.Scanner?.FFMpeg is null) { _logger.LogError("FFMpeg path is not set in the options"); return null; } var timer = new Stopwatch(); timer.Start(); var outputDir = _options.Scanner?.SnapshotFolder; if (string.IsNullOrEmpty(outputDir)) { _logger.LogError("Snapshot folder is not set in the options"); return null; } var outputPath = Path.Combine(outputDir, "snp.jpeg"); //create if doesnt exists if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } var originalFeed = await _dvrConnector.GetVideoStream(); var ffmArgs = $"-y -rtsp_transport tcp -i \"{originalFeed}\" -ss 00:00:00.500 -frames:v 1 {outputPath}"; var process = new Process { StartInfo = new ProcessStartInfo { //To change this, I need to make sure ffmpeg is installed FileName = _options.Scanner?.FFMpeg, Arguments = ffmArgs, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, } }; process.Start(); var timeoutSignal = new CancellationTokenSource(TimeSpan.FromSeconds(6)); try { await process.WaitForExitAsync(timeoutSignal.Token); } catch (OperationCanceledException) { _logger.LogError("Taking snapshot timed out"); process.Kill(); return null; } // you can read the output here. // var output = await process.StandardOutput.ReadToEndAsync(); // var error = await process.StandardError.ReadToEndAsync(); timer.Stop(); _logger.LogDebug("Taking snapshot took {Elapsed} ms", timer.ElapsedMilliseconds); if (process.ExitCode != 0) { _logger.LogError("Error taking snapshot, exit code: {ExitCode}", process.ExitCode); return string.Empty; } return outputPath; } catch (Exception ex) { _logger.LogError(ex, "Error taking snapshot"); return null; } } }