65.9K
CodeProject is changing. Read more.
Home

Direct Show Api For Web Based Project

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.29/5 (9 votes)

Apr 18, 2008

Public Domain

1 min read

viewsIcon

35835

downloadIcon

572

Code Project

New_Folder__2_

Introduction

This article is on how to grab a thumbnail from video file in ASP.NET using C#. I have found a lot of articles using a desktop-based method of grabbing thumbnails, but felt there should be some articles related a web-based method.

Background

You should know the basics of OOP, and have knowledge of DirectShow Api. But not knowing all these things is not a big deal if you know C#. You can read about DirectShow media library on msdn.

Using the code

GetFramefromvideo will return you to the bitmap. So the heart of this code is GetFrame.

           
public void Page_Load(Object Sender, EventArgs E)

{

double streamLength;

Bitmap bit = GetFrameFromVideo("B:\\child.wmv", 0, out streamLength, Size.Empty);

Graphics objGraphic = Graphics.FromImage(bit);

objGraphic.SmoothingMode = SmoothingMode.HighQuality;

bit.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);

Response.ContentType = "image/gif";

}


 ///grabing poster from video file
public static Bitmap GetFrameFromVideo(string videoFile, double percentagePosition,
   out double streamLength, Size target)

{

if (videoFile == null)

throw new ArgumentNullException("videoFile");

if (percentagePosition > 1 || percentagePosition < 0)

throw new ArgumentOutOfRangeException("percentagePosition", percentagePosition,
    "Valid range is 0.0 .. 1.0");

if (target.Width % 4 != 0 || target.Height % 4 != 0)

throw new ArgumentException("Target size must be a multiple of 4", "target");

IMediaDet mediaDet = null;

try

{

_AMMediaType mediaType;

if (openVideoStream(videoFile, out mediaDet, out mediaType))

{

streamLength = mediaDet.StreamLength;

//calculates the REAL target size of our frame

if (target == Size.Empty)

target = getVideoSize(mediaType);

else

{

target = scaleToFit(target, getVideoSize(mediaType));

//ensures that the size is a multiple of 4 (required by the Bitmap constructor)

target.Width -= target.Width % 4;

target.Height -= target.Height % 4;

}

unsafe

{

Size s = getVideoSize(mediaType);

int bmpinfoheaderSize = 40; //equals to sizeof(CommonClasses.BITMAPINFOHEADER);

//get size for buffer

//equals to mediaDet.GetBitmapBits(0d, ref bufferSize, ref *buffer,
//target.Width, target.Height); 
int bufferSize = (((s.Width * s.Height) * 24) / 8) + bmpinfoheaderSize; 

//allocates enough memory to store the frame

IntPtr frameBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(bufferSize);

byte* frameBuffer2 = (byte*)frameBuffer.ToPointer();

//gets bitmap, save in frameBuffer2

mediaDet.GetBitmapBits(streamLength * percentagePosition, ref bufferSize,
    ref *frameBuffer2, target.Width, target.Height);

//now in buffer2 we have a BITMAPINFOHEADER structure followed by the DIB bits

Bitmap bmp = new Bitmap(target.Width, target.Height, target.Width * 3,
     System.Drawing.Imaging.PixelFormat.Format24bppRgb,
     new IntPtr(frameBuffer2 + bmpinfoheaderSize));

bmp.RotateFlip(RotateFlipType.Rotate180FlipX);

System.Runtime.InteropServices.Marshal.FreeHGlobal(frameBuffer);

return bmp;

}

}

}

catch (COMException ex)

{

throw new InvalidVideoFileException(getErrorMsg((uint)ex.ErrorCode), ex);

}

finally

{

if (mediaDet != null)

Marshal.ReleaseComObject(mediaDet);

}

throw new InvalidVideoFileException("No video stream was found");

}

To get a thumbnail of image I use GetBitmapBits which will write bits into the buffer and then save it to intpionter to a bitmap and return it. Bascially this code deals with memory. If you want save that image physically at a location you can use writeBitmapbits. Which is quite easy and you can grab image that way. To make this code work please don't forget to add references to two DLL files which are attached with this project folder: Interop.DexterLib.dll and JockerSoft.Media.dll. Once in a new folder give the relevant hard code path in page_onload.

Points of Interest

I feel it is harder to publish an article then to write code. Keep a running update of any changes or improvements you've made here. email me at pankaj.chhura@gmail.com