I’m using FrameGrabber.cs and I added its dll as reference: JockerSoft.Media.dll and Interop.qedit.
Now in Form1 code in the constructor I’m trying to retrieve all the frames in their position and save each frame to a new bitmap file on the hard disk but I can’t figure out how to do it.
I don’t know how to loop through all frames/double[] position I also wanted to see get information about how many frames there are I could get the framerate which is 17.8….
I want to get a list/array of all frames and then save each frame to hard disk and then do another manipulations on the frames.
This is the site i got the example from. Tried to look there and on source code but couldn’t figure out how to do it.
** I also have a trackBar1 in the designer I wanted to be able to scroll through all frames which also doesn’t work good.
This is my Form1 code which doesn’t work good I can get only one frame.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ExtractFrames.Properties;
using ExtractFrames;
using JockerSoft.Media;
using JockerSoft;
using Interop.qedit;
using Interop;
using System.Runtime.InteropServices;
namespace ExtractFrames
{
public partial class Form1 : Form
{
double x;
string sf;
double[] streamDouble ;
string strVideoFile;
public Form1()
{
InitializeComponent();
sf = @"d:\Frames\";
strVideoFile = @"d:\My Movie.wmv";
for (int x = 0; x < 40; x++)
{
streamDouble = new double[x];
SaveFramesFromVideo(strVideoFile, streamDouble, sf + x.ToString("D6") + ".bmp");
}
//getFrameRate();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void getFrameRate()
{
// Get framerate
MediaDet md = new MediaDet();
md.Filename = strVideoFile;
//md.CurrentStream = 0; // choose the video stream
x = md.FrameRate;
double i = md.StreamLength;
}
public static void SaveFramesFromVideo(string videoFile, double[] positions, string outputBitmapFiles)
{
if (videoFile == null)
throw new ArgumentNullException("videoFile");
double streamLength;
IMediaDet mediaDet = null;
try
{
_AMMediaType mediaType;
if (openVideoStream(videoFile, out mediaDet, out mediaType))
{
streamLength = mediaDet.StreamLength;
Size target = getVideoSize(mediaType);
int iteration = 0;
foreach (double position in positions)
{
iteration++;
string outputBitmapFile = string.Format(outputBitmapFiles, iteration);
mediaDet.WriteBitmapBits(position, target.Width, target.Height, outputBitmapFile);
}
return;
}
}
catch (COMException ex)
{
throw new InvalidVideoFileException();
}
finally
{
if (mediaDet != null)
Marshal.ReleaseComObject(mediaDet);
}
throw new InvalidVideoFileException("No video stream was found");
}
private static Size getVideoSize(_AMMediaType mediaType)
{
WinStructs.VIDEOINFOHEADER videoInfo = (WinStructs.VIDEOINFOHEADER)Marshal.PtrToStructure(mediaType.pbFormat, typeof(WinStructs.VIDEOINFOHEADER));
return new Size(videoInfo.bmiHeader.biWidth, videoInfo.bmiHeader.biHeight);
}
private static Size scaleToFit(Size target, Size original)
{
if (target.Height * original.Width > target.Width * original.Height)
target.Height = target.Width * original.Height / original.Width;
else
target.Width = target.Height * original.Width / original.Height;
return target;
}
private static Size scaleToFitSmart(Size target, Size original)
{
target = scaleToFit(target, original);
if (target.Width > original.Width || target.Height > original.Height)
return original;
return target;
}
private static bool openVideoStream(string videoFile, out IMediaDet mediaDet, out _AMMediaType aMMediaType)
{
mediaDet = new MediaDet();
//loads file
mediaDet.Filename = videoFile;
//gets # of streams
int streamsNumber = mediaDet.OutputStreams;
//finds a video stream
for (int i = 0; i < streamsNumber; i++)
{
mediaDet.CurrentStream = i;
_AMMediaType mediaType = mediaDet.StreamMediaType;
if (mediaType.majortype == JockerSoft.Media.MayorTypes.MEDIATYPE_Video)
{
//video stream found
aMMediaType = mediaType;
return true;
}
}
//no video stream found
Marshal.ReleaseComObject(mediaDet);
mediaDet = null;
aMMediaType = new _AMMediaType();
return false;
}
}
}
The
SaveFramesFromVideo()method expects a double array filled with the percentage position in the file in seconds – since you don’t know how this relates to the length of the video you cannot use the frame rate alone. You can however save a frame at each full percentage into the file:If you just need that for WMV files you could also use AsfMojo instead – a complete solution would then look like this: