hello kitty
This commit is contained in:
76
ShadowStream/Modules/videoFrameModule.cs
Normal file
76
ShadowStream/Modules/videoFrameModule.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
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<byte> to byte[] for Marshal.Copy
|
||||
Marshal.Copy(imageData.Data.ToArray(), 0, bmpData.Scan0, imageData.Data.Length);
|
||||
|
||||
bitmap.UnlockBits(bmpData);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user