当前位置: 移动技术网 > IT编程>开发语言>c# > 基于AForge实现C#摄像头视频录制功能

基于AForge实现C#摄像头视频录制功能

2019年07月18日  | 移动技术网IT编程  | 我要评论

本文为大家分享了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.componentmodel;
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.combobox_videoecode.items.add("raw");
      this.combobox_videoecode.items.add("mpeg2");
      this.combobox_videoecode.items.add("flv1");
      this.combobox_videoecode.items.add("h263p");
      this.combobox_videoecode.items.add("msmpeg4v3");
      this.combobox_videoecode.items.add("msmpeg4v2");
      this.combobox_videoecode.items.add("wmv2");
      this.combobox_videoecode.items.add("wmv1");
      this.combobox_videoecode.items.add("mpeg4");
      this.combobox_videoecode.selectedindex = 1;
 
      //设置视频来源
      try
      {
        // 枚举所有视频输入设备
        videodevices = new filterinfocollection(filtercategory.videoinputdevice);
 
        if (videodevices.count == 0)
          throw new applicationexception();  //没有找到摄像头设备
 
        foreach (filterinfo device in videodevices)
        {
          this.combobox_camera.items.add(device.name);
        }
        //this.combobox_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.combobox_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.combobox_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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网