using RandomNameGeneratorLibrary; namespace CrestronOpenCvSharp.Capture; public class MjpegCapture { private readonly HttpClient _client = new HttpClient(); private readonly string? _mjpegUrl; private readonly string? _directory; private readonly FacialRecognition? _facialRecognition; private Timer? _timer; private readonly PersonNameGenerator _personNameGenerator; public bool CaptureRunning { get; private set; } public MjpegCapture(string? url, string? directory, FacialRecognition? facialRecognition) { _mjpegUrl = url; _directory = Path.Combine(directory!, "captures"); _facialRecognition = facialRecognition; _personNameGenerator = new PersonNameGenerator(); } public void StartCapture(int timeout) { if (string.IsNullOrEmpty(_directory)) { Console.WriteLine("Directory variable was null or empty."); CaptureRunning = false; return; } CheckIfDirectoryExists(_directory); // Only create if it's null _timer = new Timer(CaptureImage, null, 0, timeout); CaptureRunning = true; } public void StopCapture() { if (_timer is not null) { // Stop the timer _timer.Change(Timeout.Infinite, Timeout.Infinite); // Dispose it _timer.Dispose(); } CaptureRunning = false; } private void CheckIfDirectoryExists(string directory) { Console.WriteLine($"Checking if directory {directory} exists."); if (Directory.Exists(directory)) { // Remove the directory and all its contents Directory.Delete(directory, true); Console.WriteLine($"Directory '{directory}' and all its contents have been removed."); Directory.CreateDirectory(directory); Console.WriteLine($"Directory '{directory}' has been created."); } else { // Create the directory Directory.CreateDirectory(directory); Console.WriteLine($"Directory '{directory}' has been created."); } } private async void CaptureImage(object? state) { try { CaptureRunning = true; var fileName = Path.Combine(_directory!, $"frame_{DateTime.Now:yyyyMMdd_HHmmss}.jpg"); try { HttpResponseMessage response = await _client.GetAsync(_mjpegUrl, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); await using (var stream = await response.Content.ReadAsStreamAsync()) await using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) { await stream.CopyToAsync(fileStream); } Console.WriteLine($"Saved frame to {fileName}"); // TODO Send to image preview window on touchpanel if (_facialRecognition!.CheckForFace(fileName)) { StopCapture(); Console.WriteLine("Face detected, stopping capture"); // TODO Send image to preview window on touchpanel //Path.Combine(_baseDirectory, "aligned.png")); Console.WriteLine("Comparing captured face against database"); var result = await _facialRecognition.CompareFaces(); if (result is not null) { Console.WriteLine($"We have found a match! The person in front of the camera is: {result}"); } else { Console.WriteLine("No match was found in our database, let's add this person!"); var randomFullName = _personNameGenerator.GenerateRandomFirstAndLastName(); _facialRecognition.AddPersonToDatabase(randomFullName); Thread.Sleep(2000); Console.WriteLine("Person added to database, restarting capture"); StartCapture(2000); } } else { Console.WriteLine("No face detected, carrying on!"); } } catch (Exception ex) { Console.WriteLine($"Error capturing image: {ex.Message}"); } } catch (Exception e) { Console.WriteLine($"Error capturing image: {e}"); } } }