using FFMediaToolkit.Decoding; using FFMediaToolkit.Graphics; using System; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; public static class VideoFrameExtractor { public static Bitmap GetFrame200(string videoPath) { FFMediaToolkit.FFmpegLoader.FFmpegPath = AppDomain.CurrentDomain.BaseDirectory; using var mediaFile = MediaFile.Open(videoPath); // Read first two frames to estimate frame rate if (!mediaFile.Video.TryGetNextFrame(out var firstFrame)) throw new Exception("Cannot read first frame"); double firstSeconds = mediaFile.Video.Position.TotalSeconds; if (!mediaFile.Video.TryGetNextFrame(out var secondFrame)) throw new Exception("Cannot read second frame"); double secondSeconds = mediaFile.Video.Position.TotalSeconds; double frameDuration = secondSeconds - firstSeconds; if (frameDuration <= 0) throw new Exception("Invalid frame duration calculated"); double frameRate = 1.0 / frameDuration; int totalFrames = (int)(mediaFile.Info.Duration.TotalSeconds * frameRate); const int targetFrameIndex = 200; if (targetFrameIndex >= totalFrames) throw new ArgumentOutOfRangeException($"Video has only {totalFrames} frames, cannot extract frame {targetFrameIndex}"); // Reopen to reset reading mediaFile.Dispose(); using var mediaFile2 = MediaFile.Open(videoPath); int currentFrameIndex = 0; Bitmap targetFrameBitmap = null; while (mediaFile2.Video.TryGetNextFrame(out var frame)) { if (currentFrameIndex == targetFrameIndex) { targetFrameBitmap = ImageDataToBitmap(frame); break; } currentFrameIndex++; } if (targetFrameBitmap == null) throw new Exception($"Failed to extract frame {targetFrameIndex}"); return targetFrameBitmap; } private static Bitmap ImageDataToBitmap(ImageData imageData) { var bitmap = new Bitmap(imageData.ImageSize.Width, imageData.ImageSize.Height, PixelFormat.Format24bppRgb); var bmpData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); // Convert Span to byte[] for Marshal.Copy Marshal.Copy(imageData.Data.ToArray(), 0, bmpData.Scan0, imageData.Data.Length); bitmap.UnlockBits(bmpData); return bitmap; } }