在本文中,将探讨如何使用摄像头录制视频文件。将使用avicap32.dll来实现这一功能,它允许连接到摄像头并设置其属性。此外,还将学习如何定时启动视频录制。
本文的代码基础是使用avicap32.dll。这个动态链接库(DLL)允许连接到摄像头并设置其属性。使用SendMessage函数来向摄像头发送消息,比如连接和捕获视频。虽然已经有关于这个话题的一些文章,但会尽量让本文更加简单易懂。
首先,需要设置捕获控制。使用了一个简单的PictureBox控件来显示摄像头的输出。这可以通过以下代码实现:
C#
mCapHwnd = capCreateCaptureWindowA(
"WebCap", WS_VISIBLE | WS_CHILD,
0,
0,
this.pictureBox1.Width,
this.pictureBox1.Height,
this.pictureBox1.Handle.ToInt32(),
0
);
接下来,需要连接到摄像头:
C#
SendMessage(mCapHwnd, WM_CAP_CONNECT, 0, 0);
然后,需要设置一些摄像头属性:
C#
// 设置摄像头的帧率
SendMessage(mCapHwnd, WM_CAP_SET_PREVIEWRATE, 66, 0);
// 设置预览标志为true
SendMessage(mCapHwnd, WM_CAP_SET_PREVIEW, 1, 0);
// 如果想要控制输出视频的视频压缩,可以设置这个
SendMessage(mCapHwnd, WM_CAP_DLG_VIDEOCOMPRESSION, 0, 0);
对于捕获视频,需要设置各种视频属性,比如是否捕获音频等。需要使用CAPTUREPARMS结构来实现这一点。
C#
SendMessage2(mCapHwnd, WM_CAP_SET_SEQUENCE_SETUP, new IntPtr(Marshal.SizeOf(CaptureParams)), ref CaptureParams);
CAPTUREPARMS结构中的一个重要参数是fYield。如果想要在一个与窗体不同的线程中捕获视频,可以将这个参数设置为true(1)。
接下来,想要将视频捕获到PictureBox控件中。通过调用以下消息来实现这一点:
C#
SendMessage(mCapHwnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0);
需要在一个计时器的tick事件中调用这行代码,以便能够获得连续的视频。使用了System.Threading.Timer来实现这一点。
C#
private void DoIt()
{
System.Threading.Timer t = null;
t = new System.Threading.Timer(
delegate(object state)
{
t.Dispose();
CaptureImage();
DoIt();
},
null,
66,
-1);
}
接下来,需要将视频捕获到文件中(默认文件格式是.avi):
C#
string file = DateTime.Now.ToShortDateString().Replace('/', '_') +
"_" + DateTime.Now.ToLongTimeString().Replace(':', '_') +
".avi";
SendMessageA(mCapHwnd, WM_CAP_FILE_SET_CAPTURE_FILEA, 0, dir +
Path.DirectorySeparatorChar + file);
SendMessage(mCapHwnd, WM_CAP_SEQUENCE, 0, 0);
接下来的两个方法用于配置摄像头的源和格式。如果不想使用摄像头的默认设置,可以使用这两个方法。
C#
private void btnConfig_Click(object sender, EventArgs e)
{
SendMessage(mCapHwnd, WM_CAP_DLG_VIDEOSOURCE, 0, 0);
}
private void btnFormat_Click(object sender, EventArgs e)
{
SendMessage(mCapHwnd, WM_CAP_DLG_VIDEOFORMAT, 0, 0);
}
代码的定时部分非常简单。使用app.config文件来存储想要开始捕获的时间,并使用Timer控件来检查是否到了开始捕获的时间。可以在源代码下载中查看这部分内容。
最后,当工作完成后,需要从摄像头断开连接:
C#
SendMessage(mCapHwnd, WM_CAP_DISCONNECT, 0, 0);