C#写的一个视频转换解码器
生活随笔
收集整理的這篇文章主要介紹了
C#写的一个视频转换解码器
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
C#寫的一個視頻轉(zhuǎn)換解碼器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using System.IO; namespace Basic
{
public class VideoAPI //視頻API類
{
// 視頻API調(diào)用
[DllImport("avicap32.dll")]//包含了執(zhí)行視頻捕獲的函數(shù),它給AVI文件I/O和視頻、音頻設備驅(qū)動程序提供一個高級接口
public static extern IntPtr capCreateCaptureWindow(string lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hwndParent, int nID);
[DllImport("AVICAP32.dll", CharSet = CharSet.Unicode)]
public static extern bool capGetDriverDescription(int wDriverIndex, StringBuilder lpszName, int cbName, StringBuilder lpszVer, int cbVer);
[DllImport("avicap32.dll")]
public static extern IntPtr capCreateCaptureWindowA(byte[] lpszWindowName, int dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, int nID);
[DllImport("avicap32.dll")]
public static extern bool capGetDriverDescriptionA(short wDriver, byte[] lpszName, int cbName, byte[] lpszVer, int cbVer);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, bool wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, short wParam, FrameEventHandler lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref BITMAPINFO lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPDRIVERCAPS lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPTUREPARMS lParam);
[DllImport("User32.dll")]
public static extern bool SendMessage(IntPtr hWnd, int wMsg, int wParam, ref CAPSTATUS lParam);
[DllImport("User32.dll")]
public static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, int wFlags);
[DllImport("avicap32.dll")]
public static extern int capGetVideoFormat(IntPtr hWnd, IntPtr psVideoFormat, int wSize); // 常量
// public const int WM_USER = 0x400;
public const int WS_CHILD = 0x40000000;
public const int WS_VISIBLE = 0x10000000; public const int SWP_NOMOVE = 0x2;
public const int SWP_NOZORDER = 0x4;
// public const int WM_CAP_DRIVER_CONNECT = WM_USER + 10;
// public const int WM_CAP_DRIVER_DISCONNECT = WM_USER + 11;
public const int WM_CAP_SET_CALLBACK_FRAME = WM_USER + ;
// public const int WM_CAP_SET_PREVIEW = WM_USER + 50;
// public const int WM_CAP_SET_PREVIEWRATE = WM_USER + 52;
// public const int WM_CAP_SET_VIDEOFORMAT = WM_USER + 45;
// public const int WM_CAP_START = WM_USER;
public const int WM_CAP_SAVEDIB = WM_CAP_START + ; public const string avicap32 = "avicap32.dll";
public const int WM_USER = ;
/// <summary>
///WM_CAP_START=WM_USER=1024
/// </summary>
public const int WM_CAP_START = WM_USER; // start of unicode messages
/// <summary>
/// 開始 WM_USER + 100=1124
/// </summary>
public const int WM_CAP_UNICODE_START = WM_USER + ; //開始 1124
/// <summary>
/// /獲得 CAPSTR EAMPTR
/// WM_CAP_START + 1=1025
/// </summary>
public const int WM_CAP_GET_CAPSTREAMPTR = (WM_CAP_START + ); //獲得 CAPSTR EAMPTR
/// <summary>
/// 設置收回錯誤 WM_CAP_START + 2=1026
/// </summary>
public const int WM_CAP_SET_CALLBACK_ERROR = (WM_CAP_START + ); //設置收回錯誤
/// <summary>
/// 設置收回狀態(tài) WM_CAP_START + 3=1027
/// </summary>
public const int WM_CAP_SET_CALLBACK_STATUS = (WM_CAP_START + ); //設置收回狀態(tài)
/// <summary>
/// 設置收回出產(chǎn) WM_CAP_START + 4=1028
/// </summary>
public const int WM_CAP_SET_CALLBACK_YIELD = (WM_CAP_START + ); //設置收回出產(chǎn)
/// <summary>
/// 設置收回結構 WM_CAP_START + 5=1029
/// </summary>
public const int WM_CAP_SET_CALLBACK_FRame = (WM_CAP_START + ); //設置收回結構
/// <summary>
/// 設置收回視頻流 WM_CAP_START + 6=1030
/// </summary>
public const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = (WM_CAP_START + ); //設置收回視頻流
/// <summary>
/// 設置收回視頻波流 WM_CAP_START +7=1031
/// </summary>
public const int WM_CAP_SET_CALLBACK_WAVESTREAM = (WM_CAP_START + ); //設置收回視頻波流
/// <summary>
/// 獲得使用者數(shù)據(jù) WM_CAP_START + 8=1032
/// </summary>
public const int WM_CAP_GET_USER_DATA = (WM_CAP_START + ); //獲得使用者數(shù)據(jù)
/// <summary>
/// 設置使用者數(shù)據(jù) WM_CAP_START + 9=1033
/// </summary>
public const int WM_CAP_SET_USER_DATA = (WM_CAP_START + ); //設置使用者數(shù)據(jù)
/// <summary>
/// 驅(qū)動程序連接 WM_CAP_START + 10=1034
/// </summary>
public const int WM_CAP_DRIVER_CONNECT = (WM_CAP_START + ); //驅(qū)動程序連接
/// <summary>
/// 斷開啟動程序連接 WM_CAP_START + 11=1035
/// </summary>
public const int WM_CAP_DRIVER_DISCONNECT = (WM_CAP_START + ); //斷開啟動程序連接
/// <summary>
/// 獲得驅(qū)動程序名字 WM_CAP_START + 12=1036
/// </summary>
public const int WM_CAP_DRIVER_GET_NAME = (WM_CAP_START + ); //獲得驅(qū)動程序名字
/// <summary>
/// 獲得驅(qū)動程序版本 WM_CAP_START + 13=1037
/// </summary>
public const int WM_CAP_DRIVER_GET_VERSION = (WM_CAP_START + ); //獲得驅(qū)動程序版本
/// <summary>
/// 獲得驅(qū)動程序帽子 WM_CAP_START + 14=1038
/// </summary>
public const int WM_CAP_DRIVER_GET_CAPS = (WM_CAP_START + ); //獲得驅(qū)動程序帽子
/// <summary>
/// 設置捕獲文件 WM_CAP_START + 20=1044
/// </summary>
public const int WM_CAP_FILE_SET_CAPTURE_FILE = (WM_CAP_START + ); //設置捕獲文件
/// <summary>
/// 獲得捕獲文件 WM_CAP_START + 21=1045
/// </summary>
public const int WM_CAP_FILE_GET_CAPTURE_FILE = (WM_CAP_START + ); //獲得捕獲文件
/// <summary>
/// 另存文件為 WM_CAP_START + 23=1047
/// </summary>
public const int WM_CAP_FILE_SAVEAS = (WM_CAP_START + ); //另存文件為
/// <summary>
/// 保存文件 WM_CAP_START + 25=1049
/// </summary>
public const int WM_CAP_FILE_SAVEDIB = (WM_CAP_START + ); //保存文件 // out of order to save on ifdefs
/// <summary>
/// 分派文件 WM_CAP_START + 22=1044
/// </summary>
public const int WM_CAP_FILE_ALLOCATE = (WM_CAP_START + ); //分派文件
/// <summary>
/// 設置開始文件 WM_CAP_START + 24=1046
/// </summary>
public const int WM_CAP_FILE_SET_INFOCHUNK = (WM_CAP_START + ); //設置開始文件
/// <summary>
/// 編輯復制 WM_CAP_START + 30=1054
/// </summary>
public const int WM_CAP_EDIT_COPY = (WM_CAP_START + ); //編輯復制
/// <summary>
/// 設置音頻格式 WM_CAP_START + 35=1059
/// </summary>
public const int WM_CAP_SET_AUDIOFORMAT = (WM_CAP_START + ); //設置音頻格式
/// <summary>
/// 捕獲音頻格式 WM_CAP_START + 36=1060
/// </summary>
public const int WM_CAP_GET_AUDIOFORMAT = (WM_CAP_START + ); //捕獲音頻格式
/// <summary>
/// 打開視頻格式設置對話框 WM_CAP_START + 41=1065
/// </summary>
public const int WM_CAP_DLG_VIDEOFORMAT = (WM_CAP_START + ); //1065 打開視頻格式設置對話框
/// <summary>
/// 打開屬性設置對話框,設置對比度、亮度等 WM_CAP_START + 42=1066
/// </summary>
public const int WM_CAP_DLG_VIDEOSOURCE = (WM_CAP_START + ); //1066 打開屬性設置對話框,設置對比度、亮度等。
/// <summary>
/// 打開視頻顯示 WM_CAP_START + 43=1067
/// </summary>
public const int WM_CAP_DLG_VIDEODISPLAY = (WM_CAP_START + ); //1067 打開視頻顯示
/// <summary>
/// 獲得視頻格式 WM_CAP_START + 44=1068
/// </summary>
public const int WM_CAP_GET_VIDEOFORMAT = (WM_CAP_START + ); //1068 獲得視頻格式
/// <summary>
/// 設置視頻格式 WM_CAP_START + 45=1069
/// </summary>
public const int WM_CAP_SET_VIDEOFORMAT = (WM_CAP_START + ); //1069 設置視頻格式
/// <summary>
/// 打開壓縮設置對話框 WM_CAP_START + 46=1070
/// </summary>
public const int WM_CAP_DLG_VIDEOCOMPRESSION = (WM_CAP_START + ); //1070 打開壓縮設置對話框
/// <summary>
/// 設置預覽 WM_CAP_START + 50=1074
/// </summary>
public const int WM_CAP_SET_PREVIEW = (WM_CAP_START + ); //設置預覽
/// <summary>
/// 設置覆蓋 WM_CAP_START + 51=1075
/// </summary>
public const int WM_CAP_SET_OVERLAY = (WM_CAP_START + ); //設置覆蓋
/// <summary>
/// 設置預覽比例 WM_CAP_START + 52=1076
/// </summary>
public const int WM_CAP_SET_PREVIEWRATE = (WM_CAP_START + ); //設置預覽比例
/// <summary>
/// 設置刻度 WM_CAP_START + 53=1077
/// </summary>
public const int WM_CAP_SET_SCALE = (WM_CAP_START + ); //設置刻度
/// <summary>
/// 獲得狀態(tài) WM_CAP_START + 54=1078
/// </summary>
public const int WM_CAP_GET_STATUS = (WM_CAP_START + ); //獲得狀態(tài)
/// <summary>
/// 設置卷 WM_CAP_START + 55=1079
/// </summary>
public const int WM_CAP_SET_SCROLL = (WM_CAP_START + ); //設置卷
/// <summary>
/// 逮捕結構 WM_CAP_START + 60=1084
/// </summary>
public const int WM_CAP_GRAB_FRame = (WM_CAP_START + ); //逮捕結構
/// <summary>
/// 停止逮捕結構 WM_CAP_START + 61=1085
/// </summary>
public const int WM_CAP_GRAB_FRame_NOSTOP = (WM_CAP_START + ); //停止逮捕結構
/// <summary>
/// 次序 WM_CAP_START + 62=1086
/// </summary>
public const int WM_CAP_SEQUENCE = (WM_CAP_START + ); //次序
/// <summary>
/// 沒有文件 WM_CAP_START + 63=1087
/// </summary>
public const int WM_CAP_SEQUENCE_NOFILE = (WM_CAP_START + ); //沒有文件
/// <summary>
/// 設置安裝次序 WM_CAP_START + 64=1088
/// </summary>
public const int WM_CAP_SET_SEQUENCE_SETUP = (WM_CAP_START + ); //設置安裝次序
/// <summary>
/// 獲得安裝次序 WM_CAP_START + 65=1089
/// </summary>
public const int WM_CAP_GET_SEQUENCE_SETUP = (WM_CAP_START + ); //獲得安裝次序
/// <summary>
/// 設置媒體控制接口 WM_CAP_START + 66=1090
/// </summary>
public const int WM_CAP_SET_MCI_DEVICE = (WM_CAP_START + ); //設置媒體控制接口
/// <summary>
/// 獲得媒體控制接口 WM_CAP_START + 67=1091
/// </summary>
public const int WM_CAP_GET_MCI_DEVICE = (WM_CAP_START + ); //獲得媒體控制接口
/// <summary>
/// 停止 WM_CAP_START + 68=1092
/// </summary>
public const int WM_CAP_STOP = (WM_CAP_START + ); //停止
/// <summary>
/// 異常中斷 WM_CAP_START + 69=1093
/// </summary>
public const int WM_CAP_ABORT = (WM_CAP_START + ); //異常中斷
/// <summary>
/// 打開單一的結構 WM_CAP_START + 68=1094
/// </summary>
public const int WM_CAP_SINGLE_FRame_OPEN = (WM_CAP_START + ); //打開單一的結構
/// <summary>
/// 關閉單一的結構 WM_CAP_START + 71=1095
/// </summary>
public const int WM_CAP_SINGLE_FRame_CLOSE = (WM_CAP_START + ); //關閉單一的結構
/// <summary>
/// 單一的結構 WM_CAP_START + 72=1096
/// </summary>
public const int WM_CAP_SINGLE_FRame = (WM_CAP_START + ); //單一的結構
/// <summary>
/// 打開視頻 WM_CAP_START + 80=1104
/// </summary>
public const int WM_CAP_PAL_OPEN = (WM_CAP_START + ); //打開視頻
/// <summary>
/// 保存視頻 WM_CAP_START + 81=1105
/// </summary>
public const int WM_CAP_PAL_SAVE = (WM_CAP_START + ); //保存視頻
/// <summary>
/// 粘貼視頻 WM_CAP_START + 82=1106
/// </summary>
public const int WM_CAP_PAL_PASTE = (WM_CAP_START + ); //粘貼視頻
/// <summary>
/// 自動創(chuàng)造 WM_CAP_START + 83=1107
/// </summary>
public const int WM_CAP_PAL_AUTOCREATE = (WM_CAP_START + ); //自動創(chuàng)造
/// <summary>
/// 手動創(chuàng)造 WM_CAP_START + 84=1108
/// </summary>
public const int WM_CAP_PAL_MANUALCREATE = (WM_CAP_START + ); //手動創(chuàng)造 // Following added post VFW 1.1
/// <summary>
/// 設置收回的錯誤 WM_CAP_START + 85=1109
/// </summary>
public const int WM_CAP_SET_CALLBACK_CAPCONTROL = (WM_CAP_START + ); // 設置收回的錯誤 public const int WM_CAP_END = WM_CAP_SET_CALLBACK_CAPCONTROL; public delegate void FrameEventHandler(IntPtr lwnd, IntPtr lpVHdr); #region 公共函數(shù)
//公共函數(shù)
public static object GetStructure(IntPtr ptr, ValueType structure)
{
return Marshal.PtrToStructure(ptr, structure.GetType());
} public static object GetStructure(int ptr, ValueType structure)
{
return GetStructure(new IntPtr(ptr), structure);
} public static void Copy(IntPtr ptr, byte[] data)
{
Marshal.Copy(ptr, data, , data.Length);
} public static void Copy(int ptr, byte[] data)
{
Copy(new IntPtr(ptr), data);
} public static int SizeOf(object structure)
{
return Marshal.SizeOf(structure);
}
#endregion 公共函數(shù)
#region 結構 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS
//========================================================VideoHdr 結構=====================================================================
//VideoHdr 結構 定義了視頻數(shù)據(jù)塊的頭信息,在編寫回調(diào)函數(shù)時常用到其數(shù)據(jù)成員lpData(指向數(shù)據(jù)緩存的指針)和dwBufferLength(數(shù)據(jù)緩存的大小)。
//視頻幀到緩存的捕獲則需要應用回調(diào)函數(shù)和相應的數(shù)據(jù)塊結構 VIDEOHDR
[StructLayout(LayoutKind.Sequential)]
public struct VIDEOHDR
{
public IntPtr lpData; /* 指向數(shù)據(jù)緩存的指針 */
public int dwBufferLength; /* 數(shù)據(jù)緩存的大小 */
public int dwBytesUsed; /* Bytes actually used */
public int dwTimeCaptured; /* Milliseconds from start of stream */
public int dwUser; /* for client's use */
public int dwFlags; /* assorted flags (see defines) */
public int dwReserved; /* reserved for driver */
}
//=======================================================BitmapInfoHeader結構===================================================================
//BitmapInfoHeader定義了位圖的頭部信息
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
public int biSize;
public int biWidth;
public int biHeight;
public short biPlanes;
public short biBitCount;
public int biCompression;
public int biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public int biClrUsed;
public int biClrImportant;
}
//========================================================================================================================================= //======================================================BitmapInfo結構=====================================================================
//BitmapInfo 位圖信息
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFO
{
public BITMAPINFOHEADER bmiHeader;
public int bmiColors;
} //=====================================================CAPTUREPARMS結構======================================================================
//CAPTUREPARMS 包含控制視頻流捕獲過程的參數(shù),如捕獲幀頻、指定鍵盤或鼠標鍵以終止捕獲、捕獲時間限制等;
[StructLayout(LayoutKind.Sequential)]
public struct CAPTUREPARMS
{
public int dwRequestMicroSecPerFrame; // 期望的楨播放率,以毫秒為單位,默認為66667,相當于15楨每秒。
public bool fMakeUserHitOKToCapture; // Show "Hit OK to cap" dlg?開始捕獲標志位,如果值為真,則在開始捕獲前要產(chǎn)生一個詢問對話框,默認為假。
public uint wPercentDropForError; //所允許的最大丟楨百分比,可以從0變化到100,默認值為10。
public bool fYield; /*另起線程標志位,如果為真,則程序重新啟動一個線程用于視頻流的捕獲,默認值是假。
但是如果你是為了真,你必須要在程序中處理一些潛在的操作,因為當視頻捕獲時,其他操作并沒有被屏蔽。*/
public int dwIndexSize; // 在AVI文件中所允許的最大數(shù)目的索引項(32K)
public uint wChunkGranularity; // AVI文件的邏輯尺寸,以字節(jié)為單位。如果值是0,則說明該尺寸漸增 在 Win32程序中無用。(2K)
public bool fUsingDOSMemory; // Use DOS buffers?
public uint wNumVideoRequested; // 所被允許分配的最大視頻緩存
public bool fCaptureAudio; // 音頻標志位,如果音頻流正在捕獲,則該值為真。
public uint wNumAudioRequested; // 最大數(shù)量的音頻緩存,默認值為10。
public uint vKeyAbort; // 終止流捕獲的虛擬鍵盤碼,默認值為VK_ESCAPE
[MarshalAs(UnmanagedType.Bool)]
public bool fAbortLeftMouse; // 終止鼠標左鍵標志位,如果該值為真,則在流捕獲過程中如果點擊鼠標左鍵則該捕獲終止,默認值為真。
public bool fAbortRightMouse; // Abort on right mouse?
public bool fLimitEnabled; // 捕獲操作時間限制,如果為真,則時間到了以后捕獲操作終止,默認為假
public uint wTimeLimit; // 具體終止時間,只有 fLimitEnabled是真時.該位才有效
public bool fMCIControl; // Use MCI video source?
public bool fStepMCIDevice; // Step MCI device?MCI 設備標志。
public int dwMCIStartTime; // Time to start in MS
public int dwMCIStopTime; // Time to stop in MS
public bool fStepCaptureAt2x; // Perform spatial averaging 2x
public int wStepCaptureAverageFrames; // 當基于平均采樣來創(chuàng)建楨時,楨的采樣時間,典型值是5
public int dwAudioBufferSize; // 音頻緩存的尺寸,如果用默認值0,緩存尺寸是最大0.5秒,或10k字節(jié)。
public int fDisableWriteCache; // Attempt to disable write cache
public int AVStreamMaster; //音視頻同步標志。
}
//========================================================================================================================================= //=================================================CAPDRIVERCAPS結構=======================================================================
//CAPDRIVERCAPS定義了捕獲驅(qū)動器的能力,如有無視頻疊加能力、有無控制視頻源、視頻格式的對話框等;
[StructLayout(LayoutKind.Sequential)]
public struct CAPDRIVERCAPS
{
[MarshalAs(UnmanagedType.U2)]
public UInt16 wDeviceIndex; //捕獲驅(qū)動器的索引值,該值可以由0到9變化。
[MarshalAs(UnmanagedType.Bool)]
public bool fHasOverlay; // 視頻疊加標志,如果設備支持視頻疊加這該位是真。
[MarshalAs(UnmanagedType.Bool)]
public bool fHasDlgVideoSource; //視頻資源對話框標志位,如果設備支持視頻選擇、控制對話框,該值為真。
[MarshalAs(UnmanagedType.Bool)]
public bool fHasDlgVideoFormat; //視頻格式對話框標志位,如果設備支持對視頻格式對話框的選擇,該位真。
[MarshalAs(UnmanagedType.Bool)]
public bool fHasDlgVideoDisplay; //視頻展示對話框標志位,如果設備支持對視頻捕獲緩存區(qū)的重新播放,該位是真。
[MarshalAs(UnmanagedType.Bool)]
public bool fCaptureInitialized; //捕獲安裝標志位,如果捕獲驅(qū)動器已經(jīng)成功連接,該值為真。
//[MarshalAs(UnmanagedType.Bool)]
public bool fDriverSuppliesPalettes; //驅(qū)動器調(diào)色板標志位,如果驅(qū)動器能創(chuàng)建調(diào)色板,則該位是真。
[MarshalAs(UnmanagedType.I4)]
public int hVideoIn;
[MarshalAs(UnmanagedType.I4)]
public int hVideoOut;
[MarshalAs(UnmanagedType.I4)]
public int hVideoExtIn;
[MarshalAs(UnmanagedType.I4)]
public int hVideoExtOut;
}
//========================================================================================================================================= //=====================================================CAPSTATUS結構========================================================================
//CAPSTATUS定義了捕獲窗口的當前狀態(tài),如圖像的寬、高等;
[StructLayout(LayoutKind.Sequential)]
public struct CAPSTATUS
{
public int uiImageWidth; //圖像寬度
public int uiImageHeight; //圖像高度
public bool fLiveWindow; //活動窗口標記,如果窗口正以預覽的方式展示圖像,那么該值為真
public bool fOverlayWindow; //疊加窗口標志位,如果正在使用硬件疊加,則該位是真。
public bool fScale; //輸入所放標志位,如果窗口是正在縮放視頻到客戶區(qū),那么該位是真。當使用硬件疊加時,改位無效。
public Point ptScroll; //被展示在窗口客戶區(qū)左上角的那個象素的x、y坐標偏移量。
public bool fUsingDefaultPalette; //默認調(diào)色板標志位,如果捕獲窗口正在使用當前默認調(diào)色板,該值為真
public bool fAudioHardware; // 音頻硬件標志位,如果系統(tǒng)已經(jīng)安裝了音頻硬件,該值為真。
public bool fCapFileExists; //捕獲文件標志位,如果一個捕獲文件已經(jīng)被創(chuàng)建,該值為真
public int dwCurrentVideoFrame; // 當前或最近流捕獲過程中,所處理的楨的數(shù)目。包括丟棄的楨。
public int dwCurrentVideoFramesDropped;//當前流捕獲過程中丟棄的楨的數(shù)目。
public int dwCurrentWaveSamples; // # of wave samples cap'td
public int dwCurrentTimeElapsedMS; // 從當前流捕獲開始計算,程序所用的時間,以毫秒為單位。
public IntPtr hPalCurrent; // 當前剪切板的句柄。
public bool fCapturingNow; // 捕獲標志位,當捕獲是正在進行時,改位是真
public int dwReturn; // 錯誤返回值,當你的應用程序不支持錯誤回調(diào)函數(shù)時可以應用改位
public int wNumVideoAllocated; // 被分配的視頻緩存的數(shù)目。
public int wNumAudioAllocated; // 被分配的音頻緩存的數(shù)目。
}
//========================================================================================================================================= #endregion 結構 VIDEOHDR|BITMAPINFOHEADER|BITMAPINFO|CAPTUREPARMS|CAPDRIVERCAPS|CAPSTATUS }
public class cVideo //視頻類
{
public bool flag = true;
private IntPtr lwndC; //保存無符號句柄
private IntPtr mControlPtr; //保存管理指示器
private int mWidth;
private int mHeight;
public delegate void RecievedFrameEventHandler(byte[] data);
public event RecievedFrameEventHandler RecievedFrame; public VideoAPI.CAPTUREPARMS Capparms;
private VideoAPI.FrameEventHandler mFrameEventHandler;
public VideoAPI.CAPDRIVERCAPS CapDriverCAPS;//捕獲驅(qū)動器的能力,如有無視頻疊加能力、有無控制視頻源、視頻格式的對話框等;
public VideoAPI.CAPSTATUS CapStatus;//該結構用于保存視頻設備捕獲窗口的當前狀態(tài),如圖像的寬、高等
string strFileName;
public cVideo(IntPtr handle, int width, int height)
{
CapDriverCAPS = new VideoAPI.CAPDRIVERCAPS();//捕獲驅(qū)動器的能力,如有無視頻疊加能力、有無控制視頻源、視頻格式的對話框等;
CapStatus = new VideoAPI.CAPSTATUS();//該結構用于保存視頻設備捕獲窗口的當前狀態(tài),如圖像的寬、高等
mControlPtr = handle; //顯示視頻控件的句柄
mWidth = width; //視頻寬度
mHeight = height; //視頻高度
}
public bool StartWebCam()
{
return StartWebCam(mWidth, mHeight);
}
/// <summary>
/// 打開視頻設備
/// </summary>
/// <param name="width">捕獲窗口的寬度</param>
/// <param name="height">捕獲窗口的高度</param>
/// <returns></returns>
public bool StartWebCam(int width,int height)
{
//byte[] lpszName = new byte[100];
//byte[] lpszVer = new byte[100];
//VideoAPI.capGetDriverDescriptionA(0, lpszName, 100, lpszVer, 100);
//this.lwndC = VideoAPI.capCreateCaptureWindowA(lpszName, VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);
//if (VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
//{
// VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 100, 0);
// VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SET_PREVIEW, true, 0);
// return true;
//}
//else
//{
// return false;
//}
this.lwndC = VideoAPI.capCreateCaptureWindow("", VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, , , mWidth, mHeight, mControlPtr, );//AVICap類的捕捉窗口
VideoAPI.FrameEventHandler FrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, , );//注冊錯誤回調(diào)函數(shù)
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUS, , );//注冊狀態(tài)回調(diào)函數(shù)
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, , );//注冊視頻流回調(diào)函數(shù)
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, , FrameEventHandler);//注冊幀回調(diào)函數(shù) //if (!CapDriverCAPS.fCaptureInitialized)//判斷當前設備是否被其他設備連接已經(jīng)連接
//{ if (VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, , ))
{
//-----------------------------------------------------------------------
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_GET_CAPS, VideoAPI.SizeOf(CapDriverCAPS), ref CapDriverCAPS);//獲得當前視頻 CAPDRIVERCAPS定義了捕獲驅(qū)動器的能力,如有無視頻疊加能力、有無控制視頻源、視頻格式的對話框等;
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_STATUS, VideoAPI.SizeOf(CapStatus), ref CapStatus);//獲得當前視頻流的尺寸 存入CapStatus結構 VideoAPI.BITMAPINFO bitmapInfo = new VideoAPI.BITMAPINFO();//設置視頻格式 (height and width in pixels, bits per frame).
bitmapInfo.bmiHeader = new VideoAPI.BITMAPINFOHEADER();
bitmapInfo.bmiHeader.biSize = VideoAPI.SizeOf(bitmapInfo.bmiHeader);
bitmapInfo.bmiHeader.biWidth = mWidth;
bitmapInfo.bmiHeader.biHeight = mHeight;
bitmapInfo.bmiHeader.biPlanes = ;
bitmapInfo.bmiHeader.biBitCount = ;
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, , );//設置在PREVIEW模式下設定視頻窗口的刷新率 設置每40毫秒顯示一幀,即顯示幀速為每秒25幀
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SCALE, , );//打開預覽視頻的縮放比例
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_VIDEOFORMAT, VideoAPI.SizeOf(bitmapInfo), ref bitmapInfo); this.mFrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
this.capSetCallbackOnFrame(this.lwndC, this.mFrameEventHandler); VideoAPI.CAPTUREPARMS captureparms = new VideoAPI.CAPTUREPARMS();
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(captureparms), ref captureparms);
if (CapDriverCAPS.fHasOverlay)
{
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_OVERLAY, , );//啟用疊加 注:據(jù)說啟用此項可以加快渲染速度
}
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEW, , );//設置顯示圖像啟動預覽模式 PREVIEW
VideoAPI.SetWindowPos(this.lwndC, , , , width, height, VideoAPI.SWP_NOZORDER | VideoAPI.SWP_NOMOVE);//使捕獲窗口與進來的視頻流尺寸保持一致
return true;
}
else
{ flag = false;
return false;
}
}
public bool ReSizePic(int width, int height)
{
try
{
// CloseWebcam();
// StartWebCam();
// this.lwndC = VideoAPI.capCreateCaptureWindow("", VideoAPI.WS_CHILD | VideoAPI.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0); // VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_STATUS, VideoAPI.SizeOf(CapStatus), ref CapStatus);//獲得當前視頻流的尺寸 存入CapStatus結構
// VideoAPI.FrameEventHandler FrameEventHandler = new VideoAPI.FrameEventHandler(FrameCallback);
// VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_ERROR, 0, 0);//注冊錯誤回調(diào)函數(shù)
// VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_STATUS, 0, 0);//注冊狀態(tài)回調(diào)函數(shù)
// VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, 0);//注冊視頻流回調(diào)函數(shù)
// VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, 0, FrameEventHandler);//注冊幀回調(diào)函數(shù)
//// if (VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_DRIVER_CONNECT, 0, 0))
// {
// VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SCALE, 1, 0);
// VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEWRATE, 40, 0);
// VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_PREVIEW, 1, 0); return VideoAPI.SetWindowPos(this.lwndC, , , , width, height, VideoAPI.SWP_NOZORDER | VideoAPI.SWP_NOMOVE) > ;
// }
// return false;
}
catch
{
return false;
}
}
public void get()
{
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_GET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);
}
public void set()
{
VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_SEQUENCE_SETUP, VideoAPI.SizeOf(Capparms), ref Capparms);
}
private bool capSetCallbackOnFrame(IntPtr lwnd, VideoAPI.FrameEventHandler lpProc)
{
return VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SET_CALLBACK_FRAME, , lpProc);
}
/// <summary>
/// 關閉視頻設備
/// </summary>
public void CloseWebcam()
{
VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_DRIVER_DISCONNECT, , );
}
/// <summary>
/// 拍照
/// </summary>
/// <param name="path">要保存bmp文件的路徑</param>
public void GrabImage(IntPtr hWndC, string path)
{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_SAVEDIB, , hBmp.ToInt32());
}
public bool StarKinescope(string path)
{
try
{
strFileName = path;
string dir = path.Remove(path.LastIndexOf("\\"));
if (!File.Exists(dir))
{
Directory.CreateDirectory(dir);
}
int hBmp = Marshal.StringToHGlobalAnsi(path).ToInt32();
bool b = VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_FILE_SET_CAPTURE_FILE, , hBmp);
b = b && VideoAPI.SendMessage(this.lwndC, VideoAPI.WM_CAP_SEQUENCE, , );
return b;
}
catch
{
return false;
}
}
/// <summary>
/// 停止錄像
/// </summary>
public bool StopKinescope()
{
return VideoAPI.SendMessage(lwndC, VideoAPI.WM_CAP_STOP, , );
}
private void FrameCallback(IntPtr lwnd, IntPtr lpvhdr)
{
VideoAPI.VIDEOHDR videoHeader = new VideoAPI.VIDEOHDR();
byte[] VideoData;
videoHeader = (VideoAPI.VIDEOHDR)VideoAPI.GetStructure(lpvhdr, videoHeader);
VideoData = new byte[videoHeader.dwBytesUsed];
VideoAPI.Copy(videoHeader.lpData, VideoData);
if (this.RecievedFrame != null)
this.RecievedFrame(VideoData);
}
private Thread myThread; public void CompressVideoFfmpeg()
{
myThread = new Thread(new ThreadStart(testfn));
myThread.Start();
testfn();
}
private void testfn()
{
string file_name = strFileName;
string command_line = " -i " + file_name + " -vcodec libx264 -cqp 25 -y " + file_name.Replace(".avi", "_264") + ".avi";
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.WorkingDirectory = Application.StartupPath;
proc.StartInfo.UseShellExecute = false; //use false if you want to hide the window
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.FileName = "ffmpeg";
proc.StartInfo.Arguments = command_line;
proc.Start();
proc.WaitForExit();
proc.Close();
Common.writeLog("視頻"+strFileName+"壓縮完畢");
// 刪除原始avi文件
FileInfo file = new FileInfo(file_name);
if (file.Exists)
{
try
{
file.Delete(); //刪除單個文件
}
catch (Exception e)
{
// Common.writeLog("刪除視頻文件“" + file_name + "”出錯!準備" ); (new Thread(() =>
{
bool b = false;
for (int i = ; i < ; i++)
{
Thread.Sleep(*(i*i));
try
{
file.Delete();
b = true;
break;
}
catch
{
}
};
if (!b)
Common.writeLog("刪除視頻文件“" + file_name + "”出錯");
}
)).Start();
}
}
//myThread.Abort();
}
}
}
總結
以上是生活随笔為你收集整理的C#写的一个视频转换解码器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工业污水流量计在废水处理中的关键作用
- 下一篇: 气浴振荡器的这些使用注意事项你可知