using System; using System.IO; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Media.Imaging; using LibVLCSharp.Shared; using ModuleManager; public static class VideoFrameExtractor { public static BitmapImage GetFrame200(string videoPath) { try { Core.Initialize(); string path = Path.GetTempFileName() + ".png"; 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); 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); } // ❗ Stop playback and dispose BEFORE trying to read the file mp.Stop(); } 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."); // Load BitmapImage on the UI thread BitmapImage image = Application.Current.Dispatcher.Invoke(() => { try { using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { var img = new BitmapImage(); img.BeginInit(); img.CacheOption = BitmapCacheOption.OnLoad; img.DecodePixelWidth = 150; img.DecodePixelHeight = 100; img.StreamSource = fs; fs.Position = 0; img.EndInit(); img.Freeze(); return img; } } catch (Exception ex) { foreach (System.Windows.Window window in System.Windows.Application.Current.Windows) { if (window.IsActive && window is MainWindow mainWindow) { mainWindow.ReciveErrorLog($"Error loading snapshot image from {path}: {ex}"); break; } } throw new Exception("Failed to load snapshot image.", ex); } }); DeleteFileLaterAsync(path); return image; } catch (Exception e) { Console.WriteLine(e); throw; } } 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}"); } } }