C#实现USB摄像头录像功能
最近在做一个小程序,用C#实现USB摄像头录像功能,目前录像功能已经完成,现在问题是录出来的avi文件超大的,50秒左右就达到一百多兆了,想知道怎么在录像的时候,进行压缩处理。望高手指点,分不多了,谁做过这方面的例子可以发个给我最好啦! C# 视频 --------------------编程问答-------------------- http://blog.csdn.net/svtme/article/details/5668522 --------------------编程问答-------------------- C# 做多媒体能力很有限 去学习C++吧 --------------------编程问答-------------------- 没有人做过么?顶起 --------------------编程问答-------------------- http://download.csdn.net/detail/mjp1234airen4385/3607954这个资源你看看。
资源里使用的是mp4压缩编码,录制图像格式是avi。
你可以使用里面的mp4编码类库(微软提供的免费压缩类库),自己处理视频,但是要使用directshow了 --------------------编程问答-------------------- 录像是直接复制了网上的。
压缩是一个同事做的。
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调用
[DllImport("avicap32.dll")]//包含了执行视频捕获的函数,它给AVI文件I/O和视频、音频设备驱动程序提供一个高级接口
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 + 5;
// 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 + 25;
public const string avicap32 = "avicap32.dll";
public const int WM_USER = 1024;
/// <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 + 100; //开始 1124
/// <summary>
/// /获得 CAPSTR EAMPTR
/// WM_CAP_START + 1=1025
/// </summary>
public const int WM_CAP_GET_CAPSTREAMPTR = (WM_CAP_START + 1); //获得 CAPSTR EAMPTR
/// <summary>
/// 设置收回错误 WM_CAP_START + 2=1026
/// </summary>
public const int WM_CAP_SET_CALLBACK_ERROR = (WM_CAP_START + 2); //设置收回错误
/// <summary>
/// 设置收回状态 WM_CAP_START + 3=1027
/// </summary>
public const int WM_CAP_SET_CALLBACK_STATUS = (WM_CAP_START + 3); //设置收回状态
/// <summary>
/// 设置收回出产 WM_CAP_START + 4=1028
/// </summary>
public const int WM_CAP_SET_CALLBACK_YIELD = (WM_CAP_START + 4); //设置收回出产
/// <summary>
/// 设置收回结构 WM_CAP_START + 5=1029
/// </summary>
public const int WM_CAP_SET_CALLBACK_FRame = (WM_CAP_START + 5); //设置收回结构
/// <summary>
/// 设置收回视频流 WM_CAP_START + 6=1030
/// </summary>
public const int WM_CAP_SET_CALLBACK_VIDEOSTREAM = (WM_CAP_START + 6); //设置收回视频流
/// <summary>
/// 设置收回视频波流 WM_CAP_START +7=1031
/// </summary>
public const int WM_CAP_SET_CALLBACK_WAVESTREAM = (WM_CAP_START + 7); //设置收回视频波流
/// <summary>
/// 获得使用者数据 WM_CAP_START + 8=1032
/// </summary>
public const int WM_CAP_GET_USER_DATA = (WM_CAP_START + 8); //获得使用者数据
/// <summary>
/// 设置使用者数据 WM_CAP_START + 9=1033
/// </summary>
public const int WM_CAP_SET_USER_DATA = (WM_CAP_START + 9); //设置使用者数据
/// <summary>
/// 驱动程序连接 WM_CAP_START + 10=1034
/// </summary>
public const int WM_CAP_DRIVER_CONNECT = (WM_CAP_START + 10); //驱动程序连接
/// <summary>
/// 断开启动程序连接 WM_CAP_START + 11=1035
/// </summary>
public const int WM_CAP_DRIVER_DISCONNECT = (WM_CAP_START + 11); //断开启动程序连接
/// <summary>
/// 获得驱动程序名字 WM_CAP_START + 12=1036
/// </summary>
public const int WM_CAP_DRIVER_GET_NAME = (WM_CAP_START + 12); //获得驱动程序名字
/// <summary>
/// 获得驱动程序版本 WM_CAP_START + 13=1037
/// </summary>
public const int WM_CAP_DRIVER_GET_VERSION = (WM_CAP_START + 13); //获得驱动程序版本
/// <summary>
/// 获得驱动程序帽子 WM_CAP_START + 14=1038
/// </summary>
public const int WM_CAP_DRIVER_GET_CAPS = (WM_CAP_START + 14); //获得驱动程序帽子
/// <summary>
/// 设置捕获文件 WM_CAP_START + 20=1044
/// </summary>
public const int WM_CAP_FILE_SET_CAPTURE_FILE = (WM_CAP_START + 20); //设置捕获文件
/// <summary>
/// 获得捕获文件 WM_CAP_START + 21=1045
/// </summary>
public const int WM_CAP_FILE_GET_CAPTURE_FILE = (WM_CAP_START + 21); //获得捕获文件
/// <summary>
/// 另存文件为 WM_CAP_START + 23=1047
/// </summary>
public const int WM_CAP_FILE_SAVEAS = (WM_CAP_START + 23); //另存文件为
/// <summary>
/// 保存文件 WM_CAP_START + 25=1049
/// </summary>
public const int WM_CAP_FILE_SAVEDIB = (WM_CAP_START + 25); //保存文件
// out of order to save on ifdefs
/// <summary>
/// 分派文件 WM_CAP_START + 22=1044
/// </summary>
public const int WM_CAP_FILE_ALLOCATE = (WM_CAP_START + 22); //分派文件
/// <summary>
/// 设置开始文件 WM_CAP_START + 24=1046
/// </summary>
public const int WM_CAP_FILE_SET_INFOCHUNK = (WM_CAP_START + 24); //设置开始文件
/// <summary>
/// 编辑复制 WM_CAP_START + 30=1054
/// </summary>
public const int WM_CAP_EDIT_COPY = (WM_CAP_START + 30); //编辑复制
/// <summary>
/// 设置音频格式 WM_CAP_START + 35=1059
/// </summary>
public const int WM_CAP_SET_AUDIOFORMAT = (WM_CAP_START + 35); //设置音频格式
/// <summary>
/// 捕获音频格式 WM_CAP_START + 36=1060
/// </summary>
public const int WM_CAP_GET_AUDIOFORMAT = (WM_CAP_START + 36); //捕获音频格式
/// <summary>
/// 打开视频格式设置对话框 WM_CAP_START + 41=1065
/// </summary>
--------------------编程问答-------------------- 你们回答的,我网上都查过了,没效果,还有哪位做过类似的程序么? --------------------编程问答-------------------- 加个编码filter 就可以了 "XviD MPEG-4 Codec" --------------------编程问答-------------------- 录像部分我是从网上找的,你看看怎么加
--------------------编程问答-------------------- /// <summary>
/// 开始录像
/// </summary>
/// <param>要保存录像的路径</param>
public void StarKinescope(string path)
{
IntPtr hBmp = Marshal.StringToHGlobalAnsi(path);
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_FILE_SET_CAPTURE_FILE, 0, hBmp.ToInt32());
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_SEQUENCE, 0, 0);
} --------------------编程问答-------------------- /// <summary>
/// 开启摄像头
/// </summary>
public void StartWebCam()
{
this.lwndC = AviCapture.capCreateCaptureWindow("", AviCapture.WS_CHILD | AviCapture.WS_VISIBLE, 0, 0, mWidth, mHeight, mControlPtr, 0);//AVICap类的捕捉窗口
if (AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_DRIVER_CONNECT, 0, 0))
{
//获得当前视频 CAPDRIVERCAPS定义了捕获驱动器的能力,如有无视频叠加能力、有无控制视频源、视频格式的对话框等;
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_DRIVER_GET_CAPS, AviCapture.SizeOf(CapDriverCAPS), ref CapDriverCAPS);
//获得当前视频流的尺寸 存入CapStatus结构
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_GET_STATUS, AviCapture.SizeOf(CapStatus), ref CapStatus);
//设置视频格式 (height and width in pixels, bits per frame).
AviCapture.BITMAPINFO bitmapInfo = new AviCapture.BITMAPINFO();
bitmapInfo.bmiHeader = new AviCapture.BITMAPINFOHEADER();
bitmapInfo.bmiHeader.biSize = AviCapture.SizeOf(bitmapInfo.bmiHeader);
bitmapInfo.bmiHeader.biWidth = mWidth;
bitmapInfo.bmiHeader.biHeight = mHeight;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 24;
//设置在PREVIEW模式下设定视频窗口的刷新率 设置每34毫秒显示一帧,即显示帧速为每秒29帧
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_SET_PREVIEWRATE, 34, 0);
//打开预览视频的缩放比例
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_SET_SCALE, 1, 0);
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_SET_VIDEOFORMAT, AviCapture.SizeOf(bitmapInfo), ref bitmapInfo);
AviCapture.CAPTUREPARMS captureparms = new AviCapture.CAPTUREPARMS();
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_GET_SEQUENCE_SETUP, AviCapture.SizeOf(captureparms), ref captureparms);
if (CapDriverCAPS.fHasOverlay)
{
//启用叠加 注:据说启用此项可以加快渲染速度
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_SET_OVERLAY, 1, 0);
}
//设置显示图像启动预览模式 PREVIEW
AviCapture.SendMessage(this.lwndC, AviCapture.WM_CAP_SET_PREVIEW, 1, 0);
//使捕获窗口与进来的视频流尺寸保持一致
AviCapture.SetWindowPos(this.lwndC, 0, 0, 0, mWidth, mHeight, AviCapture.SWP_NOZORDER | AviCapture.SWP_NOMOVE);
}
else
{
System.Windows.Forms.MessageBox.Show("未能连接设备,请检查设备连接及是否有其他程序占用!");
//flag = false;
}
} --------------------编程问答-------------------- 我之前做过,好像有个什么开源的库对avi转换成rmvb就可以了
补充:.NET技术 , C#