casa-bot/src/CasaBot/AutoScan/Implementations/Snapshoter.cs

96 lines
3.2 KiB
C#
Raw Normal View History

2025-05-05 19:56:34 -03:00
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<Snapshoter> _logger;
public Snapshoter(IDVRConnector dvrConnector, IOptions<AutoScanOptions> options, ILogger<Snapshoter> logger)
{
_dvrConnector = dvrConnector;
_options = options.Value;
_logger = logger;
}
public async Task<string?> 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;
}
}
}