溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

發(fā)布時(shí)間:2020-08-27 02:45:42 來源:腳本之家 閱讀:512 作者:m_buddy 欄目:編程語言

本文為大家分享了AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能的具體方法,供大家參考,具體內(nèi)容如下

1. 概述

最近由于興趣學(xué)習(xí)了下在C#上使用AForge錄制攝像頭視頻并壓縮編碼??傮w上來說這個(gè)第三方.net視覺開發(fā)庫還是比較穩(wěn)定的(AForge lib下載、離線幫助文檔下載)。但是由于這個(gè)第三方庫維護(hù)不怎么樣,導(dǎo)致會(huì)出現(xiàn)不兼容的問題。這里將這些與大家分享,希望對您有幫助。

在使用AForge第三方庫錄制本地視頻所要使用到的類主要有這幾個(gè):FilterInfoCollection、VideoCaptureDevice、VideoSourcePlayer、VideoFileWriter。下面我就簡單的介紹一下這幾個(gè)類涉及到的方法等。

FilterInfoCollection:

該類主要是用于攝像頭視頻輸入設(shè)備列表檢測的。是繼承自C#中的System.Collections.CollectionBase類。

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

這是離線幫助文檔上對這個(gè)類的調(diào)用方式:

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

其中構(gòu)造函數(shù)傳遞進(jìn)去的參數(shù)是需要采集的信號的類型,他還有其他的輸入類型(如聲音等):

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

VideoCaptureDevice:

這是該類中的一些成員函數(shù)和變量

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

這個(gè)類便是要選擇了視頻輸入的設(shè)備了,他的構(gòu)造函數(shù)是

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

在實(shí)際的使用過程中可能會(huì)存在多個(gè)設(shè)備的情況,便可以通過第二個(gè)參數(shù)進(jìn)行輸入設(shè)備的指定。初始化是這樣的

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

在本例子的實(shí)際使用過程中對上面該類事件NewFrame函數(shù)進(jìn)行了響應(yīng),然后提取出當(dāng)前幀。

VideoSourcePlayer:

該類是AForge.Control中的類,是控件中調(diào)用的,這里將它添加進(jìn)來是為了作為拍照功能使用的,這里就不做介紹了。

VideoFileWriter:

該類是視頻寫操作類,主要實(shí)現(xiàn)視頻文件的壓縮和寫入到文件中。

本例子中先使用VideoFileWriter.Open()函數(shù)設(shè)定錄制視頻的高度、寬度、幀率、編碼類型。

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

這是該第三方類庫支持的視頻編碼格式

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

然后使用下面這個(gè)函數(shù)就可以將當(dāng)前幀寫入到視頻文件中了。

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

2. 實(shí)現(xiàn)

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();
    }
 
    //關(guān)閉窗口響應(yīng)函數(shù)
    private void button2_Click(object sender, EventArgs e)
    {
      if (this.writer.IsOpen)
      {
        MessageBox.Show("視頻流還沒有寫完,請點(diǎn)擊結(jié)束錄制。", "錯(cuò)誤", 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; //攝像頭設(shè)備
    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;
 
    //窗體初始化函數(shù)
    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();
 
      //設(shè)置視頻編碼格式
      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;
 
      //設(shè)置視頻來源
      try
      {
        // 枚舉所有視頻輸入設(shè)備
        videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
 
        if (videoDevices.Count == 0)
          throw new ApplicationException();  //沒有找到攝像頭設(shè)備
 
        foreach (FilterInfo device in videoDevices)
        {
          this.comboBox_camera.Items.Add(device.Name);
        }
        //this.comboBox_camera.SelectedIndex = 0;  //注釋掉,選擇攝像頭來源的時(shí)候才會(huì)才會(huì)觸發(fā)顯示攝像頭信息
      }
      catch (ApplicationException)
      {
        videoDevices = null;
        MessageBox.Show("沒有找到攝像頭設(shè)備", "錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
      }
 
      //秒表
      this.timer_count = new System.Timers.Timer();  //實(shí)例化Timer類,設(shè)置間隔時(shí)間為10000毫秒;
      this.timer_count.Elapsed += new System.Timers.ElapsedEventHandler(tick_count);  //到達(dá)時(shí)間的時(shí)候執(zhí)行事件;
      this.timer_count.AutoReset = true;  //設(shè)置是執(zhí)行一次(false)還是一直執(zhí)行(true);
      this.timer_count.Interval = 1000;
    }
 
    //視頻源選擇下拉框選擇之后的響應(yīng)函數(shù)
    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;
    //新幀的觸發(fā)函數(shù)
    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);
      }
    }
 
    //拍攝圖像按鈕響應(yīng)函數(shù)
    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("攝像頭沒有運(yùn)行", "錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
 
    //開始錄像按鈕響應(yīng)函數(shù)
    private void button_start_Click(object sender, EventArgs e)
    {
      int width = 640;  //錄制視頻的寬度
      int height = 480;  //錄制視頻的高度
      int fps = 9;
 
      //創(chuàng)建一個(gè)視頻文件
      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("沒有視頻源輸入,無法錄制視頻。", "錯(cuò)誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
 
      timer_count.Enabled = true;//是否執(zhí)行System.Timers.Timer.Elapsed事件;
      this.label5.Visible = true;
      this.label5.Text = "REC";
      this.is_record_video = true;
    }
 
 
    //停止錄制視頻響應(yīng)函數(shù)
    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;
    }
 
    //暫停按鈕響應(yīng)函數(shù)
    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 = "恢復(fù)錄像";
        timer_count.Enabled = false;  //暫停計(jì)時(shí)
        return;
      }
      if (this.button3.Text.Trim() == "恢復(fù)錄像")
      {
        this.is_record_video = true;
        timer_count.Enabled = true;   //恢復(fù)計(jì)時(shí)
        this.label5.Visible = true;
        this.button3.Text = "暫停錄像";
      }
    }
 
    //計(jì)時(shí)器響應(yīng)函數(shù)
    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. 結(jié)果

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

4. 錯(cuò)誤和注意事項(xiàng)

1. 在使用AForge這個(gè)軟件過程中需要的不僅僅是將Release文件夾下對應(yīng)的lib添加到項(xiàng)目的引用中,在進(jìn)行視頻壓縮編碼的時(shí)候需要將External文件夾下的相關(guān)lib添加到程序運(yùn)行的Debug目錄下

基于AForge實(shí)現(xiàn)C#攝像頭視頻錄制功能

2. 在使用的時(shí)候會(huì)遇到這個(gè)錯(cuò)誤“混合模式程序集是針對“v2.0.50727”版的運(yùn)行時(shí)生成的,在沒有配置其他信息的情況”的錯(cuò)誤。這是因?yàn)?net框架不兼容的問題,AForge使用的比較老好像是2.0的。。。-_-||。所以需要在App.config對其進(jìn)行配置,使其對前版本的兼容,配置如下(這是我添加的配置):

<startup useLegacyV2RuntimeActivationPolicy="true">  
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>  
<supportedRuntime version="v2.0.50727"/>  
</startup>

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI