C#使用ffmpeg录视频和拍照

您所在的位置:网站首页 jpeg文件是用于为图像提供一种有损耗压缩的文件 C#使用ffmpeg录视频和拍照

C#使用ffmpeg录视频和拍照

#C#使用ffmpeg录视频和拍照| 来源: 网络整理| 查看: 265

c#使用ffmpeg调用aforge引用包实现摄像设备拍照及录像

1.添加引用

AForge.dll 是框架的核心基础类库,为其他类库提供服务。 AForge.Controls.dll 包含AForge.Net的UI控件,主要用于页面显示。 AForge.Imaging.dll 主要是框架中用于图像处理的类库,主要负责图像的处理 AForge.Video.dll 主要是框架中对视频处理的类库。 AForge.Video.DirectShow.dll 主要是通过DirectShow接口访问视频资源的类库。AForge.Video.FFMPEG.dll 是一个还未正式发布的类库,通过FFMPEG类库对视频进行读写。

但是特别注意,vs的NGet目前没有AForge.Video.FFMPEG.dll,你得去AForge官网或者第三方平台http://www.aforgenet.com/framework/downloads.html里下载,可以用迅雷之类的下载器下载,他们的离线下载是可以翻墙的。

选择了“Download Installer”,右键“复制链接地址”,然后放进迅雷下载。

下载下来之后是一个压缩包,AForge.Video.FFMPEG.dll就放在压缩包的Release文件夹中。

2.调用(注意有坑)

引用运行报错如下:

因为这个AForge.Video.FFMPEG使用VC++写的,编译的时候已经被编译成本地代码,而我们现在C#一般目标平台都是“Any CPU”,所以会发生这个问题。

解决办法不再使用“Any CPU”作为目标平台,改成“x86”或者“x64”。因为x86可以跑在x64上,而x64不能在x86上跑,所以我选择了x86。

 再按次调试,又报错如下:

4bad3f7428a4fb3373d4aec07ee0a83d.png

这个AForge.Video.FFMPEG其实是在内部调用FFMPEG来工作的。所以这个FileNotFoundException其实是AForge.Video.FFMPEG找不到FFMPEG的文件所以抛出来的。AForge.Video.FFMPEG依赖的FFMPEG组件其实已经放在了刚刚下载下来的压缩包的\Externals\ffmpeg\bin目录下:

de1e077ebfa72a66e8d76dabd6307273.png 

把这个8个文件复制到程序目录下,注意我们刚刚改过目标平台了,现在程序编译输出的目录已经是\bin\x86\Debug,不要复制错了。

再次调试又报错如下:

b92615bfcc07047a809f3f5f78fa103d.png 

因为本项目目标框架是.net Framework 4.0,而AForge官方在编译AForge.Video.FFMPEG.dll的时候,目标框架选的是.net Framework 2.0……

解决方案有三种:

1.降低自己项目的目标.net Framework版本;

2.修改Config文件;

3.重新编译Video.FFMPEG。

这里我就讲一下方法二,

在Visual Studio中按Ctrl+Shift+A,打开“添加新项”窗口,选择“应用程序配置文件”,再点击“添加”(vs2017创建的时候已经自带了App.config无需再次添加)

打开新建的App.Config文件,在和标签中加入以下内容:

     

4c86904d87e6c71a633ccaa03522717a.png 

3.界面UI设计:

