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。
再按次调试,又报错如下:
这个AForge.Video.FFMPEG其实是在内部调用FFMPEG来工作的。所以这个FileNotFoundException其实是AForge.Video.FFMPEG找不到FFMPEG的文件所以抛出来的。AForge.Video.FFMPEG依赖的FFMPEG组件其实已经放在了刚刚下载下来的压缩包的\Externals\ffmpeg\bin目录下:
把这个8个文件复制到程序目录下,注意我们刚刚改过目标平台了,现在程序编译输出的目录已经是\bin\x86\Debug,不要复制错了。
再次调试又报错如下:
因为本项目目标框架是.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文件,在<configuration>和</configuration>标签中加入以下内容:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
</startup>
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文章来源:https://www.toymoban.com/news/detail-761109.html
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 属性
/// <summary>
/// 设备源
/// 用来操作摄像头
/// </summary>
private AForge.Video.DirectShow.VideoCaptureDevice videoCapture;
private AForge.Video.DirectShow.VideoCaptureDevice videoCapture2;
private AForge.Video.DirectShow.VideoCaptureDevice videoCapture3;
/// <summary>
/// 摄像头设备集合
/// </summary>
private AForge.Video.DirectShow.FilterInfoCollection infoCollection;
/// <summary>
/// 图片
/// </summary>
private System.Drawing.Bitmap imgMap;
private System.Drawing.Bitmap imgMap2;
private System.Drawing.Bitmap imgMap3;
/// <summary>
/// 文件保存路径
/// </summary>
private readonly string filePath = $"C:\\Users\\wang jun\\Desktop\\工作\\德富莱智能科技股份有限公司\\项目\\摄像头测通讯\\";
/// <summary>
/// 文件名称
/// </summary>
private string fileName = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}";
private string fileName2 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}2";
private string fileName3 = $"{DateTime.Now.ToString("yyyyMMddhhmmssffff")}3";
/// <summary>
/// 用与把每一帧图像写入到视频文件
/// </summary>
private AForge.Video.FFMPEG.VideoFileWriter videoWriter;
private AForge.Video.FFMPEG.VideoFileWriter videoWriter2;
private AForge.Video.FFMPEG.VideoFileWriter videoWriter3;
/// <summary>
/// 是否开始录像
/// </summary>
private bool IsStartVideo = false;
/// <summary>
/// 写入次数
/// </summary>
private int tick_num = 0;
/// <summary>
/// 录制多少小时,只是为了定时间计算录制时间使用
/// </summary>
private int Hour = 0;
/// <summary>
/// 计时器
/// </summary>
private System.Timers.Timer timer_count;
#endregion
#region 窗口加载与关闭
/// <summary>
/// 讲题加载事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
/// <summary>
/// 窗口关闭时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
EndCamera();
}
#endregion
#region 实例化
/// <summary>
/// 实例化摄像头
/// </summary>
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 摄像头的连接读取与关闭
/// <summary>
/// 连接按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
/// <summary>
/// 关闭按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Close_Click(object sender, EventArgs e)
{
EndCamera();
}
/// <summary>
/// 关闭摄像头
/// </summary>
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 拍照与保存
/// <summary>
/// 拍照
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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;
}
/// <summary>
/// 保存事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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 录像
/// <summary>
/// 开始录像
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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)
{
}
}
}
}
/// <summary>
/// 停止录像
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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 计时器响应函数
/// <summary>
/// 计时器
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
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
}
}
文章来源地址https://www.toymoban.com/news/detail-761109.html
到了这里,关于C#使用ffmpeg录视频和拍照的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!