Add retroactive scan task for existing libraries
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JellyfinPlugin
|
||||
{
|
||||
public static class CropHelper
|
||||
{
|
||||
public static async Task<string> DetectCropAsync(string filePath, double limit)
|
||||
{
|
||||
string limitStr = limit.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
var startInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = "ffmpeg",
|
||||
Arguments = $"-skip_frame nokey -i \"{filePath}\" -vf \"cropdetect=limit={limitStr}:round=16:reset=0\" -f null -",
|
||||
RedirectStandardError = true,
|
||||
RedirectStandardOutput = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = startInfo };
|
||||
process.Start();
|
||||
|
||||
string output = await process.StandardError.ReadToEndAsync();
|
||||
await process.WaitForExitAsync();
|
||||
|
||||
var regex = new Regex(@"crop=([0-9]+):([0-9]+):([0-9]+):([0-9]+)");
|
||||
var matches = regex.Matches(output);
|
||||
|
||||
var crops = new ConcurrentDictionary<string, int>();
|
||||
int totalFrames = 0;
|
||||
|
||||
foreach (Match match in matches)
|
||||
{
|
||||
string cropStr = match.Value.Replace("crop=", "");
|
||||
crops.AddOrUpdate(cropStr, 1, (_, count) => count + 1);
|
||||
totalFrames++;
|
||||
}
|
||||
|
||||
if (totalFrames == 0) return string.Empty;
|
||||
|
||||
var validCrops = crops.Where(kvp => (double)kvp.Value / totalFrames > 0.05).ToList();
|
||||
if (!validCrops.Any())
|
||||
{
|
||||
validCrops = crops.OrderByDescending(kvp => kvp.Value).Take(1).ToList();
|
||||
}
|
||||
|
||||
int minX = int.MaxValue, minY = int.MaxValue, maxXW = 0, maxYH = 0;
|
||||
|
||||
foreach (var kvp in validCrops)
|
||||
{
|
||||
var parts = kvp.Key.Split(':');
|
||||
if (parts.Length == 4 &&
|
||||
int.TryParse(parts[0], out int w) && int.TryParse(parts[1], out int h) &&
|
||||
int.TryParse(parts[2], out int x) && int.TryParse(parts[3], out int y))
|
||||
{
|
||||
minX = Math.Min(minX, x);
|
||||
minY = Math.Min(minY, y);
|
||||
maxXW = Math.Max(maxXW, x + w);
|
||||
maxYH = Math.Max(maxYH, y + h);
|
||||
}
|
||||
}
|
||||
|
||||
int finalW = maxXW - minX;
|
||||
int finalH = maxYH - minY;
|
||||
|
||||
if (finalW <= 0 || finalH <= 0) return string.Empty;
|
||||
|
||||
return $"{finalW}:{finalH}:{minX}:{minY}";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user