基於AForge的C#網路攝影機視頻錄製

來源:互聯網
上載者:User
1. 概述

最近搞華為的CDN(-_-||-_-||-_-||),寫東西的時間比較少了。最近由於興趣學習了下在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 AForgeusing 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>
這裡是我做的 Demo,有興趣的可以看看....

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.