AForge Video

来源:互联网 发布:手链饰品店淘宝 编辑:程序博客网 时间:2024/05/27 21:04

简介

使用AForge Video进行录像

界面

这里写图片描述

运行

这里写图片描述

代码

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;//usingusing System.IO;//Path、Directory用到using System.Timers;using AForge;using AForge.Video;using AForge.Video.DirectShow;using AForge.Video.FFMPEG;using AForge.Controls;namespace AforgeVideo{    public partial class Form1 : Form    {        private delegate void MyDelegateUI();//多线程问题        public FilterInfoCollection videoDevices = null;  //摄像头设备        public VideoCaptureDevice cam1 = null;     //视频的来源选择        public VideoFileWriter videoWriter = null;//写入到视频        public Bitmap bm1 = null;        Boolean is_record_video = false;        Boolean ifCam1 = false;        int i = 1;  //摄像头数        int hour = 0;        int tick_num = 0;        int width = 640;    //录制视频的宽度        int height = 480;   //录制视频的高度        int fps = 20;        //正常速率,fps越大速率越快,相当于快进        System.Timers.Timer timer_count;        public Form1()        {            InitializeComponent();        }        private void Form1_Load(object sender, EventArgs e)        {            //初始化按钮状态            labelScreen.Visible = false;            btnPauseVideo.Enabled = false;            btnStartVideo.Enabled = false;            btnStopVideo.Enabled = false;            btnTakePic.Enabled = false;            //设置视频编码格式            comboBox_videoecode.Items.Add("MPEG");            comboBox_videoecode.Items.Add("WMV");            comboBox_videoecode.Items.Add("FLV");            comboBox_videoecode.Items.Add("H263p");            comboBox_videoecode.Items.Add("MSMPEG4v3");            comboBox_videoecode.SelectedIndex = 0;             //设置视频来源            try            {                // 枚举所有视频输入设备                videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);                if (videoDevices.Count == 0)                    throw new ApplicationException();   //没有找到摄像头设备                foreach (FilterInfo device in videoDevices)                {                    comboBox_camera.Items.Add(device.Name);                    textBoxC.AppendText("摄像头" + i + "初始化完毕..." + "\n");                    textBoxC.ScrollToCaret();                    i++;                }                //comboBox_camera.SelectedIndex = 0;   //注释掉,选择摄像头来源的时候才会才会触发显示摄像头信息            }            catch (ApplicationException)            {                comboBox_camera.Items.Add("No local capture devices");                videoDevices = null;                MessageBox.Show("没有找到摄像头设备", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);            }            //秒表            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 comboBox_camera_SelectedIndexChanged(object sender, EventArgs e)        {            cam1 = new VideoCaptureDevice(videoDevices[comboBox_camera.SelectedIndex].MonikerString);            //cam1.DesiredFrameSize = new System.Drawing.Size(width, height);            //cam1.DesiredFrameRate = fps;            cam1.NewFrame += new NewFrameEventHandler(Cam_NewFrame1);            cam1.Start();            labelScreen.Text = "连接中...";            labelScreen.Visible = true;            ifCam1 = true;            //激活初始化按钮状态            btnTakePic.Enabled = true;            btnPauseVideo.Enabled = true;            btnStartVideo.Enabled = true;            btnStopVideo.Enabled = true;        }        private void Cam_NewFrame1(object obj, NewFrameEventArgs eventArgs)        {            pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();            bm1 = (Bitmap)eventArgs.Frame.Clone();            if (is_record_video)            {                videoWriter.WriteVideoFrame(bm1);            }        }        //计时器响应函数        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 (min%60==0)            {                hour = min / 60;                min = 0;            }            else            {                min = min - hour * 60;            }            String tick = hour.ToString() + ":" + min.ToString() + ":" + sec.ToString();            MyDelegateUI d = delegate            {                this.labelTime.Text = tick;            };            this.labelTime.Invoke(d);        }        private void btnStartVideo_Click(object sender, EventArgs e)        {            //创建一个视频文件            String video_format = comboBox_videoecode.Text.Trim(); //获取选中的视频编码            String picName = GetVideoPath() + "\\" + DateTime.Now.ToString("yyyyMMdd HH-mm-ss");            if (-1 != video_format.IndexOf("MPEG"))            {                picName = picName + ".avi";            }            else if (-1 != video_format.IndexOf("WMV"))            {                picName = picName + ".wmv";            }            else            {                picName = picName + ".mkv";            }            textBoxC.AppendText("Video保存地址:" + picName + "\n");            textBoxC.ScrollToCaret();            timer_count.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;            labelScreen.Text = "REC";            textBoxC.AppendText("录制中...\n");            is_record_video = true;            videoWriter = new VideoFileWriter();            if (cam1.IsRunning)            {                if (-1 != video_format.IndexOf("MPEG"))                {                    videoWriter.Open(picName, width, height, fps, VideoCodec.MPEG4);                }                else if (-1 != video_format.IndexOf("WMV"))                {                    videoWriter.Open(picName, width, height, fps, VideoCodec.WMV1);                }                else                {                    videoWriter.Open(picName, width, height, fps, VideoCodec.Default);                }            }            else            {                MessageBox.Show("没有视频源输入,无法录制视频。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);            }        }        private void btnStopVideo_Click(object sender, EventArgs e)        {            labelScreen.Visible = false;            this.is_record_video = false;            this.videoWriter.Close();            this.timer_count.Enabled = false;            tick_num = 0;            textBoxC.AppendText("录制停止!\n");            textBoxC.ScrollToCaret();        }        private void btnExit_Click(object sender, EventArgs e)        {            if (this.videoWriter == null)            {                //MessageBox.Show("videoWriter对象未实例化。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);                //return;                videoWriter = new VideoFileWriter();            }            if (this.videoWriter.IsOpen)            {                MessageBox.Show("视频流还没有写完,请点击结束录制。", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);                return;            }            cam1.SignalToStop();            cam1.WaitForStop();            Hide();            Close();            Dispose();        }        private void btnPauseVideo_Click(object sender, EventArgs e)        {            if (this.btnPauseVideo.Text.Trim() == "暂停录像")            {                is_record_video = false;                labelScreen.Visible = false;                btnPauseVideo.Text = "恢复录像";                timer_count.Enabled = false;    //暂停计时                return;            }            if (this.btnPauseVideo.Text.Trim() == "恢复录像")            {                is_record_video = true;                labelScreen.Visible = true;                btnPauseVideo.Text = "暂停录像";                timer_count.Enabled = true;     //恢复计时            }        }        private void btnTakePic_Click(object sender, EventArgs e)        {            if (ifCam1)            {                String filepath = GetImagePath() + "\\"+DateTime.Now.ToString("yyyyMMdd HH-mm-ss") + ".bmp";                bm1.Save(filepath);                textBoxC.AppendText("摄像头1保存:" + filepath + "\n");                textBoxC.ScrollToCaret();            }            else                MessageBox.Show("摄像头没有运行", "错误", MessageBoxButtons.OK, MessageBoxIcon.Information);        }        //获取Video相对路径?        private String GetVideoPath()        {            String personImgPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)                         + Path.DirectorySeparatorChar.ToString() + "MyVideo";            if (!Directory.Exists(personImgPath))            {                Directory.CreateDirectory(personImgPath);            }            return personImgPath;        }        //获取Img相对路径?        private String GetImagePath()        {            String personImgPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory)                         + Path.DirectorySeparatorChar.ToString() + "MyImages";            if (!Directory.Exists(personImgPath))            {                Directory.CreateDirectory(personImgPath);            }            return personImgPath;        }    }}

