本文为大家分享了aforge实现c#摄像头视频录制功能的具体方法,供大家参考,具体内容如下
1. 概述
最近由于兴趣学习了下在c#上使用aforge录制摄像头视频并压缩编码。总体上来说这个第三方.net视觉开发库还是比较稳定的(aforge lib下载、离线帮助文档下载)。但是由于这个第三方库维护不怎么样,导致会出现不兼容的问题。这里将这些与大家分享,希望对您有帮助。
在使用aforge第三方库录制本地视频所要使用到的类主要有这几个: filterinfocollection、videocapturedevice、videosourceplayer、videofilewriter 。下面我就简单的介绍一下这几个类涉及到的方法等。
filterinfocollection:
该类主要是用于摄像头视频输入设备列表检测的。是继承自c#中的system.collections.collectionbase类。
这是离线帮助文档上对这个类的调用方式:
其中构造函数传递进去的参数是需要采集的信号的类型,他还有其他的输入类型(如声音等):
videocapturedevice:
这是该类中的一些成员函数和变量
这个类便是要选择了视频输入的设备了,他的构造函数是
在实际的使用过程中可能会存在多个设备的情况,便可以通过第二个参数进行输入设备的指定。初始化是这样的
在本例子的实际使用过程中对上面该类事件newframe函数进行了响应,然后提取出当前帧。
videosourceplayer:
该类是aforge.control中的类,是控件中调用的,这里将它添加进来是为了作为拍照功能使用的,这里就不做介绍了。
videofilewriter:
该类是视频写操作类,主要实现视频文件的压缩和写入到文件中。
本例子中先使用videofilewriter.open()函数设定录制视频的高度、宽度、帧率、编码类型。
这是该第三方类库支持的视频编码格式
然后使用下面这个函数就可以将当前帧写入到视频文件中了。
2. 实现
using system;
using system.collections.generic;
using system测试数据ponentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.threading.tasks;
using system.windows.forms;
using system.timers;
//using aforge
using aforge;
using aforge.video;
using aforge.video.directshow;
using aforge.video.ffmpeg;
using aforge.controls;
namespace video_record
{
public partial class form1 : form
{
public form1()
{
initializecomponent();
}
//关闭窗口响应函数
private void button2_click( object sender, eventargs e)
{
if ( this .writer.isopen)
{
messagebox.show( "视频流还没有写完,请点击结束录制。" , "错误" , messageboxbuttons.ok, messageboxicon.error);
return ;
}
this .videosource.signaltostop();
this .videosource.waitforstop();
this .videosourceplayer.signaltostop();
this .videosourceplayer.waitforstop();
this .hide();
this .close();
this .dispose();
}
private filterinfocollection videodevices; //摄像头设备
private videocapturedevice videosource; //视频的来源选择
private videosourceplayer videosourceplayer; //aforge控制控件
private videofilewriter writer; //写入到视频
private bool is_record_video = false ; //是否开始录像
system.timers.timer timer_count;
int tick_num = 0;
//窗体初始化函数
private void form1_load( object sender, eventargs e)
{
this .label5.visible = false ;
this .videosourceplayer = new aforge.controls.videosourceplayer();
this .videosource = new videocapturedevice();
this .writer = new videofilewriter();
//设置视频编码格式
this 测试数据bobox_videoecode.items.add( "raw" );
this 测试数据bobox_videoecode.items.add( "mpeg2" );
this 测试数据bobox_videoecode.items.add( "flv1" );
this 测试数据bobox_videoecode.items.add( "h263p" );
this 测试数据bobox_videoecode.items.add( "msmpeg4v3" );
this 测试数据bobox_videoecode.items.add( "msmpeg4v2" );
this 测试数据bobox_videoecode.items.add( "wmv2" );
this 测试数据bobox_videoecode.items.add( "wmv1" );
this 测试数据bobox_videoecode.items.add( "mpeg4" );
this 测试数据bobox_videoecode.selectedindex = 1;
//设置视频来源
try
{
// 枚举所有视频输入设备
videodevices = new filterinfocollection(filtercategory.videoinputdevice);
if (videodevices.count == 0)
throw new applicationexception(); //没有找到摄像头设备
foreach (filterinfo device in videodevices)
{
this 测试数据bobox_camera.items.add(device.name);
}
//this测试数据bobox_camera.selectedindex = 0; //注释掉,选择摄像头来源的时候才会才会触发显示摄像头信息
}
catch (applicationexception)
{
videodevices = null ;
messagebox.show( "没有找到摄像头设备" , "错误" , messageboxbuttons.ok, messageboxicon.error);
}
//秒表
this .timer_count = new system.timers.timer(); //实例化timer类,设置间隔时间为10000毫秒;
this .timer_count.elapsed += new system.timers.elapsedeventhandler(tick_count); //到达时间的时候执行事件;
this .timer_count.autoreset = true ; //设置是执行一次(false)还是一直执行(true);
this .timer_count.interval = 1000;
}
//视频源选择下拉框选择之后的响应函数
private void combobox_camera_selectedindexchanged( object sender, eventargs e)
{
int selected_index = this 测试数据bobox_camera.selectedindex;
this .videosource = new videocapturedevice(videodevices[selected_index].monikerstring);
// set newframe event handler
videosource.newframe += new newframeeventhandler(show_video);
videosource.start();
videosourceplayer.videosource = videosource;
videosourceplayer.start();
this .label5.text = "连接中..." ;
this .label5.visible = true ;
isshowed = true ;
}
bool isshowed = true ;
//新帧的触发函数
private void show_video( object sender, newframeeventargs eventargs)
{
if (isshowed)
{
this .label5.visible = false ;
isshowed = false ;
}
bitmap bitmap = eventargs.frame; //获取到一帧图像
picturebox1.image = image.fromhbitmap(bitmap.gethbitmap());
if (is_record_video)
{
writer.writevideoframe(bitmap);
}
}
//拍摄图像按钮响应函数
private void button1_click( object sender, eventargs e)
{
if ( this .videosource.isrunning && this .videosourceplayer.isrunning)
{
bitmap bitmap = this .videosourceplayer.getcurrentvideoframe();
bitmap.save( "img.jpeg" , system.drawing.imaging.imageformat.jpeg);
}
else
messagebox.show( "摄像头没有运行" , "错误" , messageboxbuttons.ok, messageboxicon.information);
}
//开始录像按钮响应函数
private void button_start_click( object sender, eventargs e)
{
int width = 640; //录制视频的宽度
int height = 480; //录制视频的高度
int fps = 9;
//创建一个视频文件
string video_format = this 测试数据bobox_videoecode.text.trim(); //获取选中的视频编码
if ( this .videosource.isrunning && this .videosourceplayer.isrunning)
{
if (-1 != video_format.indexof( "mpeg" ))
{
writer.open( "test.avi" , width, height, fps, videocodec.mpeg4);
}
else if (-1 != video_format.indexof( "wmv" ))
{
writer.open( "test.wmv" , width, height, fps, videocodec.wmv1);
}
else
{
writer.open( "test.mkv" , width, height, fps, videocodec. default );
}
}
else
messagebox.show( "没有视频源输入,无法录制视频。" , "错误" , messageboxbuttons.ok, messageboxicon.error);
timer_count.enabled = true ; //是否执行system.timers.timer.elapsed事件;
this .label5.visible = true ;
this .label5.text = "rec" ;
this .is_record_video = true ;
}
//停止录制视频响应函数
private void button_stop_click( object sender, eventargs e)
{
this .label5.visible = false ;
this .is_record_video = false ;
this .writer.close();
this .timer_count.enabled = false ;
tick_num = 0;
}
//暂停按钮响应函数
private void button3_click( object sender, eventargs e)
{
if ( this .button3.text.trim() == "暂停录像" )
{
this .is_record_video = false ;
this .label5.visible = false ;
this .button3.text = "恢复录像" ;
timer_count.enabled = false ; //暂停计时
return ;
}
if ( this .button3.text.trim() == "恢复录像" )
{
this .is_record_video = true ;
timer_count.enabled = true ; //恢复计时
this .label5.visible = true ;
this .button3.text = "暂停录像" ;
}
}
//计时器响应函数
public void tick_count( object source, system.timers.elapsedeventargs e)
{
tick_num++;
int temp = tick_num;
int sec = temp % 60;
int min = temp / 60;
if (60 == min)
{
min = 0;
min++;
}
int hour = min / 60;
string tick = hour.tostring() + ":" + min.tostring() + ":" + sec.tostring();
this .label4.text = tick;
}
}
}
3. 结果
4. 错误和注意事项
1. 在使用aforge这个软件过程中需要的不仅仅是将release文件夹下对应的lib添加到项目的引用中,在进行视频压缩编码的时候需要将external文件夹下的相关lib添加到程序运行的debug目录下
2. 在使用的时候会遇到这个错误[ 混合模式程序集是针对[v2.0.50727]版的运行时生成的,在没有配置其他信息的情况 ]的错误。这是因为.net框架不兼容的问题,aforge使用的比较老好像是2.0的。。。-_-||。所以需要在app.config对其进行配置,使其对前版本的兼容,配置如下(这是我添加的配置):
<startup uselegacyv2runtimeactivationpolicy= "true" >
<supportedruntime version= "v4.0" sku= ".netframework,version=v4.5" />
<supportedruntime version= "v2.0.50727" />
</startup>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/m_buddy/article/details/62417912
dy("nrwz");
查看更多关于基于AForge实现C#摄像头视频录制功能的详细内容...