96 lines
3.2 KiB
C#
96 lines
3.2 KiB
C#
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;
|
|
}
|
|
}
|
|
} |