VideoFrameReader


I’m enamored with the movie capabilities of my Canon Digital Elph.  While I love taking pictures, sometimes I don’t just want stills from an event, but would prefer to capture the whole thing in the form of a movie.  As a result, I take short movies with it all the time.


Recently, I wanted to extract some frames from one of these .avi movies.  Sure, there are a plethora of tools I could download that would do this for me, but what fun is that when I could write one myself? 🙂


So, I wrote a small app called ExtractFrames that extracts all the frames from a video into individual .jpg files, and I’ve made the source available for download (standard disclaimers apply). To use the tool, simply drag-and-drop the video(s) you want to process onto the app in Explorer, or from the command line specify the video(s) you want processed as separate arguments.


The Main method of ExtractFrames is a short wrapper around a class I wrote called VideoFrameReader:

using (VideoFrameReader reader = new VideoFrameReader(path))
{
Console.WriteLine(“Processing ” + path + “…”);

// Create a directory to store the frames
string dirPath = path + “_frames\\”;
Directory.CreateDirectory(dirPath);

// Read each frame and save it into the directory
for (int frameNumber = 0; frameNumber < reader.NumberOfFrames; frameNumber++)
{
using (Bitmap frame = reader.GetFrame(frameNumber))
{
const long quality = 100;
Console.WriteLine(“\tSaving frame {0}/{1}”, frameNumber, reader.NumberOfFrames);
ImageUtilities.SaveImage(frame, dirPath + frameNumber + “.jpg”, quality);
}
}
}


VideoFrameReader is, in turn, a wrapper around the MediaDet COM object, accessed through COM interop (if you want to use VideoFrameReader in your own apps, make sure to add a COM reference to the Dexter 1.0 type library, or just use the existing Interop.DexterLib.dll included in the download).


MediaDet works with most .avi and .wmv files, and I believe some .mpg files, which means VideoFrameReader will do the same. Unfortunately, it doesn’t currently work with .dvr-ms files, so this class can’t be used to extract stills from recorded television unless you first transcode the .dvr-ms to another supported format.


Enjoy!


 

ExtractFrames.zip

Comments (8)

  1. JackLuminous says:

    Hey, Stephen,

    I am working on a video add-in for Media Center and hit a snag with Dexterlib; could you lend a hand? How do I give it a strong name so I can use it with my addin? My add-in is going into the GAC.

    Thanks!

    PS. Love your in-depth (and cool!) articles

  2. You’re welcome, and glad you like the articles! When you create Dexterlib with tlbimp.exe, you can use tlbimp’s /keyfile flag at the command-line to assign a strong-name.

  3. Jeremy Wise says:

    Stephen-

    There appears to be a bug under Vista using Dexterlib. Your sample VideoFrameReader suffers from the same issue that my own code does namely that the 1st image from an avi file is always returned regardless of the requested time.

    Any help would be greatly appreciated.

    jeremywise@readingsuccesslab.com

  4. Devin says:

    Is there anyway to make this work for dvr-ms files? Thanks.

  5. KelA says:

    Stephen,

    I have been using code very similar to yours found in the VideoFrameReader.CS GetFrameSize function. This has worked fine under XP but now under Vista & Visual Studio 2008 (.NET 2.0 still) I am getting an exception when the following executes:

    VIDEOINFOHEADER videoInfo = (VIDEOINFOHEADER)Marshal.PtrToStructure(

                   mediaType.pbFormat, typeof(VIDEOINFOHEADER));

    The exception is:

    "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." System.Exception {System.AccessViolationException}

    Any idea what may be causing this and how this can be resolved?

    Thanks.

  6. suraj.punugade@hotmail.com says:

    It’s really helpful…. Thanks