本文為大家分享了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. 實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
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對其進行配置,使其對前版本的兼容,配置如下(這是我添加的配置):
1
2
3
4
|
<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