vpr/ShadowStream/Modules/videoFrameModule.cs
2025-06-11 19:01:09 +01:00

97 lines
2.8 KiB
C#

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using LibVLCSharp.Shared;
public static class VideoFrameExtractor
{
public static BitmapImage GetFrame200(string videoPath)
{
Core.Initialize();
using var libVLC = new LibVLC("--no-xlib");
using var media = new Media(libVLC, videoPath, FromType.FromPath);
using var mp = new MediaPlayer(media);
mp.Play();
while (!mp.IsPlaying)
Thread.Sleep(10);
// Seek to ~200th frame at 30 fps
mp.Time = (long)((200.0 / 30.0) * 1000);
Thread.Sleep(500);
if (!mp.IsPlaying)
mp.Play();
Thread.Sleep(1000);
string path = Path.GetTempFileName() + ".png";
if (!mp.TakeSnapshot(0, path, 0, 0))
throw new Exception("Snapshot failed.");
// Wait for snapshot file to be fully written and valid
int attempts = 10;
while (attempts-- > 0)
{
if (File.Exists(path) && new FileInfo(path).Length > 0)
break;
Thread.Sleep(100);
}
if (!File.Exists(path))
throw new FileNotFoundException("Snapshot file not found", path);
var fileInfo = new FileInfo(path);
if (fileInfo.Length == 0)
throw new Exception("Snapshot file is empty or corrupted.");
BitmapImage image = null;
try
{
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
if (fs == null)
throw new Exception("FileStream is null.");
image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
// Removed CreateOptions.IgnoreImageCache here to avoid ArgumentNullException
image.StreamSource = fs ?? throw new Exception("StreamSource cannot be null.");
fs.Position = 0;
image.EndInit();
image.Freeze();
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading snapshot image from {path}: {ex}");
throw new Exception("Failed to load snapshot image.", ex);
}
// Async delayed delete of temp snapshot file (after 1 minute)
DeleteFileLaterAsync(path);
return image!;
}
private static async void DeleteFileLaterAsync(string path, int delayMs = 60000)
{
try
{
await Task.Delay(delayMs);
File.Delete(path);
}
catch (Exception ex)
{
Console.WriteLine($"[WARNING] Failed to delete temp snapshot file {path}: {ex.Message}");
}
}
}