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}"); } } }