C#/기술 개발

C# EMGUCV 화면 녹화 프로그램

sheepone 2022. 10. 13. 09:35
반응형

동영상 녹화에서는 이미지를 이용하여 동영상을 만들지만

화면 녹화는 화면을 캡쳐한뒤 해당 이미지를 이용하여 동영상을 만듬.

 

1. 프로그램 화면

 

RECORD시 녹화 시작

STOP시 녹화 중지

REC - 현재 녹화중 상태 표기 (REC or STOP)

2022 - 현재 시간 표기

 

2. 동영상

 

폼위에 판넬 사이즈만큼 캡쳐한 동영상 30fps

저장 위치 C:\Rec

 

3. 코드 내용

using Emgu.CV;
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsRec
{
    public partial class Form1 : Form
    {
        Thread tUpdate     ;
        static public object RecodeLock = new object(); //녹화시와 정지시에 동기가 맞아야 한다.
        VideoWriter videoWriter;
        struct TRecPara
        {
            public bool      bNeedRecode ;
            public Rectangle rRect       ;
            public int       iFps        ;
        };
        TRecPara RecPara = new TRecPara { bNeedRecode = false };
        public Form1()
        {
            InitializeComponent();

            tUpdate = new Thread(Update); 
            tUpdate.Priority = ThreadPriority.Normal ;
            tUpdate.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = DateTime.Now.ToString("yyyy MM dd HH:mm:ss") ;

            if(RecPara.bNeedRecode) label2.Text = "REC"  ; 
            else                    label2.Text = "STOP" ;
        }

        Stopwatch swRec  = new Stopwatch();
        public void Update()
        {
            while(true)
            {
                Thread.Sleep(1);

                if (RecPara.bNeedRecode)
                {
                    if(!swRec.IsRunning) swRec.Start();
                    try
                    {
                        lock (RecodeLock)
                        {
                            if (videoWriter != null && videoWriter.IsOpened)
                            {
                                if(swRec.ElapsedMilliseconds > (1000 / RecPara.iFps))
                                {
                                    swRec.Restart();
                                    Bitmap bmp = new Bitmap(RecPara.rRect.Width, RecPara.rRect.Height,PixelFormat.Format24bppRgb);
                                    using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp))
                                    {
                                        g.CopyFromScreen(RecPara.rRect.X, RecPara.rRect.Y, 0, 0, new Size(RecPara.rRect.Width, RecPara.rRect.Height));
                                    }
                                    Mat mat = Emgu.CV.BitmapExtension.ToMat(bmp);
                                    
                                    videoWriter.Write(mat);
                                }
                            }
                        }
                    }
                    catch
                    {
                        Debug.WriteLine("Error VideoWriter");
                    }

                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false ;

            RecPara.bNeedRecode  = true                                          ;
            Point pPoint = this.PointToScreen(new Point(panel1.Left, panel1.Top));
            RecPara.rRect.X      = pPoint.X                                      ;
            RecPara.rRect.Y      = pPoint.Y                                      ;
            RecPara.rRect.Width  = panel1.Width  /4*4                            ;
            RecPara.rRect.Height = panel1.Height /4*4                            ;
            RecPara.iFps         = 30                                            ;

            string sPath = "C:\\Rec\\" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".avi";//".avi"; //".mp4";//".avi";
            if (!Directory.Exists(Path.GetDirectoryName(sPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(sPath));
            }
            //string sFourcc = "XVID";//"H264";//"XVID";//"DP02";
            string sFourcc = "MPEG";//"H264";//"XVID";//"DP02";

            int iFourcc = VideoWriter.Fourcc(sFourcc[0], sFourcc[1], sFourcc[2], sFourcc[3]);
            //int iFourcc = 0 ; //0일때 무손실 압축 

            videoWriter = new VideoWriter(sPath, iFourcc, RecPara.iFps, new Size(RecPara.rRect.Width, RecPara.rRect.Height), true);
            videoWriter.Set(VideoWriter.WriterProperty.Quality, 100); //0~100%

            button1.Enabled = true  ;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            lock (RecodeLock) //녹화와 동기 문제로 없으면 뻑남
            {
                try
                {
                    RecPara.bNeedRecode = false;
                    if (videoWriter != null) {
                        videoWriter.Dispose();
                    }
                }
                catch
                {
                    Debug.WriteLine("Error videoWriter");
                }
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            tUpdate.Abort();
            tUpdate.Join();
        }
    }
}

 

4. 소스파일

WindowsFormsRec.zip.001
19.00MB
WindowsFormsRec.zip.002
19.00MB
WindowsFormsRec.zip.003
8.58MB

반응형