首页 > 代码库 > C#写的一个视频转换解码器
C#写的一个视频转换解码器
C#写的一个视频转换解码器
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Drawing; 6 using System.Runtime.InteropServices; 7 using System.Threading; 8 using System.Windows.Forms; 9 using System.IO; 10 11 namespace Basic 12 { 13 public class VideoAPI //视频API类 14 { 15 // 视频API调用 16 [DllImport("avicap32.dll")]//包含了执行视频捕获的函数,它给AVI文件I/O和视频、音频设备驱动程序提供一个高级接口 17 public static extern IntPtr capCreateCaptureWindow(string lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hwndParent, int nID); 18 [DllImport("AVICAP32.dll", CharSet = CharSet.Unicode)] 19 public static extern bool capGetDriverDescription(int wDriverIndex, StringBuilder lpszName, int cbName, StringBuilder lpszVer, int cbVer); 20 [DllImport("avicap32.dll")] 21 public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID); 22 [DllImport("avicap32.dll")] 23 public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer); 24 [DllImport("User32.dll")] 25 public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam); 26 [DllImport("User32.dll")] 27 public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam); 28 [DllImport("User32.dll")] 29 public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam); 30 [DllImport("User32.dll")] 31 public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, FrameEventHandler lParam); 32 [DllImport("User32.dll")] 33 public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam); 34 [DllImport("User32.dll")] 35 public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPDRIVERCAPS lParam); 36 [DllImport("User32.dll")] 37 public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPTUREPARMS lParam); 38 [DllImport("User32.dll")] 39 public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPSTATUS lParam); 40 [DllImport("User32.dll")] 41 public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags); 42 [DllImport("avicap32.dll")] 43 public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize); 44 45 // 常量 46 // public const int WM_USER = 0x400; 47 public const int WS_CHILD = 0x40000000; 48 public const int WS_VISIBLE = 0x10000000; 49 50 public const int SWP_NOMOVE = 0x2; 51 public const int SWP_NOZORDER = 0x4; 52 // public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10; 53 // public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11; 54 public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + 5; 55 // public const int WM_CAP_SET_PREVIEW = WM_USER + 50; 56 // public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52; 57 // public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45; 58 // public const int WM_CAP_START = WM_USER; 59 public const int WM_CAP_SAVEDIB = WM_CAP_START + 25; 60 61 public const string avicap32 = "avicap32.dll"; 62 public const int WM_USER = 1024; 63 /// <summary> 64 ///WM_CAP_START=WM_USER=1024 65 /// </summary> 66 public const int WM_CAP_START = WM_USER; 67 68 // start of unicode messages 69 /// <summary> 70 /// 开始 WM_USER + 100=1124 71 /// </summary> 72 public const int WM_CAP_UNICODE_START = WM_USER + 100; //开始 1124 73 /// <summary> 74 /// /获得 CAPSTR EAMPTR 75 /// WM_CAP_START + 1=1025 76 /// </summary> 77 public const int WM_CAP_GET_CAPSTREAMPTR = (WM_CAP_START + 1); //获得 CAPSTR EAMPTR 78 /// <summary> 79 /// 设置收回错误 WM_CAP_START + 2=1026 80 /// </summary> 81 public const int WM_CAP_SET_CALLBACK_ERROR = (WM_CAP_START + 2); //设置收回错误 82 /// <summary> 83 /// 设置收回状态 WM_CAP_START + 3=1027 84 /// </summary> 85 public const int WM_CAP_SET_CALLBACK_STATUS = (WM_CAP_START + 3); //设置收回状态 86 /// <summary> 87 /// 设置收回出产 WM_CAP_START + 4=1028 88 /// </summary> 89 public const int WM_CAP_SET_CALLBACK_YIELD = (WM_CAP_START + 4); //设置收回出产 90 /// <summary> 91 /// 设置收回结构 WM_CAP_START + 5=1029 92 /// </summary> 93 public const int WM_CAP_SET_CALLBACK_FRame = (WM_CAP_START + 5); //设置收回结构 94 /// <summary> 95 /// 设置收回视频流 WM_CAP_START + 6=1030 96 /// </summary> 97 public const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = (WM_CAP_START + 6); //设置收回视频流 98 /// <summary> 99 /// 设置收回视频波流 WM_CAP_START +7=1031100 /// </summary>101 public const int WM_CAP_SET_CALLBACK_WAVESTREAM = (WM_CAP_START + 7); //设置收回视频波流102 /// <summary>103 /// 获得使用者数据 WM_CAP_START + 8=1032104 /// </summary>105 public const int WM_CAP_GET_USER_DATA = http://www.mamicode.com/(WM_CAP_START + 8); //获得使用者数据106 /// <summary>107 /// 设置使用者数据 WM_CAP_START + 9=1033108 /// </summary>109 public const int WM_CAP_SET_USER_DATA = http://www.mamicode.com/(WM_CAP_START + 9); //设置使用者数据110 /// <summary>111 /// 驱动程序连接 WM_CAP_START + 10=1034112 /// </summary>113 public const int WM_CAP_DRIVER_CONNECT = (WM_CAP_START + 10); //驱动程序连接114 /// <summary>115 /// 断开启动程序连接 WM_CAP_START + 11=1035116 /// </summary>117 public const int WM_CAP_DRIVER_DISCONNECT = (WM_CAP_START + 11); //断开启动程序连接118 /// <summary>119 /// 获得驱动程序名字 WM_CAP_START + 12=1036120 /// </summary>121 public const int WM_CAP_DRIVER_GET_NAME = (WM_CAP_START + 12); //获得驱动程序名字122 /// <summary>123 /// 获得驱动程序版本 WM_CAP_START + 13=1037124 /// </summary>125 public const int WM_CAP_DRIVER_GET_VERSION = (WM_CAP_START + 13); //获得驱动程序版本126 /// <summary>127 /// 获得驱动程序帽子 WM_CAP_START + 14=1038128 /// </summary>129 public const int WM_CAP_DRIVER_GET_CAPS = (WM_CAP_START + 14); //获得驱动程序帽子130 /// <summary>131 /// 设置捕获文件 WM_CAP_START + 20=1044132 /// </summary>133 public const int WM_CAP_FILE_SET_CAPTURE_FILE = (WM_CAP_START + 20); //设置捕获文件134 /// <summary>135 /// 获得捕获文件 WM_CAP_START + 21=1045136 /// </summary>137 public const int WM_CAP_FILE_GET_CAPTURE_FILE = (WM_CAP_START + 21); //获得捕获文件138 /// <summary>139 /// 另存文件为 WM_CAP_START + 23=1047140 /// </summary>141 public const int WM_CAP_FILE_SAVEAS = (WM_CAP_START + 23); //另存文件为142 /// <summary>143 /// 保存文件 WM_CAP_START + 25=1049144 /// </summary>145 public const int WM_CAP_FILE_SAVEDIB = (WM_CAP_START + 25); //保存文件146 147 // out of order to save on ifdefs148 /// <summary>149 /// 分派文件 WM_CAP_START + 22=1044150 /// </summary>151 public const int WM_CAP_FILE_ALLOCATE = (WM_CAP_START + 22); //分派文件152 /// <summary>153 /// 设置开始文件 WM_CAP_START + 24=1046154 /// </summary>155 public const int WM_CAP_FILE_SET_INFOCHUNK = (WM_CAP_START + 24); //设置开始文件156 /// <summary>157 /// 编辑复制 WM_CAP_START + 30=1054158 /// </summary>159 public const int WM_CAP_EDIT_COPY = (WM_CAP_START + 30); //编辑复制160 /// <summary>161 /// 设置音频格式 WM_CAP_START + 35=1059162 /// </summary>163 public const int WM_CAP_SET_AUDIOFORMAT = (WM_CAP_START + 35); //设置音频格式164 /// <summary>165 /// 捕获音频格式 WM_CAP_START + 36=1060166 /// </summary>167 public const int WM_CAP_GET_AUDIOFORMAT = (WM_CAP_START + 36); //捕获音频格式168 /// <summary>169 /// 打开视频格式设置对话框 WM_CAP_START + 41=1065170 /// </summary>171 public const int WM_CAP_DLG_VIDEOFORMAT = (WM_CAP_START + 41); //1065 打开视频格式设置对话框172 /// <summary>173 /// 打开属性设置对话框,设置对比度、亮度等 WM_CAP_START + 42=1066174 /// </summary>175 public const int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START + 42); //1066 打开属性设置对话框,设置对比度、亮度等。176 /// <summary>177 /// 打开视频显示 WM_CAP_START + 43=1067178 /// </summary>179 public const int WM_CAP_DLG_VIDEODISPLAY = (WM_CAP_START + 43); //1067 打开视频显示180 /// <summary>181 /// 获得视频格式 WM_CAP_START + 44=1068182 /// </summary>183 public const int WM_CAP_GET_VIDEOFORMAT = (WM_CAP_START + 44); //1068 获得视频格式184 /// <summary>185 /// 设置视频格式 WM_CAP_START + 45=1069186 /// </summary>187 public const int WM_CAP_SET_VIDEOFORMAT = (WM_CAP_START + 45); //1069 设置视频格式188 /// <summary>189 /// 打开压缩设置对话框 WM_CAP_START + 46=1070190 /// </summary>191 public const int WM_CAP_DLG_VIDEOCOMPRESSION = (WM_CAP_START + 46); //1070 打开压缩设置对话框192 /// <summary>193 /// 设置预览 WM_CAP_START + 50=1074194 /// </summary>195 public const int WM_CAP_SET_PREVIEW = (WM_CAP_START + 50); //设置预览196 /// <summary>197 /// 设置覆盖 WM_CAP_START + 51=1075198 /// </summary>199 public const int WM_CAP_SET_OVERLAY = (WM_CAP_START + 51); //设置覆盖200 /// <summary>201 /// 设置预览比例 WM_CAP_START + 52=1076202 /// </summary>203 public const int WM_CAP_SET_PREVIEWRATE = (WM_CAP_START + 52); //设置预览比例204 /// <summary>205 /// 设置刻度 WM_CAP_START + 53=1077206 /// </summary>207 public const int WM_CAP_SET_SCALE = (WM_CAP_START + 53); //设置刻度208 /// <summary> 209 /// 获得状态 WM_CAP_START + 54=1078210 /// </summary>211 public const int WM_CAP_GET_STATUS = (WM_CAP_START + 54); //获得状态212 /// <summary>213 /// 设置卷 WM_CAP_START + 55=1079214 /// </summary>215 public const int WM_CAP_SET_SCROLL = (WM_CAP_START + 55); //设置卷216 /// <summary>217 /// 逮捕结构 WM_CAP_START + 60=1084218 /// </summary>219 public const int WM_CAP_GRAB_FRame = (WM_CAP_START + 60); //逮捕结构220 /// <summary>221 /// 停止逮捕结构 WM_CAP_START + 61=1085222 /// </summary>223 public const int WM_CAP_GRAB_FRame_NOSTOP = (WM_CAP_START + 61); //停止逮捕结构224 /// <summary>225 /// 次序 WM_CAP_START + 62=1086226 /// </summary>227 public const int WM_CAP_SEQUENCE = (WM_CAP_START + 62); //次序228 /// <summary>229 /// 没有文件 WM_CAP_START + 63=1087230 /// </summary>231 public const int WM_CAP_SEQUENCE_NOFILE = (WM_CAP_START + 63); //没有文件232 /// <summary>233 /// 设置安装次序 WM_CAP_START + 64=1088234 /// </summary>235 public const int WM_CAP_SET_SEQUENCE_SETUP = (WM_CAP_START + 64); //设置安装次序236 /// <summary>237 /// 获得安装次序 WM_CAP_START + 65=1089238 /// </summary>239 public const int WM_CAP_GET_SEQUENCE_SETUP = (WM_CAP_START + 65); //获得安装次序240 /// <summary>241 /// 设置媒体控制接口 WM_CAP_START + 66=1090242 /// </summary>243 public const int WM_CAP_SET_MCI_DEVICE = (WM_CAP_START + 66); //设置媒体控制接口244 /// <summary>245 /// 获得媒体控制接口 WM_CAP_START + 67=1091246 /// </summary>247 public const int WM_CAP_GET_MCI_DEVICE = (WM_CAP_START + 67); //获得媒体控制接口 248 /// <summary>249 /// 停止 WM_CAP_START + 68=1092250 /// </summary>251 public const int WM_CAP_STOP = (WM_CAP_START + 68); //停止252 /// <summary>253 /// 异常中断 WM_CAP_START + 69=1093254 /// </summary>255 public const int WM_CAP_ABORT = (WM_CAP_START + 69); //异常中断256 /// <summary>257 /// 打开单一的结构 WM_CAP_START + 68=1094258 /// </summary>259 public const int WM_CAP_SINGLE_FRame_OPEN = (WM_CAP_START + 70); //打开单一的结构260 /// <summary>261 /// 关闭单一的结构 WM_CAP_START + 71=1095262 /// </summary>263 public const int WM_CAP_SINGLE_FRame_CLOSE = (WM_CAP_START + 71); //关闭单一的结构264 /// <summary>265 /// 单一的结构 WM_CAP_START + 72=1096266 /// </summary>267 public const int WM_CAP_SINGLE_FRame = (WM_CAP_START + 72); //单一的结构268 /// <summary>269 /// 打开视频 WM_CAP_START + 80=1104270 /// </summary>271 public const int WM_CAP_PAL_OPEN = (WM_CAP_START + 80); //打开视频272 /// <summary>273 /// 保存视频 WM_CAP_START + 81=1105274 /// </summary>275 public const int WM_CAP_PAL_SAVE = (WM_CAP_START + 81); //保存视频276 /// <summary>277 /// 粘贴视频 WM_CAP_START + 82=1106278 /// </summary>279 public const int WM_CAP_PAL_PASTE = (WM_CAP_START + 82); //粘贴视频280 /// <summary>281 /// 自动创造 WM_CAP_START + 83=1107282 /// </summary>283 public const int WM_CAP_PAL_AUTOCREATE = (WM_CAP_START + 83); //自动创造284 /// <summary>285 /// 手动创造 WM_CAP_START + 84=1108286 /// </summary>287 public const int WM_CAP_PAL_MANUALCREATE = (WM_CAP_START + 84); //手动创造288 289 // Following added post VFW 1.1290 /// <summary>291 /// 设置收回的错误 WM_CAP_START + 85=1109292 /// </summary>293 public const int WM_CAP_SET_CALLBACK_CAPCONTROL = (WM_CAP_START + 85); // 设置收回的错误294 295 public const int WM_CAP_END = WM_CAP_SET_CALLBACK_CAPCONTROL;296 297 public delegate void FrameEventHandler(IntPtr lwnd, IntPtr lpVHdr);298 299 #region 公共函数300 //公共函数301 public static object GetStructure(IntPtr ptr, ValueType structure)302 {303 return Marshal.PtrToStructure(ptr, structure.GetType());304 }305 306 public static object GetStructure(int ptr, ValueType structure)307 {308 return GetStructure(new IntPtr(ptr), structure);309 }310 311 public static void Copy(IntPtr ptr, byte[] data)312 {313 Marshal.Copy(ptr, data, 0, data.Length);314 }315 316 public static void Copy(int ptr, byte[] data)317 {318 Copy(new IntPtr(ptr), data);319 }320 321 public static int SizeOf(object structure)322 {323 return Marshal.SizeOf(structure);324 }325 #endregion 公共函数326 #region 结构 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS327 //========================================================VideoHdr 结构=====================================================================328 //VideoHdr 结构 定义了视频数据块的头信息,在编写回调函数时常用到其数据成员lpData(指向数据缓存的指针)和dwBufferLength(数据缓存的大小)。 329 //视频帧到缓存的捕获则需要应用回调函数和相应的数据块结构 VIDEOHDR 330 [StructLayout(LayoutKind.Sequential)]331 public struct VIDEOHDR332 {333 public IntPtr lpData; /* 指向数据缓存的指针 */334 public int dwBufferLength; /* 数据缓存的大小 */335 public int dwBytesUsed; /* Bytes actually used */336 public int dwTimeCaptured; /* Milliseconds from start of stream */337 public int dwUser; /* for client‘s use */338 public int dwFlags; /* assorted flags (see defines) */339 public int dwReserved; /* reserved for driver */340 }341 //=======================================================BitmapInfoHeader结构===================================================================342 //BitmapInfoHeader定义了位图的头部信息343 [StructLayout(LayoutKind.Sequential)]344 public struct BITMAPINFOHEADER345 {346 public int biSize;347 public int biWidth;348 public int biHeight;349 public short biPlanes;350 public short biBitCount;351 public int biCompression;352 public int biSizeImage;353 public int biXPelsPerMeter;354 public int biYPelsPerMeter;355 public int biClrUsed;356 public int biClrImportant;357 }358 //=========================================================================================================================================359 360 //======================================================BitmapInfo结构=====================================================================361 //BitmapInfo 位图信息362 [StructLayout(LayoutKind.Sequential)]363 public struct BITMAPINFO364 {365 public BITMAPINFOHEADER bmiHeader;366 public int bmiColors;367 }368 369 //=====================================================CAPTUREPARMS结构======================================================================370 //CAPTUREPARMS 包含控制视频流捕获过程的参数,如捕获帧频、指定键盘或鼠标键以终止捕获、捕获时间限制等; 371 [StructLayout(LayoutKind.Sequential)]372 public struct CAPTUREPARMS373 {374 public int dwRequestMicroSecPerFrame; // 期望的桢播放率,以毫秒为单位,默认为66667,相当于15桢每秒。375 public bool fMakeUserHitOKToCapture; // Show "Hit OK to cap" dlg?开始捕获标志位,如果值为真,则在开始捕获前要产生一个询问对话框,默认为假。376 public uint wPercentDropForError; //所允许的最大丢桢百分比,可以从0变化到100,默认值为10。377 public bool fYield; /*另起线程标志位,如果为真,则程序重新启动一个线程用于视频流的捕获,默认值是假。378 但是如果你是为了真,你必须要在程序中处理一些潜在的操作,因为当视频捕获时,其他操作并没有被屏蔽。*/379 public int dwIndexSize; // 在AVI文件中所允许的最大数目的索引项(32K)380 public uint wChunkGranularity; // AVI文件的逻辑尺寸,以字节为单位。如果值是0,则说明该尺寸渐增 在 Win32程序中无用。(2K)381 public bool fUsingDOSMemory; // Use DOS buffers?382 public uint wNumVideoRequested; // 所被允许分配的最大视频缓存383 public bool fCaptureAudio; // 音频标志位,如果音频流正在捕获,则该值为真。384 public uint wNumAudioRequested; // 最大数量的音频缓存,默认值为10。385 public uint vKeyAbort; // 终止流捕获的虚拟键盘码,默认值为VK_ESCAPE386 [MarshalAs(UnmanagedType.Bool)]387 public bool fAbortLeftMouse; // 终止鼠标左键标志位,如果该值为真,则在流捕获过程中如果点击鼠标左键则该捕获终止,默认值为真。388 public bool fAbortRightMouse; // Abort on right mouse?389 public bool fLimitEnabled; // 捕获操作时间限制,如果为真,则时间到了以后捕获操作终止,默认为假390 public uint wTimeLimit; // 具体终止时间,只有 fLimitEnabled是真时.该位才有效391 public bool fMCIControl; // Use MCI video source?392 public bool fStepMCIDevice; // Step MCI device?MCI 设备标志。393 public int dwMCIStartTime; // Time to start in MS394 public int dwMCIStopTime; // Time to stop in MS395 public bool fStepCaptureAt2x; // Perform spatial averaging 2x396 public int wStepCaptureAverageFrames; // 当基于平均采样来创建桢时,桢的采样时间,典型值是5397 public int dwAudioBufferSize; // 音频缓存的尺寸,如果用默认值0,缓存尺寸是最大0.5秒,或10k字节。398 public int fDisableWriteCache; // Attempt to disable write cache399 public int AVStreamMaster; //音视频同步标志。400 }401 //=========================================================================================================================================402 403 //=================================================CAPDRIVERCAPS结构=======================================================================404 //CAPDRIVERCAPS定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等; 405 [StructLayout(LayoutKind.Sequential)]406 public struct CAPDRIVERCAPS407 {408 [MarshalAs(UnmanagedType.U2)]409 public UInt16 wDeviceIndex; //捕获驱动器的索引值,该值可以由0到9变化。410 [MarshalAs(UnmanagedType.Bool)]411 public bool fHasOverlay; // 视频叠加标志,如果设备支持视频叠加这该位是真。412 [MarshalAs(UnmanagedType.Bool)]413 public bool fHasDlgVideoSource; //视频资源对话框标志位,如果设备支持视频选择、控制对话框,该值为真。414 [MarshalAs(UnmanagedType.Bool)]415 public bool fHasDlgVideoFormat; //视频格式对话框标志位,如果设备支持对视频格式对话框的选择,该位真。416 [MarshalAs(UnmanagedType.Bool)]417 public bool fHasDlgVideoDisplay; //视频展示对话框标志位,如果设备支持对视频捕获缓存区的重新播放,该位是真。418 [MarshalAs(UnmanagedType.Bool)]419 public bool fCaptureInitialized; //捕获安装标志位,如果捕获驱动器已经成功连接,该值为真。420 //[MarshalAs(UnmanagedType.Bool)]421 public bool fDriverSuppliesPalettes; //驱动器调色板标志位,如果驱动器能创建调色板,则该位是真。422 [MarshalAs(UnmanagedType.I4)]423 public int hVideoIn;424 [MarshalAs(UnmanagedType.I4)]425 public int hVideoOut;426 [MarshalAs(UnmanagedType.I4)]427 public int hVideoExtIn;428 [MarshalAs(UnmanagedType.I4)]429 public int hVideoExtOut;430 }431 //=========================================================================================================================================432 433 434 //=====================================================CAPSTATUS结构========================================================================435 //CAPSTATUS定义了捕获窗口的当前状态,如图像的宽、高等;436 [StructLayout(LayoutKind.Sequential)]437 public struct CAPSTATUS438 {439 public int uiImageWidth; //图像宽度440 public int uiImageHeight; //图像高度441 public bool fLiveWindow; //活动窗口标记,如果窗口正以预览的方式展示图像,那么该值为真442 public bool fOverlayWindow; //叠加窗口标志位,如果正在使用硬件叠加,则该位是真。443 public bool fScale; //输入所放标志位,如果窗口是正在缩放视频到客户区,那么该位是真。当使用硬件叠加时,改位无效。444 public Point ptScroll; //被展示在窗口客户区左上角的那个象素的x、y坐标偏移量。445 public bool fUsingDefaultPalette; //默认调色板标志位,如果捕获窗口正在使用当前默认调色板,该值为真446 public bool fAudioHardware; // 音频硬件标志位,如果系统已经安装了音频硬件,该值为真。447 public bool fCapFileExists; //捕获文件标志位,如果一个捕获文件已经被创建,该值为真448 public int dwCurrentVideoFrame; // 当前或最近流捕获过程中,所处理的桢的数目。包括丢弃的桢。449 public int dwCurrentVideoFramesDropped;//当前流捕获过程中丢弃的桢的数目。450 public int dwCurrentWaveSamples; // # of wave samples cap‘td451 public int dwCurrentTimeElapsedMS; // 从当前流捕获开始计算,程序所用的时间,以毫秒为单位。452 public IntPtr hPalCurrent; // 当前剪切板的句柄。453 public bool fCapturingNow; // 捕获标志位,当捕获是正在进行时,改位是真454 public int dwReturn; // 错误返回值,当你的应用程序不支持错误回调函数时可以应用改位455 public int wNumVideoAllocated; // 被分配的视频缓存的数目。456 public int wNumAudioAllocated; // 被分配的音频缓存的数目。457 }458 //=========================================================================================================================================459 460 461 #endregion 结构 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS462 463 }464 public class cVideo //视频类465 {466 public bool flag = true;467 private IntPtr lwndC; //保存无符号句柄468 private IntPtr mControlPtr; //保存管理指示器469 private int mWidth;470 private int mHeight;471 public delegate void RecievedFrameEventHandler(byte[] data);472 public event RecievedFrameEventHandler RecievedFrame;473 474 public VideoAPI.CAPTUREPARMS Capparms;475 private VideoAPI.FrameEventHandler mFrameEventHandler;476 public VideoAPI.CAPDRIVERCAPS CapDriverCAPS;//捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;477 public VideoAPI.CAPSTATUS CapStatus;//该结构用于保存视频设备捕获窗口的当前状态,如图像的宽、高等478 string strFileName;479 public cVideo(IntPtr handle, int width, int height)480 {481 CapDriverCAPS = new VideoAPI.CAPDRIVERCAPS();//捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;482 CapStatus = new VideoAPI.CAPSTATUS();//该结构用于保存视频设备捕获窗口的当前状态,如图像的宽、高等483 mControlPtr = handle; //显示视频控件的句柄484 mWidth = width; //视频宽度485 mHeight = height; //视频高度486 }487 public bool StartWebCam()488 {489 return StartWebCam(mWidth, mHeight);490 }491 /// <summary>492 /// 打开视频设备493 /// </summary>494 /// <param name="width">捕获窗口的宽度</param>495 /// <param name="height">捕获窗口的高度</param>496 /// <returns></returns>497 public bool StartWebCam(int width,int height)498 {499 //byte[] lpszName = new byte[100];500 //byte[] lpszVer = new byte[100];501 //VideoAPI.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);502 //this.lwndC = VideoAPI.capCreateCaptureWindowA(lpszName, VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);503 //if (VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))504 //{505 // VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 100, 0);506 // VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEW, true, 0);507 // return true;508 //}509 //else510 //{511 // return false;512 //}513 this.lwndC = VideoAPI.capCreateCaptureWindow("", VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);//AVICap类的捕捉窗口514 VideoAPI.FrameEventHandler FrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);515 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, 0, 0);//注册错误回调函数516 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUS, 0, 0);//注册状态回调函数 517 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);//注册视频流回调函数518 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, FrameEventHandler);//注册帧回调函数519 520 //if (!CapDriverCAPS.fCaptureInitialized)//判断当前设备是否被其他设备连接已经连接521 //{522 523 if (VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))524 {525 //-----------------------------------------------------------------------526 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_GET_CAPS, VideoAPI.SizeOf(CapDriverCAPS), ref CapDriverCAPS);//获得当前视频 CAPDRIVERCAPS定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;527 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_STATUS, VideoAPI.SizeOf(CapStatus), ref CapStatus);//获得当前视频流的尺寸 存入CapStatus结构528 529 VideoAPI.BITMAPINFO bitmapInfo = new VideoAPI.BITMAPINFO();//设置视频格式 (height and width in pixels, bits per frame). 530 bitmapInfo.bmiHeader = new VideoAPI.BITMAPINFOHEADER();531 bitmapInfo.bmiHeader.biSize = VideoAPI.SizeOf(bitmapInfo.bmiHeader);532 bitmapInfo.bmiHeader.biWidth = mWidth;533 bitmapInfo.bmiHeader.biHeight = mHeight;534 bitmapInfo.bmiHeader.biPlanes = 1;535 bitmapInfo.bmiHeader.biBitCount = 24;536 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 40, 0);//设置在PREVIEW模式下设定视频窗口的刷新率 设置每40毫秒显示一帧,即显示帧速为每秒25帧537 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SCALE, 1, 0);//打开预览视频的缩放比例538 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_VIDEOFORMAT, VideoAPI.SizeOf(bitmapInfo), ref bitmapInfo);539 540 this.mFrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);541 this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler);542 543 544 VideoAPI.CAPTUREPARMS captureparms = new VideoAPI.CAPTUREPARMS();545 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(captureparms), ref captureparms);546 if (CapDriverCAPS.fHasOverlay)547 {548 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_OVERLAY, 1, 0);//启用叠加 注:据说启用此项可以加快渲染速度 549 }550 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEW, 1, 0);//设置显示图像启动预览模式 PREVIEW551 VideoAPI.SetWindowPos(this.lwndC, 0, 0, 0, width, height, VideoAPI.SWP_NOZORDER | VideoAPI.SWP_NOMOVE);//使捕获窗口与进来的视频流尺寸保持一致552 return true;553 }554 else555 { 556 557 flag = false;558 return false;559 }560 }561 public bool ReSizePic(int width, int height)562 {563 try564 {565 // CloseWebcam();566 // StartWebCam();567 // this.lwndC = VideoAPI.capCreateCaptureWindow("", VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);568 569 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_STATUS, VideoAPI.SizeOf(CapStatus), ref CapStatus);//获得当前视频流的尺寸 存入CapStatus结构570 // VideoAPI.FrameEventHandler FrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);571 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, 0, 0);//注册错误回调函数572 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUS, 0, 0);//注册状态回调函数 573 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);//注册视频流回调函数574 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, FrameEventHandler);//注册帧回调函数575 //// if (VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))576 // {577 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SCALE, 1, 0);578 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 40, 0);579 // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEW, 1, 0);580 581 return VideoAPI.SetWindowPos(this.lwndC, 0, 0, 0, width, height, VideoAPI.SWP_NOZORDER | VideoAPI.SWP_NOMOVE) > 0;582 // }583 // return false;584 }585 catch586 {587 return false;588 }589 }590 public void get()591 {592 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);593 }594 public void set()595 {596 VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);597 }598 private bool capSetCallbackOnFrame(IntPtr lwnd, VideoAPI.FrameEventHandler lpProc)599 {600 return VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, lpProc);601 }602 /// <summary>603 /// 关闭视频设备604 /// </summary>605 public void CloseWebcam()606 {607 VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_DISCONNECT, 0, 0);608 }609 /// <summary> 610 /// 拍照611 /// </summary> 612 /// <param name="path">要保存bmp文件的路径</param> 613 public void GrabImage(IntPtr hWndC, string path)614 {615 IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);616 VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SAVEDIB, 0, hBmp.ToInt32());617 }618 public bool StarKinescope(string path)619 {620 try621 {622 strFileName = path;623 string dir = path.Remove(path.LastIndexOf("\\"));624 if (!File.Exists(dir))625 {626 Directory.CreateDirectory(dir);627 }628 int hBmp = Marshal.StringToHGlobalAnsi(path).ToInt32();629 bool b = VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_FILE_SET_CAPTURE_FILE, 0, hBmp);630 b = b && VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SEQUENCE, 0, 0);631 return b;632 }633 catch634 {635 return false;636 }637 }638 /// <summary>639 /// 停止录像640 /// </summary>641 public bool StopKinescope()642 {643 return VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_STOP, 0, 0);644 }645 private void FrameCallback(IntPtr lwnd, IntPtr lpvhdr)646 {647 VideoAPI.VIDEOHDR videoHeader = new VideoAPI.VIDEOHDR();648 byte[] VideoData;649 videoHeader = (VideoAPI.VIDEOHDR)VideoAPI.GetStructure(lpvhdr, videoHeader);650 VideoData = http://www.mamicode.com/new byte[videoHeader.dwBytesUsed];651 VideoAPI.Copy(videoHeader.lpData, VideoData);652 if (this.RecievedFrame != null)653 this.RecievedFrame(VideoData);654 }655 private Thread myThread;656 657 public void CompressVideoFfmpeg()658 {659 myThread = new Thread(new ThreadStart(testfn));660 myThread.Start();661 testfn();662 }663 private void testfn()664 {665 string file_name = strFileName;666 string command_line = " -i " + file_name + " -vcodec libx264 -cqp 25 -y " + file_name.Replace(".avi", "_264") + ".avi";667 System.Diagnostics.Process proc = new System.Diagnostics.Process();668 proc.StartInfo.WorkingDirectory = Application.StartupPath;669 proc.StartInfo.UseShellExecute = false; //use false if you want to hide the window670 proc.StartInfo.CreateNoWindow = true;671 proc.StartInfo.FileName = "ffmpeg";672 proc.StartInfo.Arguments = command_line;673 proc.Start();674 proc.WaitForExit();675 proc.Close();676 Common.writeLog("视频"+strFileName+"压缩完毕");677 // 删除原始avi文件678 FileInfo file = new FileInfo(file_name);679 if (file.Exists)680 {681 try682 {683 file.Delete(); //删除单个文件684 }685 catch (Exception e)686 {687 // Common.writeLog("删除视频文件“" + file_name + "”出错!准备" );688 689 (new Thread(() =>690 {691 bool b = false;692 for (int i = 0; i < 5; i++)693 {694 Thread.Sleep(10000*(i*i));695 try696 {697 file.Delete();698 b = true;699 break;700 }701 catch702 {703 }704 };705 if (!b)706 Common.writeLog("删除视频文件“" + file_name + "”出错");707 }708 )).Start();709 }710 }711 //myThread.Abort();712 }713 }714 }
C#写的一个视频转换解码器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。