您好,登錄后才能下訂單哦!
本文為大家分享了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類。
這是離線幫助文檔上對這個(gè)類的調(diào)用方式:
其中構(gòu)造函數(shù)傳遞進(jìn)去的參數(shù)是需要采集的信號的類型,他還有其他的輸入類型(如聲音等):
VideoCaptureDevice:
這是該類中的一些成員函數(shù)和變量
這個(gè)類便是要選擇了視頻輸入的設(shè)備了,他的構(gòu)造函數(shù)是
在實(shí)際的使用過程中可能會(huì)存在多個(gè)設(shè)備的情況,便可以通過第二個(gè)參數(shù)進(jìn)行輸入設(shè)備的指定。初始化是這樣的
在本例子的實(shí)際使用過程中對上面該類事件NewFrame函數(shù)進(jìn)行了響應(yīng),然后提取出當(dāng)前幀。
VideoSourcePlayer:
該類是AForge.Control中的類,是控件中調(diào)用的,這里將它添加進(jìn)來是為了作為拍照功能使用的,這里就不做介紹了。
VideoFileWriter:
該類是視頻寫操作類,主要實(shí)現(xiàn)視頻文件的壓縮和寫入到文件中。
本例子中先使用VideoFileWriter.Open()函數(shù)設(shè)定錄制視頻的高度、寬度、幀率、編碼類型。
這是該第三方類庫支持的視頻編碼格式
然后使用下面這個(gè)函數(shù)就可以將當(dāng)前幀寫入到視頻文件中了。
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é)果
4. 錯(cuò)誤和注意事項(xiàng)
1. 在使用AForge這個(gè)軟件過程中需要的不僅僅是將Release文件夾下對應(yīng)的lib添加到項(xiàng)目的引用中,在進(jìn)行視頻壓縮編碼的時(shí)候需要將External文件夾下的相關(guān)lib添加到程序運(yùn)行的Debug目錄下
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í)有所幫助,也希望大家多多支持億速云。
免責(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)容。