feat: add scanner functionality and thumbnails

This commit is contained in:
Guillermo Marcel 2025-02-17 18:44:11 -03:00
parent 67042945e5
commit f94c6d5b2a
4 changed files with 47 additions and 25 deletions

View File

@ -1,46 +1,56 @@
using AutoScan.Interfaces; using AutoScan.Interfaces;
using AutoScan.Options;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Diagnostics; using System.Diagnostics;
namespace AutoScan.Implementations; namespace AutoScan.Implementations;
public class DVRScanner : IDVRScanner public class DVRScanner : IDVRScanner
{ {
private readonly ILogger<DVRScanner> _logger; private readonly ILogger _logger;
private const string _mediaPath = @".\media"; // Replace with your desired file path private readonly AutoScanOptions _options;
private const string _dvrScannerFile = @".\dvr-scanner\dvr-scan.exe";
private const string _dvrScannerConfig = @".\dvr-scanner\dvr-scan.cfg";
//.\dvr-scanner\dvr-scan.exe -i .\media\*.mp4 -c .\dvr-scanner\dvr-scan.cfg private DateTime? _startedAt;
public DVRScanner(ILogger<DVRScanner> logger) public DVRScanner(IOptionsSnapshot<AutoScanOptions> options, ILoggerFactory loggerFactory)
{ {
_logger = logger; _options = options.Value;
_logger = loggerFactory.CreateLogger(nameof(DVRScanner));
} }
public async Task ScanVideos(CancellationToken cancellationToken = default) public async Task ScanVideos(CancellationToken cancellationToken = default)
{ {
if(_options.Scanner == null)
{
throw new ArgumentNullException(nameof(_options.Scanner));
}
try try
{ {
//make sure the directory exists
Directory.CreateDirectory(Path.GetDirectoryName(_mediaPath)!);
_logger.LogDebug("Scanning videos..."); _logger.LogDebug("Scanning videos...");
var folderParam = Path.Combine(_options.MediaFolder!, "*.mp4");
var arguments = $"-i {folderParam} -c {_options.Scanner.ConfigFile} --thumbnails highscore";
_logger.LogDebug("Executing command: {_dvrScannerFile} {arguments}", _options.Scanner.Exe, arguments);
var process = new Process var process = new Process
{ {
StartInfo = new ProcessStartInfo StartInfo = new ProcessStartInfo
{ {
FileName = _dvrScannerFile, FileName = _options.Scanner.Exe,
Arguments = $"-i {_mediaPath}\\*.mp4 -c {_dvrScannerConfig}", Arguments = arguments,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = false,
UseShellExecute = false, UseShellExecute = false,
CreateNoWindow = true, CreateNoWindow = true,
} }
}; };
if(_options.Scanner.RunDry)
{
_logger.LogInformation("Dry run enabled, skipping execution...");
return;
}
_startedAt = DateTime.Now;
process.Start(); process.Start();
process.PriorityClass = ProcessPriorityClass.High;
cancellationToken.Register(() => cancellationToken.Register(() =>
{ {
_logger.LogDebug("DVR Process status: ID: {Id}, HasExited: {HasExited}, Responding: {Responding}", _logger.LogDebug("DVR Process status: ID: {Id}, HasExited: {HasExited}, Responding: {Responding}",
@ -52,9 +62,8 @@ public class DVRScanner : IDVRScanner
}); });
_logger.LogDebug("DVR Process started with ID: {Id}", process.Id); _logger.LogDebug("DVR Process started with ID: {Id}", process.Id);
await process.WaitForExitAsync(cancellationToken);
await UpdateProcessUntilExits(process, cancellationToken);
_logger.LogInformation("Videos scanned successfully!"); _logger.LogInformation("Videos scanned successfully!");
} }
catch (Exception ex) catch (Exception ex)
@ -62,4 +71,17 @@ public class DVRScanner : IDVRScanner
_logger.LogError(ex, "An error occurred while scanning the videos"); _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);
}
}
} }

View File

@ -38,15 +38,14 @@ public class ShinobiConnector : IDVRConnector
_logger.LogInformation("Found {Count} videos in the specified range", response.videos.Count); _logger.LogInformation("Found {Count} videos in the specified range", response.videos.Count);
foreach (var video in response.videos.OrderBy(x => x.time))
return response.videos.Select(video =>
{ {
video.end = video.end.ToLocalTime(); video.end = video.end.ToLocalTime();
video.time = video.time.ToLocalTime(); video.time = video.time.ToLocalTime();
_logger.LogDebug("Video: {Filename} - Time: {time} - Ends: {end}", video.filename, video.time, video.end); _logger.LogDebug("Video: {Filename} - Time: {time} - Ends: {end}", video.filename, video.time, video.end);
} return video;
}).OrderBy(x => x.time).ToList();
return response.videos;
} }
public async Task DownloadMonitorVideo(VideoDetail video, string downloadFolder, CancellationToken cancellationToken = default) public async Task DownloadMonitorVideo(VideoDetail video, string downloadFolder, CancellationToken cancellationToken = default)

View File

@ -16,8 +16,9 @@ public class ScannerJob : IJob
} }
public Task Execute(IJobExecutionContext context) public Task Execute(IJobExecutionContext context)
{ {
_logger.LogWarning("ScannerJob is not implemented yet!");
_logger.LogInformation("Scanner {scannerName} is ready to scan!", _scanner.GetType().Name); _logger.LogInformation("Scanner {scannerName} is ready to scan!", _scanner.GetType().Name);
_scanner.ScanVideos();
return Task.CompletedTask; return Task.CompletedTask;
} }