对一段视频,采帧(总结)
引用DexterLib。dll
1.新建一个类文件 FrameGrabber.cs
#region 版权注释
/* **************************************************************
* this class is created by jillzhang at 06/9/26
* this class is based on Interop.DexterLib.dll
* Interop.DexterLib.dll is a assembly to allow u
* user DirectShow Object Com within .net rather than
* add com object directly.
* this code consult the ariticles:
* http://www.yafla.com/dennisforbes/Extracting-Video-Frames-with-NET/Extracting-Video-Frames-with-NET.html
* http://www.jockersoft.com"
* especialy thank jocker's article and example.
* thank you for using the code
* but when your system or application is commercial
* please give clear indication thatthe source code is
* created by jillzhang at a drak night!thank u.:)
****************************************************************/
#endregion
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using DexterLib;
namespace Jillzhang.VideoCapture
{
/// <summary>
/// 此类从视频文件中抓取某桢图片,用于生成视频文件的缩略图
/// this class can capture a frame of a vedio,i test successfule
/// for following format:wmv,rm,avi,rmvb,mpg,mepg,asf
/// </summary>
public class FrameGrabber
{
/// <summary>
/// 从视频文件的特定位置吸取出一桢
/// Extracts a frame from videoFile at percentagePosition and returns it
/// </summary>
/// <param name="videoFile">视频文件的系统路径(此处为绝对路径)-Path to the video file</param>
/// <param name="percentagePosition">抓取位置,合法范围为0.0-1.0-Valid range is 0.0 .. 1.0</param>
/// <param name="target">图像限制大小,如果为空则为视频文件源大小-The image will be scaled to the specified size.
/// If Size.Empty is passed, the original video size will be used</param>
/// <returns>吸取出来的图像-Bitmap of the extracted frame</returns>
/// <exception cref="InvalidVideoFileException">在执行此函数过程中可能抛出非法视频文件异常-thrown if the extraction fails</exception>
/// <exception cref="ArgumentOutOfRangeException">在执行过程中可能抛出超出范围的异常,表示图像过大,不能正常生成-
/// thrown if an invalid percentagePosition is passed</exception>
public static Bitmap GetFrameFromVideo(string videoFile, double percentagePosition)
{
double streamLength;
return GetFrameFromVideo(videoFile, percentagePosition, out streamLength, Size.Empty);
}
/// <summary>
/// 从视频文件的特定位置吸取出一桢
/// Extracts a frame from videoFile at percentagePosition and returns it
/// </summary>
/// <param name="videoFile">视频文件的系统路径(此处为绝对路径)-Path to the video file</param>
/// <param name="percentagePosition">抓取位置,合法范围为0.0-1.0-Valid range is 0.0 .. 1.0</param>
/// <param name="target">图像限制大小,如果为空则为视频文件源大小-The image will be scaled to the specified size.
/// If Size.Empty is passed, the original video size will be used</param>
/// <returns>吸取出来的图像-Bitmap of the extracted frame</returns>
/// <exception cref="InvalidVideoFileException">在执行此函数过程中可能抛出非法视频文件异常-thrown if the extraction fails</exception>
/// <exception cref="ArgumentOutOfRangeException">在执行过程中可能抛出超出范围的异常,表示图像过大,不能正常生成-
/// thrown if an invalid percentagePosition is passed</exception>
public static Bitmap GetFrameFromVideo(string videoFile, double percentagePosition, Size target)
{
double streamLength;
return GetFrameFromVideo(videoFile, percentagePosition, out streamLength, target);
}
/// <summary>
/// 从视频文件的特定位置吸取出一桢
/// Extracts a frame from videoFile at percentagePosition and returns it
/// </summary>
/// <param name="videoFile">视频文件的系统路径(此处为绝对路径)-Path to the video file</param>
/// <param name="percentagePosition">抓取位置,合法范围为0.0-1.0-Valid range is 0.0 .. 1.0</param>
/// <param name="target">图像限制大小,如果为空则为视频文件源大小-The image will be scaled to the specified size.
/// If Size.Empty is passed, the original video size will be used</param>
/// <returns>吸取出来的图像-Bitmap of the extracted frame</returns>
/// <exception cref="InvalidVideoFileException">在执行此函数过程中可能抛出非法视频文件异常-thrown if the extraction fails</exception>
/// <exception cref="ArgumentOutOfRangeException">在执行过程中可能抛出超出范围的异常,表示图像过大,不能正常生成-
/// thrown if an invalid percentagePosition is passed</exception>
public static Bitmap GetFrameFromVideo(string videoFile, double percentagePosition, out double streamLength, Size target)
{
if (percentagePosition > 1 || percentagePosition < 0)
throw new ArgumentOutOfRangeException("percentagePosition", percentagePosition, "Valid range is 0.0 .. 1.0");
try
{
MediaDetClass mediaDet;
_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));
unsafe
{
Size s= GetVideoSize(videoFile);
int bmpinfoheaderSize = 40; //equals to sizeof(CommonClasses.BITMAPINFOHEADER);
//get size for buffer
int bufferSize = (((s.Width * s.Height) * 24) / 8 ) + bmpinfoheaderSize; //equals to mediaDet.GetBitmapBits(0d, ref bufferSize, ref *buffer, target.Width, target.Height);
//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)
{
//GC.Collect();
throw new InvalidVideoFileException(getErrorMsg((uint)ex.ErrorCode), ex);
}
//GC.Collect();
throw new InvalidVideoFileException("No video stream was found");
}
/// <summary>
/// 吸取一桢从视频文件里面,并且将其保存为bmp格式到特定目录-
/// Extracts a frame from videoFile at percentagePosition and saves it as .bmp in outputBitmapFile
/// </summary>
/// <param name="videoFile">视频文件系统路径(绝对路径)-Path to the video file</param>
/// <param name="percentagePosition">抓取位置,合法范围为0.0-1.0-Valid range is 0.0 .. 1.0</param>
/// <param name="outputBitmapFile">bmp图像保存位置-Path to a file in which save the frame (bmp format)</param>
/// <exception cref="InvalidVideoFileException">在执行此函数过程中可能抛出非法视频文件异常-thrown if the extraction fails</exception>
/// <exception cref="ArgumentOutOfRangeException">在执行过程中可能抛出超出范围的异常,表示图像过大,不能正常生成-
/// thrown if an invalid percentagePosition is passed</exception>
public static void SaveFrameFromVideo(string videoFile, double percentagePosition, string outputBitmapFile)
{
double streamLength;
SaveFrameFromVideo(videoFile, percentagePosition, outputBitmapFile, out streamLength, Size.Empty);
}
/// <summary>
/// 吸取一桢从视频文件里面,并且将其保存为bmp格式到特定目录-
/// Extracts a frame from videoFile at percentagePosition and saves it as .bmp in outputBitmapFile
/// </summary>
/// <param name="videoFile">视频文件系统路径(绝对路径)-Path to the video file</param>
/// <param name="percentagePosition">抓取位置,合法范围为0.0-1.0-Valid range is 0.0 .. 1.0</param>
/// <param name="outputBitmapFile">bmp图像保存位置-Path to a file in which save the frame (bmp format)</param>
/// <exception cref="InvalidVideoFileException">在执行此函数过程中可能抛出非法视频文件异常-thrown if the extraction fails</exception>
/// <exception cref="ArgumentOutOfRangeException">在执行过程中可能抛出超出范围的异常,表示图像过大,不能正常生成-
/// thrown if an invalid percentagePosition is passed</exception>
public static void SaveFrameFromVideo(string videoFile, double percentagePosition, string outputBitmapFile, Size target)
{
double streamLength;
SaveFrameFromVideo(videoFile, percentagePosition, outputBitmapFile, out streamLength, target);
}
/// <summary>
/// 吸取一桢从视频文件里面,并且将其保存为bmp格式到特定目录-
/// Extracts a frame from videoFile at percentagePosition and saves it as .bmp in outputBitmapFile
/// </summary>
/// <param name="videoFile">视频文件系统路径(绝对路径)-Path to the video file</param>
/// <param name="percentagePosition">抓取位置,合法范围为0.0-1.0-Valid range is 0.0 .. 1.0</param>
/// <param name="outputBitmapFile">bmp图像保存位置-Path to a file in which save the frame (bmp format)</param>
/// <param name="streamLength">流长度-will contain the length in seconds of the video stream</param>
/// <exception cref="InvalidVideoFileException">在执行此函数过程中可能抛出非法视频文件异常-thrown if the extraction fails</exception>
/// <exception cref="ArgumentOutOfRangeException">在执行过程中可能抛出超出范围的异常,表示图像过大,不能正常生成-
/// thrown if an invalid percentagePosition is passed</exception>
public static void SaveFrameFromVideo(string videoFile, double percentagePosition, string outputBitmapFile, out double streamLength, Size target)
{
if (percentagePosition > 1 || percentagePosition < 0)
throw new ArgumentOutOfRangeException("percentagePosition", percentagePosition, "Valid range is 0.0 .. 1.0");
try
{
MediaDetClass mediaDet;
_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));
mediaDet.WriteBitmapBits(streamLength * percentagePosition, target.Width, target.Height, outputBitmapFile);
//GC.Collect();
return;
}
}
catch (COMException ex)
{
//GC.Collect();
throw new InvalidVideoFileException(getErrorMsg((uint)ex.ErrorCode), ex);
}
//GC.Collect();
throw new InvalidVideoFileException("No video stream was found");
}
/// <summary>
/// 获得视频文件桢大小-Returns the Size of video frames
/// </summary>
/// <param name="videoFile">视频文件的路径-Path to the video file</param>
/// <returns>视频文件桢大小,返回Size.Empty表示错误-
/// Size of video. Size.Empty for failures (no video stream present, file not supported..)</returns>
public static Size GetVideoSize(string videoFile)
{
MediaDetClass mediaDet;
_AMMediaType mediaType;
if (openVideoStream(videoFile, out mediaDet, out mediaType))
{
return getVideoSize(mediaType);
}
return Size.Empty;
}
/// <summary>
/// 从视频文件里面获得视频桢大小
/// </summary>
/// <param name="mediaType">视频类型对象</param>
/// <returns>桢大小</returns>
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);
}
/// <summary>
/// 规划为合适大小
/// </summary>
/// <param name="target">目标大小</param>
/// <param name="original">源大小</param>
/// <returns>实际大小</returns>
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;
}
/// <summary>
/// 规划为小的合适大小
/// </summary>
/// <param name="target">目标大小</param>
/// <param name="original">源大小</param>
/// <returns>实际大小</returns>
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;
}
/// <summary>
/// 试图打开一视频文件,如果成功它便可以正常实例化成为一个合法的对象-
/// MediaDetClasstries to open a video file. If successful it makes available MediaDetClass and _AMMediaType instances of the current file
/// </summary>
/// <param name="videoFile">视频文件路径</param>
/// <param name="mediaDetClass">实例</param>
/// <param name="aMMediaType">视频类型</param>
/// <returns>操作结果-true for success, false for failure (no video stream, file not supported, ...)</returns>
private static bool openVideoStream(string videoFile, out MediaDetClass mediaDetClass, out _AMMediaType aMMediaType)
{
MediaDetClass mediaDet = new MediaDetClass();
//loads file
//加载视频文件
mediaDet.Filename = videoFile;
//gets # of streams
//获得视频文件的全部流
int streamsNumber = mediaDet.OutputStreams;
//finds a video stream and grabs a frame
//获得视频文件流,并抓取一桢
for (int i = 0; i < streamsNumber; i++)
{
mediaDet.CurrentStream = i;
_AMMediaType mediaType = mediaDet.StreamMediaType;
if (mediaType.majortype == Jillzhang.VideoCapture.MayorTypes.MEDIATYPE_Video)
{
mediaDetClass = mediaDet;
aMMediaType = mediaType;
return true;
}
}
mediaDetClass = null;
aMMediaType = new _AMMediaType();
return false;
}
/// <summary>
/// 获得错误消息-Returns a description for errorCode passed. Only errors of type VFW (defined in vfwmsgs.h)
/// </summary>
/// <param name="errorCode"></param>
/// <returns></returns>
private static string getErrorMsg(uint errorCode)
{
string errorMsg = null;
switch(errorCode)
{
case 0x80040200: //VFW_E_INVALIDMEDIATYPE
errorMsg = "An invalid media type was specified";
break;
case 0x80040201: //VFW_E_INVALIDSUBTYPE
errorMsg = "An invalid media subtype was specified";
break;
case 0x80040202: //VFW_E_NEED_OWNER
errorMsg = "This object can only be created as an aggregated object";
break;
case 0x80040203: //VFW_E_ENUM_OUT_OF_SYNC
errorMsg = "The enumerator has become invalid";
break;
case 0x80040204: //VFW_E_ALREADY_CONNECTED
errorMsg = "At least one of the pins involved in the operation is already connected";
break;
case 0x80040205: //VFW_E_FILTER_ACTIVE
errorMsg = "This operation cannot be performed because the filter is active";
break;
case 0x80040206: //VFW_E_NO_TYPES
errorMsg = "One of the specified pins supports no media types";
break;
case 0x80040207: //VFW_E_NO_ACCEPTABLE_TYPES
errorMsg = "There is no common media type between these pins";
break;
case 0x80040208: //VFW_E_INVALID_DIRECTION
errorMsg = "Two pins of the same direction cannot be connected together";
break;
case 0x80040209: //VFW_E_NOT_CONNECTED
errorMsg = "The operation cannot be performed because the pins are not connected";
break;
case 0x80040210: //VFW_E_NO_ALLOCATOR
errorMsg = "No sample buffer allocator is available";
break;
case 0x80040211: //VFW_E_NOT_COMMITTED
errorMsg = "Cannot allocate a sample when the allocator is not active";
break;
case 0x80040212: //VFW_E_SIZENOTSET
errorMsg = "Cannot allocate memory because no size has been set";
break;
case 0x80040213: //VFW_E_NO_CLOCK
errorMsg = "Cannot lock for synchronization because no clock has been defined";
break;
case 0x80040214: //VFW_E_NO_SINK
errorMsg = "Quality messages could not be sent because no quality sink has been defined";
break;
case 0x80040215: //VFW_E_NO_INTERFACE
errorMsg = "A required interface has not been implemented";
break;
case 0x80040216: //VFW_E_NOT_FOUND
errorMsg = "An object or name was not found";
break;
case 0x80040217: //VFW_E_CANNOT_CONNECT
errorMsg = "No combination of intermediate filters could be found to make the connection";
break;
case 0x80040218: //VFW_E_CANNOT_RENDER
errorMsg = "No combination of filters could be found to render the stream";
break;
case 0x80040219: //VFW_E_CHANGING_FORMAT
errorMsg = "Could not change formats dynamically";
break;
case 0x80040220: //VFW_E_NO_COLOR_KEY_SET
errorMsg = "No color key has been set";
break;
case 0x80040221: //VFW_E_NO_DISPLAY_PALETTE
errorMsg = "Display does not use a palette";
break;
case 0x80040222: //VFW_E_TOO_MANY_COLORS
errorMsg = "Too many colors for the current display settings";
break;
case 0x80040223: //VFW_E_STATE_CHANGED
errorMsg = "The state changed while waiting to process the sample";
break;
case 0x80040224: //VFW_E_NOT_STOPPED
errorMsg = "The operation could not be performed because the filter is not stopped";
break;
case 0x80040225: //VFW_E_NOT_PAUSED
errorMsg = "The operation could not be performed because the filter is not paused";
break;
case 0x80040226: //VFW_E_NOT_RUNNING
errorMsg = "The operation could not be performed because the filter is not running";
break;
case 0x80040227: //VFW_E_WRONG_STATE
errorMsg = "The operation could not be performed because the filter is in the wrong state";
break;
case 0x80040228: //VFW_E_START_TIME_AFTER_END
errorMsg = "The sample start time is after the sample end time";
break;
case 0x80040229: //VFW_E_INVALID_RECT
errorMsg = "The supplied rectangle is invalid";
break;
case 0x80040230: //VFW_E_TYPE_NOT_ACCEPTED
errorMsg = "This pin cannot use the supplied media type";
break;
case 0x80040231: //VFW_E_CIRCULAR_GRAPH
errorMsg = "The filter graph is circular";
break;
case 0x80040232: //VFW_E_NOT_ALLOWED_TO_SAVE
errorMsg = "Updates are not allowed in this state";
break;
case 0x80040233: //VFW_E_TIME_ALREADY_PASSED
errorMsg = "An attempt was made to queue a command for a time in the past";
break;
case 0x80040234: //VFW_E_ALREADY_CANCELLED
errorMsg = "The queued command has already been canceled";
break;
case 0x80040235: //VFW_E_CORRUPT_GRAPH_FILE
errorMsg = "Cannot render the file because it is corrupt";
break;
case 0x80040236: //VFW_E_ADVISE_ALREADY_SET
errorMsg = "An overlay advise link already exists";
break;
case 0x00040237: //VFW_S_STATE_INTERMEDIATE
errorMsg = "The state transition has not completed";
break;
case 0x80040239: //VFW_E_NO_MODEX_AVAILABLE
errorMsg = "This Advise cannot be canceled because it was not successfully set";
break;
case 0x80040240: //VFW_E_NO_FULLSCREEN
errorMsg = "The media type of this file is not recognized";
break;
case 0x80040241: //VFW_E_CANNOT_LOAD_SOURCE_FILTER
errorMsg = "The source filter for this file could not be loaded";
break;
case 0x00040242: //VFW_S_PARTIAL_RENDER
errorMsg = "Some of the streams in this movie are in an unsupported format";
break;
case 0x80040243: //VFW_E_FILE_TOO_SHORT
errorMsg = "A file appeared to be incomplete";
break;
case 0x80040244: //VFW_E_INVALID_FILE_VERSION
errorMsg = "The version number of the file is invalid";
break;
case 0x00040245: //VFW_S_SOME_DATA_IGNORED
errorMsg = "The file contained some property settings that were not used";
break;
case 0x00040246: //VFW_S_CONNECTIONS_DEFERRED
errorMsg = "Some connections have failed and have been deferred";
break;
case 0x00040103: //VFW_E_INVALID_CLSID
errorMsg = "A registry entry is corrupt";
break;
case 0x80040249: //VFW_E_SAMPLE_TIME_NOT_SET
errorMsg = "No time stamp has been set for this sample";
break;
case 0x00040250: //VFW_S_RESOURCE_NOT_NEEDED
errorMsg = "The resource specified is no longer needed";
break;
case 0x80040251: //VFW_E_MEDIA_TIME_NOT_SET
errorMsg = "No media time stamp has been set for this sample";
break;
case 0x80040252: //VFW_E_NO_TIME_FORMAT_SET
errorMsg = "No media time format has been selected";
break;
case 0x80040253: //VFW_E_MONO_AUDIO_HW
errorMsg = "Cannot change balance because audio device is mono only";
break;
case 0x00040260: //VFW_S_MEDIA_TYPE_IGNORED
errorMsg = "ActiveMovie cannot play MPEG movies on this processor";
break;
case 0x80040261: //VFW_E_NO_TIME_FORMAT
errorMsg = "Cannot get or set time related information on an object that is using a time format of TIME_FORMAT_NONE";
break;
case 0x80040262: //VFW_E_READ_ONLY
errorMsg = "The connection cannot be made because the stream is read only and the filter alters the data";
break;
case 0x00040263: //VFW_S_RESERVED
errorMsg = "This success code is reserved for internal purposes within ActiveMovie";
break;
case 0x80040264: //VFW_E_BUFFER_UNDERFLOW
errorMsg = "The buffer is not full enough";
break;
case 0x80040266: //VFW_E_UNSUPPORTED_STREAM
errorMsg = "Pins cannot connect due to not supporting the same transport";
break;
case 0x00040267: //VFW_S_STREAM_OFF
errorMsg = "The stream has been turned off";
break;
case 0x00040270: //VFW_S_CANT_CUE
errorMsg = "The stop time for the sample was not set";
break;
case 0x80040272: //VFW_E_OUT_OF_VIDEO_MEMORY
errorMsg = "The VideoPort connection negotiation process has failed";
break;
case 0x80040276: //VFW_E_DDRAW_CAPS_NOT_SUITABLE
errorMsg = "This User Operation is inhibited by DVD Content at this time";
break;
case 0x80040277: //VFW_E_DVD_INVALIDDOMAIN
errorMsg = "This Operation is not permitted in the current domain";
break;
case 0x00040280: //VFW_E_DVD_NO_BUTTON
errorMsg = "This object cannot be used anymore as its time has expired";
break;
case 0x80040281: //VFW_E_DVD_WRONG_SPEED
errorMsg = "The operation cannot be performed at the current playback speed";
break;
case 0x80040283: //VFW_E_DVD_MENU_DOES_NOT_EXIST
errorMsg = "The specified command was either cancelled or no longer exists";
break;
case 0x80040284: //VFW_E_DVD_STATE_WRONG_VERSION
errorMsg = "The data did not contain a recognized version";
break;
case 0x80040285: //VFW_E_DVD_STATE_CORRUPT
errorMsg = "The state data was corrupt";
break;
case 0x80040286: //VFW_E_DVD_STATE_WRONG_DISC
errorMsg = "The state data is from a different disc";
break;
case 0x80040287: //VFW_E_DVD_INCOMPATIBLE_REGION
errorMsg = "The region was not compatible with the current drive";
break;
case 0x80040288: //VFW_E_DVD_NO_ATTRIBUTES
errorMsg = "The requested DVD stream attribute does not exist";
break;
case 0x80040290: //VFW_E_DVD_NO_GOUP_PGC
errorMsg = "The current parental level was too low";
break;
case 0x80040291: //VFW_E_DVD_INVALID_DISC
errorMsg = "The specified path does not point to a valid DVD disc";
break;
case 0x80040292: //VFW_E_DVD_NO_RESUME_INFORMATION
errorMsg = "There is currently no resume information";
break;
case 0x80040295: //VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD
errorMsg = "An operation failed due to a certification failure";
break;
case 0x80040296: //VFW_E_VMR_NOT_IN_MIXER_MODE
errorMsg = "The VMR could not find any ProcAmp hardware on the current display device";
break;
case 0x80040297: //VFW_E_VMR_NO_AP_SUPPLIED
errorMsg = "The application has not yet provided the VMR filter with a valid allocator-presenter object";
break;
case 0x80040298: //VFW_E_VMR_NO_DEINTERLACE_HW
errorMsg = "The VMR could not find any ProcAmp hardware on the current display device";
break;
case 0x80040299: //VFW_E_VMR_NO_PROCAMP_HW
errorMsg = "VMR9 does not work with VPE-based hardware decoders";
break;
case 0x8004029A: //VFW_E_DVD_VMR9_INCOMPATIBLEDEC
errorMsg = "VMR9 does not work with VPE-based hardware decoders";
break;
case 0x8004029B: //VFW_E_NO_COPP_HW
errorMsg = "The current display device does not support Content Output Protection Protocol (COPP) H/W";
break;
}
return errorMsg;
}
}
public class WinStructs
{
/// <summary>
/// 视频信息头结构用来描述视频图像的bitmap和颜色信息-The VIDEOINFOHEADER structure describes the bitmap and color information for a video image
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct VIDEOINFOHEADER
{
/// <summary>RECT structure that specifies the source video window. This structure can be a clipping rectangle, to select a portion of the source video stream.</summary>
public RECT rcSource;
/// <summary>RECT structure that specifies the destination video window.</summary>
public RECT rcTarget;
/// <summary>Approximate data rate of the video stream, in bits per second</summary>
public uint dwBitRate;
/// <summary>Data error rate, in bit errors per second</summary>
public uint dwBitErrorRate;
/// <summary>The desired average display time of the video frames, in 100-nanosecond units. The actual time per frame may be longer. See Remarks.</summary>
public long AvgTimePerFrame;
/// <summary>BITMAPINFOHEADER structure that contains color and dimension information for the video image bitmap. If the format block contains a color table or color masks, they immediately follow the bmiHeader member. You can get the first color entry by casting the address of member to a BITMAPINFO pointer</summary>
public BITMAPINFOHEADER bmiHeader;
}
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
int left;
int top;
int right;
int bottom;
}
/// <summary>
/// bitmap信息头结构用来描述bitmap图像的维度和颜色信息-The BITMAPINFOHEADER structure contains information about the dimensions and color format of a device-independent bitmap (DIB).
/// SEE MSDN
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
/// <summary>Specifies the number of bytes required by the structure. This value does not include the size of the color table or the size of the color masks, if they are appended to the end of structure. See Remarks.</summary>
public uint biSize;
/// <summary>Specifies the width of the bitmap, in pixels. For information about calculating the stride of the bitmap, see Remarks.</summary>
public int biWidth;
/// <summary>Specifies the height of the bitmap, in pixels. SEE MSDN</summary>
public int biHeight;
/// <summary>Specifies the number of planes for the target device. This value must be set to 1</summary>
public ushort biPlanes;
/// <summary>Specifies the number of bits per pixel (bpp). For uncompressed formats, this value gives to the average number of bits per pixel. For compressed formats, this value gives the implied bit depth of the uncompressed image, after the image has been decoded.</summary>
public ushort biBitCount;
/// <summary>For compressed video and YUV formats, this member is a FOURCC code, specified as a DWORD in little-endian order. For example, YUYV video has the FOURCC 'VYUY' or 0x56595559. SEE MSDN</summary>
public uint biCompression;
/// <summary>Specifies the size, in bytes, of the image. This can be set to 0 for uncompressed RGB bitmaps</summary>
public uint biSizeImage;
/// <summary>Specifies the horizontal resolution, in pixels per meter, of the target device for the bitmap</summary>
public int biXPelsPerMeter;
/// <summary>Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap</summary>
public int biYPelsPerMeter;
/// <summary>Specifies the number of color indices in the color table that are actually used by the bitmap. See Remarks for more information.</summary>
public uint biClrUsed;
/// <summary>Specifies the number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important</summary>
public uint biClrImportant;
}
}
/// <summary>
/// 非法视频文件异常
/// </summary>
public class InvalidVideoFileException : System.Exception
{
public InvalidVideoFileException() : base () {}
public InvalidVideoFileException(string message) : base (message) {}
public InvalidVideoFileException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base (info, context) {}
public InvalidVideoFileException(string message, Exception innerException) : base (message, innerException) {}
}
}
2.新建一个GUIDS.cs文件
/* **************************************************************
*
* This code is provided as is, without any warranty.
* The entire risk as to the quality, the performance of the code
* for any particular purpose lies with the party using the code.
*
* You may edit it and use into your programs, but if you do so,
* remember to put this text into the credits window and/or into
* documentation (if applicable)
* "This program uses code developed by Jocker.
* http://www.jockersoft.com"
*
****************************************************************/
using System;
namespace Jillzhang.VideoCapture
{
// --- major and sub types --- from uuids.h
// extracted with regex .+?\((MEDIASUBTYPE_\w+),(.+?)\)//
public class MayorTypes
{
public static Guid MEDIATYPE_Video = new Guid( 0x73646976, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_Audio = new Guid( 0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_Text = new Guid( 0x73747874, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_Midi = new Guid( 0x7364696D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_Stream = new Guid( 0xe436eb83, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIATYPE_Interleaved = new Guid( 0x73766169, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_File = new Guid( 0x656c6966, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_ScriptCommand = new Guid( 0x73636d64, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_AUXLine21Data = new Guid( 0x670aea80, 0x3a82, 0x11d0, 0xb7, 0x9b, 0x0, 0xaa, 0x0, 0x37, 0x67, 0xa7);
public static Guid MEDIATYPE_VBI = new Guid( 0xf72a76e1, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba);
public static Guid MEDIATYPE_Timecode = new Guid( 0x482dee3, 0x7817, 0x11cf, 0x8a, 0x3, 0x0, 0xaa, 0x0, 0x6e, 0xcb, 0x65);
public static Guid MEDIATYPE_LMRT = new Guid( 0x74726c6d, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIATYPE_URL_STREAM = new Guid( 0x736c7275, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
}
public class SubTypes
{
public static Guid MEDIASUBTYPE_CLPL = new Guid(0x4C504C43, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_YUYV = new Guid(0x56595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IYUV = new Guid(0x56555949, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_YVU9 = new Guid(0x39555659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_Y411 = new Guid(0x31313459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_Y41P = new Guid(0x50313459, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_YUY2 = new Guid(0x32595559, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_YVYU = new Guid(0x55595659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_UYVY = new Guid(0x59565955, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_Y211 = new Guid(0x31313259, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_CLJR = new Guid(0x524a4c43, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IF09 = new Guid(0x39304649, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_CPLA = new Guid(0x414c5043, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_MJPG = new Guid(0x47504A4D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_TVMJ = new Guid(0x4A4D5654, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_WAKE = new Guid(0x454B4157, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_CFCC = new Guid(0x43434643, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IJPG = new Guid(0x47504A49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_Plum = new Guid(0x6D756C50, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_DVCS = new Guid(0x53435644, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_DVSD = new Guid(0x44535644, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_MDVF = new Guid(0x4656444D, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_RGB1 = new Guid(0xe436eb78, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_RGB4 = new Guid(0xe436eb79, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_RGB8 = new Guid(0xe436eb7a, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_RGB565 = new Guid(0xe436eb7b, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_RGB555 = new Guid(0xe436eb7c, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_RGB24 = new Guid(0xe436eb7d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
// ******************
public static Guid MEDIASUBTYPE_ARGB1555 = new Guid(0x297c55af, 0xe209, 0x4cb3, 0xb7, 0x57, 0xc7, 0x6d, 0x6b, 0x9c, 0x88, 0xa8);
public static Guid MEDIASUBTYPE_ARGB4444 = new Guid(0x6e6415e6, 0x5c24, 0x425f, 0x93, 0xcd, 0x80, 0x10, 0x2b, 0x3d, 0x1c, 0xca);
public static Guid MEDIASUBTYPE_ARGB32 = new Guid(0x773c9ac0, 0x3274, 0x11d0, 0xb7, 0x24, 0x0, 0xaa, 0x0, 0x6c, 0x1a, 0x1 );
public static Guid MEDIASUBTYPE_A2R10G10B10 = new Guid(0x2f8bb76d, 0xb644, 0x4550, 0xac, 0xf3, 0xd3, 0x0c, 0xaa, 0x65, 0xd5, 0xc5);
public static Guid MEDIASUBTYPE_A2B10G10R10 = new Guid(0x576f7893, 0xbdf6, 0x48c4, 0x87, 0x5f, 0xae, 0x7b, 0x81, 0x83, 0x45, 0x67);
public static Guid MEDIASUBTYPE_AYUV = new Guid(0x56555941, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_AI44 = new Guid(0x34344941, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IA44 = new Guid(0x34344149, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_RGB32_D3D_DX7_RT = new Guid(0x32335237, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_RGB16_D3D_DX7_RT = new Guid(0x36315237, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_ARGB32_D3D_DX7_RT = new Guid(0x38384137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_ARGB4444_D3D_DX7_RT = new Guid(0x34344137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_ARGB1555_D3D_DX7_RT = new Guid(0x35314137, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_RGB32_D3D_DX9_RT = new Guid(0x32335239, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_RGB16_D3D_DX9_RT = new Guid(0x36315239, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_ARGB32_D3D_DX9_RT = new Guid(0x38384139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_ARGB4444_D3D_DX9_RT = new Guid(0x34344139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_ARGB1555_D3D_DX9_RT = new Guid(0x35314139, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
// ***************************************
public static Guid MEDIASUBTYPE_YV12 = new Guid(0x32315659, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_NV12 = new Guid(0x3231564E, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IMC1 = new Guid(0x31434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IMC2 = new Guid(0x32434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IMC3 = new Guid(0x33434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IMC4 = new Guid(0x34434D49, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_S340 = new Guid(0x30343353, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_S342 = new Guid(0x32343353, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_Overlay = new Guid(0xe436eb7f, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_MPEG1Packet = new Guid(0xe436eb80, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_MPEG1Payload = new Guid(0xe436eb81, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_MPEG1AudioPayload = new Guid(0x00000050, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
public static Guid MEDIASUBTYPE_MPEG1System = new Guid(0xe436eb84, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_MPEG1VideoCD = new Guid(0xe436eb85, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_MPEG1Video = new Guid(0xe436eb86, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_MPEG1Audio = new Guid(0xe436eb87, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_Avi = new Guid(0xe436eb88, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_Asf = new Guid(0x3db80f90, 0x9412, 0x11d1, 0xad, 0xed, 0x0, 0x0, 0xf8, 0x75, 0x4b, 0x99);
public static Guid MEDIASUBTYPE_QTMovie = new Guid(0xe436eb89, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_QTRpza = new Guid(0x617a7072, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_QTSmc = new Guid(0x20636d73, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_QTRle = new Guid(0x20656c72, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_QTJpeg = new Guid(0x6765706a, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_PCMAudio_Obsolete = new Guid(0xe436eb8a, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_PCM = new Guid(0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71);
public static Guid MEDIASUBTYPE_WAVE = new Guid(0xe436eb8b, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_AU = new Guid(0xe436eb8c, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_AIFF = new Guid(0xe436eb8d, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
public static Guid MEDIASUBTYPE_dvsd = new Guid(0x64737664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_dvhd = new Guid(0x64687664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_dvsl = new Guid(0x6c737664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_dv25 = new Guid(0x35327664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_dv50 = new Guid(0x30357664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_dvh1 = new Guid(0x31687664, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_Line21_BytePair = new Guid(0x6e8d4a22, 0x310c, 0x11d0, 0xb7, 0x9a, 0x0, 0xaa, 0x0, 0x37, 0x67, 0xa7);
public static Guid MEDIASUBTYPE_Line21_GOPPacket = new Guid(0x6e8d4a23, 0x310c, 0x11d0, 0xb7, 0x9a, 0x0, 0xaa, 0x0, 0x37, 0x67, 0xa7);
public static Guid MEDIASUBTYPE_Line21_VBIRawData = new Guid(0x6e8d4a24, 0x310c, 0x11d0, 0xb7, 0x9a, 0x0, 0xaa, 0x0, 0x37, 0x67, 0xa7);
public static Guid MEDIASUBTYPE_TELETEXT = new Guid(0xf72a76e3, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba);
public static Guid MEDIASUBTYPE_WSS = new Guid(0x2791D576, 0x8E7A, 0x466F, 0x9E, 0x90, 0x5D, 0x3F, 0x30, 0x83, 0x73, 0x8B);
public static Guid MEDIASUBTYPE_VPS = new Guid(0xa1b3f620, 0x9792, 0x4d8d, 0x81, 0xa4, 0x86, 0xaf, 0x25, 0x77, 0x20, 0x90);
public static Guid MEDIASUBTYPE_DRM_Audio = new Guid(0x00000009, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_IEEE_FLOAT = new Guid(0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_DOLBY_AC3_SPDIF = new Guid(0x00000092, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_RAW_SPORT = new Guid(0x00000240, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_SPDIF_TAG_241h = new Guid(0x00000241, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
public static Guid MEDIASUBTYPE_DssVideo = new Guid(0xa0af4f81, 0xe163, 0x11d0, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a);
public static Guid MEDIASUBTYPE_DssAudio = new Guid(0xa0af4f82, 0xe163, 0x11d0, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a);
public static Guid MEDIASUBTYPE_VPVideo = new Guid(0x5a9b6a40, 0x1a22, 0x11d1, 0xba, 0xd9, 0x0, 0x60, 0x97, 0x44, 0x11, 0x1a);
}
}
******************************************************************************
3.调用时,FrameGrabber.SaveFrameFromVideo(videoFilePath, Math.Round(d, 4), saveFilePath);
// Math.Round(d,4) 控制进度条位置