这里解释以下界面组成及控件使用 此界面分上下两部分,其中上半部分分左,中,右三个(这里讲解左,其它类似) 上部分由一个GroupBox包裹一个AForge.NET工具包下VideoSourcePlayer控件命名为vsp_Panel组成 中间部分由一个Label,一个ComBox下拉框cb_CameraSelect,两个Button按钮btn_Connect、btn_Close组成 下部分由一个GroupBox包裹一个AForge.NET工具包下PictureBox控件命名为gb_CapturePanel组成 界面下部分由由一个GroupBox包裹5个Button按钮btn_StartVideo、btn_PauseVideo、btn_EndVideo、btn_Capture、btn_Save。以及两个label,其中录制时间: 这个label命名无所谓后续用不到,而另外一个默认显示为00:00:00的label命名为lab_Time

 4.完整代码如下: 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; namespace Camera { public partial class Form1 : Form { public Form1() { InitializeComponent(); } #region 属性 /// /// 设备源 /// 用来操作摄像头 /// private AForge.Video.DirectShow.VideoCaptureDevice videoCapture; private AForge.Video.DirectShow.VideoCaptureDevice videoCapture2; private AForge.Video.DirectShow.VideoCaptureDevice videoCapture3; /// /// 摄像头设备集合 /// private AForge.Video.DirectShow.FilterInfoCollection infoCollection; /// /// 图片 /// private System.Drawing.Bitmap imgMap; private System.Drawing.Bitmap imgMap2; private System.Drawing.Bitmap imgMap3; /// /// 文件保存路径 /// private readonly string filePath = $"C:\\Users\\wang jun\\Desktop\\工作\\德富莱智能科技股份有限公司\\项目\\摄像头测通讯\\"; /// /// 文件名称 /// private string fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}"; private string fileName2 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}2"; private string fileName3 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}3"; /// /// 用与把每一帧图像写入到视频文件 /// private AForge.Video.FFMPEG.VideoFileWriter videoWriter; private AForge.Video.FFMPEG.VideoFileWriter videoWriter2; private AForge.Video.FFMPEG.VideoFileWriter videoWriter3; /// /// 是否开始录像 /// private bool IsStartVideo = false; /// /// 写入次数 /// private int tick_num = 0; /// /// 录制多少小时,只是为了定时间计算录制时间使用 /// private int Hour = 0; /// /// 计时器 /// private System.Timers.Timer timer_count; #endregion #region 窗口加载与关闭 /// /// 讲题加载事件 /// /// /// private void Form1_Load(object sender, EventArgs e) { InitCamera(); InitCameraSelect(); this.btn_Capture.Enabled = false; this.btn_Save.Enabled = false; this.gb_CapturePanel.SizeMode = PictureBoxSizeMode.Zoom;//图片大小按比例适应控件,不加的话图片显示问题太大 this.gb_CapturePanel.Visible = false;//默认不显示照片区域,拍照时在显示 //秒表 this.gb_CapturePanel2.SizeMode = PictureBoxSizeMode.Zoom; this.gb_CapturePanel2.Visible = false; this.gb_CapturePanel3.SizeMode = PictureBoxSizeMode.Zoom; this.gb_CapturePanel3.Visible = false; timer_count = new System.Timers.Timer(); //实例化Timer类,设置间隔时间为1000毫秒; timer_count.Elapsed += new System.Timers.ElapsedEventHandler(tick_count); //到达时间的时候执行事件; timer_count.AutoReset = true; //设置是执行一次(false)还是一直执行(true); timer_count.Interval = 1000; } /// /// 窗口关闭时 /// /// /// private void Form1_FormClosing(object sender, FormClosingEventArgs e) { EndCamera(); } #endregion #region 实例化 /// /// 实例化摄像头 /// public void InitCamera() { try { //检测电脑上的摄像头设备 infoCollection = new AForge.Video.DirectShow.FilterInfoCollection(AForge.Video.DirectShow.FilterCategory.VideoInputDevice); } catch (Exception ex) { MessageBox.Show($"没有找到设备:{ex.Message}", "Error"); } } //加载摄像头选择 public void InitCameraSelect() { this.cb_CameraSelect.DropDownStyle = ComboBoxStyle.DropDownList; this.cb_CameraSelect2.DropDownStyle = ComboBoxStyle.DropDownList; this.cb_CameraSelect3.DropDownStyle = ComboBoxStyle.DropDownList; //根据读取到的摄像头加载选择项 foreach (AForge.Video.DirectShow.FilterInfo item in infoCollection) { this.cb_CameraSelect.Items.Add(item.Name); this.cb_CameraSelect2.Items.Add(item.Name); this.cb_CameraSelect3.Items.Add(item.Name); } cb_CameraSelect.Text = (string)cb_CameraSelect.Items[0]; cb_CameraSelect2.Text = (string)cb_CameraSelect.Items[1]; //需要改动cb_CameraSelect3.Text = (string)cb_CameraSelect.Items[2]; cb_CameraSelect3.Text = (string)cb_CameraSelect.Items[0]; } #endregion #region 摄像头的连接读取与关闭 /// /// 连接按钮 /// /// /// private void btn_Connect_Click(object sender, EventArgs e) { var CameraSelect = this.cb_CameraSelect.Text; var selectIndex = this.cb_CameraSelect.SelectedIndex; var selectIndex2 = this.cb_CameraSelect2.SelectedIndex; var selectIndex3 = this.cb_CameraSelect3.SelectedIndex; //已有连接的摄像头时先关闭 if (videoCapture != null|| videoCapture2 !=null|| videoCapture3 !=null) { EndCamera(); } videoCapture = new AForge.Video.DirectShow.VideoCaptureDevice(infoCollection[selectIndex].MonikerString); videoCapture2 = new AForge.Video.DirectShow.VideoCaptureDevice(infoCollection[selectIndex2].MonikerString); videoCapture3 = new AForge.Video.DirectShow.VideoCaptureDevice(infoCollection[selectIndex3].MonikerString); //启动摄像头 this.vsp_Panel.VideoSource = videoCapture; this.vsp_Panel2.VideoSource = videoCapture2; this.vsp_Panel3.VideoSource = videoCapture3; this.vsp_Panel.Start(); this.vsp_Panel2.Start(); this.vsp_Panel3.Start(); this.btn_Capture.Enabled = true; this.btn_Save.Enabled = false; } /// /// 关闭按钮 /// /// /// private void btn_Close_Click(object sender, EventArgs e) { EndCamera(); } /// /// 关闭摄像头 /// public void EndCamera() { if (this.vsp_Panel.VideoSource != null) { //也可以用 Stop() 方法关闭 //指示灯停止且等待 this.vsp_Panel.SignalToStop(); this.vsp_Panel.WaitForStop();//停止且等待 this.vsp_Panel.VideoSource = null; } if (this.vsp_Panel2.VideoSource != null) { this.vsp_Panel2.SignalToStop(); this.vsp_Panel2.WaitForStop(); this.vsp_Panel2.VideoSource = null; } if (this.vsp_Panel3.VideoSource != null) { this.vsp_Panel3.SignalToStop(); this.vsp_Panel3.WaitForStop(); this.vsp_Panel3.VideoSource = null; } } #endregion #region 拍照与保存 /// /// 拍照 /// /// /// private void btn_Capture_Click(object sender, EventArgs e) { imgMap = this.vsp_Panel.GetCurrentVideoFrame(); imgMap2 = this.vsp_Panel2.GetCurrentVideoFrame(); imgMap3 = this.vsp_Panel3.GetCurrentVideoFrame(); this.gb_CapturePanel.Visible = true; this.gb_CapturePanel2.Visible = true; this.gb_CapturePanel3.Visible = true; this.gb_CapturePanel.Image = imgMap; this.gb_CapturePanel2.Image = imgMap2; this.gb_CapturePanel3.Image = imgMap3; this.btn_Save.Enabled = true; } /// /// 保存事件 /// /// /// private void btn_Save_Click(object sender, EventArgs e) { var saveName = $"{filePath}{fileName}.jpg"; imgMap.Save(saveName); var saveName2 = $"{filePath}{fileName2}.jpg"; imgMap2.Save(saveName2); var saveName3 = $"{filePath}{fileName3}.jpg"; //需改动imgMap3.Save(saveName3); this.btn_Save.Enabled = false; fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}"; fileName2 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}2"; fileName3 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}3"; //MessageBox.Show($"保存成功"); } #endregion #region 录像 /// /// 开始录像 /// /// /// private void btn_StartVideo_Click(object sender, EventArgs e) { this.lab_Time.Text="00:00:00"; string videoName = $"{filePath}{fileName}.mp4"; string videoName2 = $"{filePath}{fileName2}.mp4"; string videoName3 = $"{filePath}{fileName3}.mp4"; IsStartVideo = true; //开始计时 timer_count.Enabled = true; //配置录像参数(宽,高,帧率,比特率等参数)VideoCapabilities这个属性会返回摄像头支持哪些配置,从这里面选一个赋值接即可 videoCapture.VideoResolution = videoCapture.VideoCapabilities[0]; videoCapture2.VideoResolution = videoCapture2.VideoCapabilities[0]; videoCapture3.VideoResolution = videoCapture3.VideoCapabilities[0]; //设置回调,aforge会不断从这个回调推出图像数据 videoCapture.NewFrame += Camera_NewFrame; videoCapture2.NewFrame += Camera_NewFrame2; videoCapture3.NewFrame += Camera_NewFrame3; videoWriter = new AForge.Video.FFMPEG.VideoFileWriter(); videoWriter2 = new AForge.Video.FFMPEG.VideoFileWriter(); videoWriter3 = new AForge.Video.FFMPEG.VideoFileWriter(); //打开摄像头 //打开录像文件(如果没有则创建,如果有也会清空),这里还有关于视频宽高、帧率、格式、比特率 videoWriter.Open( videoName, videoCapture.VideoResolution.FrameSize.Width, videoCapture.VideoResolution.FrameSize.Height, //videoCapture.VideoResolution.AverageFrameRate, 6,//帧率 AForge.Video.FFMPEG.VideoCodec.MPEG4, videoCapture.VideoResolution.BitCount ); videoWriter2.Open( videoName2, videoCapture2.VideoResolution.FrameSize.Width, videoCapture2.VideoResolution.FrameSize.Height, //videoCapture.VideoResolution.AverageFrameRate, 6,//帧率 AForge.Video.FFMPEG.VideoCodec.MPEG4, videoCapture2.VideoResolution.BitCount ); videoWriter3.Open( videoName3, videoCapture3.VideoResolution.FrameSize.Width, videoCapture3.VideoResolution.FrameSize.Height, //videoCapture.VideoResolution.AverageFrameRate, 6,//帧率 AForge.Video.FFMPEG.VideoCodec.MPEG4, videoCapture3.VideoResolution.BitCount ); } //摄像头1输出回调 private void Camera_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs) { imgMap = eventArgs.Frame; lock (imgMap) { if (eventArgs != null && eventArgs.Frame != null) { try { //写到文件 videoWriter.WriteVideoFrame(eventArgs.Frame); } catch (Exception ex) { } } } } //摄像头2输出回调 private void Camera_NewFrame2(object sender, AForge.Video.NewFrameEventArgs eventArgs) { imgMap2 = eventArgs.Frame; lock (imgMap2) { if (eventArgs != null && eventArgs.Frame != null) { try { //写到文件 videoWriter2.WriteVideoFrame(eventArgs.Frame); } catch (Exception ex) { } } } } //摄像头3输出回调 private void Camera_NewFrame3(object sender, AForge.Video.NewFrameEventArgs eventArgs) { imgMap3 = eventArgs.Frame; lock (imgMap3) { if (eventArgs != null && eventArgs.Frame != null) { try { //写到文件 //需改动videoWriter3.WriteVideoFrame(eventArgs.Frame); } catch (Exception ex) { } } } } /// /// 停止录像 /// /// /// private void btn_EndVideo_Click(object sender, EventArgs e) { IsStartVideo = false; timer_count.Enabled = false; videoWriter.Close(); videoWriter2.Close(); videoWriter3.Close(); fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}"; fileName2 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}2"; fileName3 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}3"; MessageBox.Show("停止录像"); HourStr="00"; MinuteStr = "00"; SecondStr = "00"; tick_num = 0; } #endregion string HourStr =null; string MinuteStr=null; string SecondStr=null; #region 计时器响应函数 /// /// 计时器 /// /// /// public void tick_count(object source, System.Timers.ElapsedEventArgs e) { tick_num++; int Temp = tick_num; int Second = Temp % 60; int Minute = Temp / 60; if (Minute % 60 == 0) { Hour = Minute / 60; Minute = 0; } else { Minute = Minute - Hour * 60; } HourStr = Hour < 10 ? $"0{Hour}" : Hour.ToString(); MinuteStr = Minute < 10 ? $"0{Minute}" : Minute.ToString(); SecondStr = Second < 10 ? $"0{Second}" : Second.ToString(); String tick = $"{HourStr}:{MinuteStr}:{SecondStr}"; this.Invoke((EventHandler)(delegate { this.lab_Time.Text = tick; })); } #endregion } }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3