代码

问题

  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>

【1】在writer.Close()执行前,视频帧都是在内存中的,虽然通过writer.Open()在硬盘上也生成了文件,但是文件大小为0.。 若果长时间录制不间断,内存就会溢出。除非录制一段时间后,就把内存中的视频保存到硬盘一次。

【2】图像大小不完全显示

参考

【1】基于AForge的C#摄像头视频录制 - CSDN博客
http://blog.csdn.net/m_buddy/article/details/62417912

【2】AForge.net 使用之录像拍照功能实现 - CSDN博客
http://blog.csdn.net/chenhongwu666/article/details/41965801

【3】C# 调用AForge类库操作摄像头 - CSDN博客
http://blog.csdn.net/chenhongwu666/article/details/40594365

【4】C#实现录音录像录屏源码 - zhuweisky - 博客园
http://www.cnblogs.com/zhuweisky/p/3593917.html

【5】AForge.net 使用之录像拍照功能实现 - ching126 - 博客园
http://www.cnblogs.com/ching2009/p/4168000.html

【6】C# 下写入视频的简单实现 - CSDN博客
http://blog.csdn.net/whw8007/article/details/21232737

【7】AForge.Video.FFMPEG库使用注意事项 - liang12360640的专栏 - CSDN博客
http://blog.csdn.net/liang12360640/article/details/46044763

【8】C#:AccessViolationException: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。解决办法收集(转载) - 焦涛 - 博客园
http://www.cnblogs.com/Joetao/articles/5779328.html

原创粉丝点击