Home / C# / How to record a video with C# – WPF and AForge

How to record a video with C# – WPF and AForge

In this article we will see how to record a video and a snapshot from a camera (USB or IP camera), with C# and AForge.
AForge is a library used for image acquisition and Image Processing, for example to analyse images and detect objects with a Camera.

In a previous article, we already saw how to recognize shapes and colours from an image taken from a Camera in real time.
When using image processing, being able to record video and save screenshots is helpful to debug the application and understand what is happening with the image-processing algorithm.

Watch the video on YouTube

Download the FFmpeg library

To record a video you need a library called Accord.Video.FFmpeg. You can get it from NuGet.

This library is a mirror of AForge.Video.FFmpeg, which wasn’t deployed on NuGet because of the GPL license, which is different from all other AForge licenses (LGPL).

The license of FFMpeg is GPL or LGPL, depending on how it is compiled. You can read about the licensing here: https://www.ffmpeg.org/legal.html

To keep it short, it says that you can use the library for your business, but they can’t guarantee that the algorithms they use are not under copyright.

Recording the video: how to create a video file

To record a video you need two actions: Start recording and Stop recording.

When you start recording, you need to create a file with the class VideoFileWriter.
The file needs to know the height and width of the images that it’s going to store, so we will use the Image size that comes directly from the camera.

This is the code to create the video file:

private VideoFileWriter _writer;

...

_writer = new VideoFileWriter();
_writer.Open(dialog.FileName, (int)Math.Round(Image.Width, 0), 
              (int)Math.Round(Image.Height, 0));

If you need to specify the codecs used to compress the video, you can use one of the many overloads of the method Open. There is also the possibility to specify other parameters of the recording.

public void Open(string fileName, int width, int height);

public void Open(string fileName, int width, int height, int frameRate);

public void Open(string fileName, int width, int height, int frameRate, 
                 VideoCodec codec);

public void Open(string fileName, int width, int height, int frameRate, 
                 VideoCodec codec, int bitRate);

public void Open(string fileName, int width, int height, int frameRate, 
                 VideoCodec codec, int bitRate, AudioCodec audioCodec, 
                 int audioBitrate, int sampleRate, int channels);

How to add images to the video file

A video is just a quick succession of images displayed with the right timing. That’s why we have to add the images that we receive from the camera while recording the video.

Every time we add an image we have also to specify at what time this image has to be displayed.

We already saw in a previous article that AForge uses a callback mechanism to notify that a new image is arrived.

We will use the callback to add the images to the file.
The video starts when we add the first image, that’s why we have to store the time of the start in a variable.
When we receive more images from the camera and add them to the video, we also have to specify the time that we received them.

Here is the code used on the callback both for the first image and for consecutive ones:

try
{
    if (_recording)
    {
        if (_firstFrameTime != null)
        {
            _writer.WriteVideoFrame(eventArgs.Frame, DateTime.Now - _firstFrameTime.Value);
        }
        else
        {
            _writer.WriteVideoFrame(eventArgs.Frame);
            _firstFrameTime = DateTime.Now;
        }
    }
...

How to stop recording and close the video file

To stop the video, we have to save and close the file. We also must Dispose the VideoFileWriter to release the unmanaged resources.

Here is the code on how to stop the video:

private void StopRecording()
{
    _recording = false;
    _writer.Close();
    _writer.Dispose();
}

How to save a snapshot

When receiving a stream of images from a camera, it is also possible to save a single image.

To do this we just need to use WPF libraries and in particular PngBitmapEncoder class and BitmapFrame.Create method.

Here is the code to save a WPF BitmapImage to a file:

var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(Image));
using (var filestream = new FileStream(dialog.FileName, FileMode.Create))
{
encoder.Save(filestream);
}

Download the sample application

You can download the sample application on GitHub.

23 comments

  1. hey guy can u help me ? i use your code but i got problem when i record video i got error , error messeng “access violation exception” addition i got bad memory , i no idea for solve helpme pls
    sry for bad eng and thank you for help

    • Does it happen in the sample application? I can’t reproduce the problem.

      • Yes happen in sample application

        • Does it happen when you start the camera? Or when you start the recording / during the recording? It seems that another application tries to access to the camera.

      • I don’t seen any acees cameara but i see my camera deviecs it stack not clear devies ex. Blackmagic wd(1) when i close and start program Blackmagic wd(2)

        • When the sample application is closed, it also dispose the camera by calling _videoSource.Stop();
          Maybe it is not enough and you have to use also SignalToStop and wait for stop, or similar methods.
          Anyway if you can’t start the camera it’s because someone else is using it.

  2. My camera is external camera ex. Ptz camera when close program PTZ camera not close and i use sinaltostop

  3. When I set this IpAdress http : “172.31.245.60:8080” , it gives me nothing ,Well I would like to know How can i solve this issue ?
    Thanks Mesta

  4. Hello mesta,Ihave this three mistakes ,so i dont now the probleme extactly.

    Erreur 2 Erreur de syntaxe, ‘:’ attendu C:\Users\prtintscure\Documents\Visual Studio 2013\Projects\Auto-detct\Recording-video-with-c–master\VideoRecorder\MainWindowViewModel.cs 248 22 VideoRecorder
    Erreur 3 Le nom “MainWindowViewModel” n’existe pas dans l’espace de noms “clr-namespace:VideoRecorder”. C:\Users\prtintscure\Documents\Visual Studio 2013\Projects\Auto-detct\Recording-video-with-c–master\VideoRecorder\MainWindow.xaml 12 9 VideoRecorder
    Erreur 6 Seuls une assignation, un appel, un incrément, un décrément, une attente et des expressions d’objet new peuvent être utilisés comme instruction C:\Users\prtintscure\Documents\Visual Studio 2013\Projects\Auto-detct\Recording-video-with-c–master\VideoRecorder\MainWindowViewModel.cs 248 13 VideoRecorder
    Erreur 1 Terme d’expression non valide ‘.’ C:\Users\prtintscure\Documents\Visual Studio 2013\Projects\Auto-detct\Recording-video-with-c–master\VideoRecorder\MainWindowViewModel.cs 248 21 VideoRecorder

  5. Thank you mesta, i will install VS 2015 today inchealah .

  6. Stefan Krömer

    Hello, first of all a big compliment and thanks for the very good examples. However, I have with this a problem. Everything runs without problems on the development computer. On other computers I do not get a camera image. All computers have W10, 1803. I use VS2017.

    When I deactivate the following code, I get a video image:

    if (_recording)
    {
    using (var bitmap = (Bitmap) eventArgs.Frame.Clone())
    {
    if (_firstFrameTime != null)
    {
    _writer.WriteVideoFrame(bitmap, DateTime.Now – _firstFrameTime.Value);
    }
    else
    {
    _writer.WriteVideoFrame(bitmap);
    _firstFrameTime = DateTime.Now;
    }
    }
    }

    I have tried different versions of the framework. I have deleted all AFORGE assemblies and only use Accord… Nothing helps.

    Interestingly, if I don’t use a viewmodel, but code-behind, everything works.

    Any ideas?

    Thank you very much!

  7. I am trying to record a real time video for my GUI using C# and emgucv in visual studio 2013 on 64 bits OS.But my code is not working .

    I am sending the block of code.

    recording = true;
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    //dialog.Filter = “Avi Files (*.avi)|*.avi”;
    saveFileDialog1.Filter = “Avi Files (*.avi)|*.avi”;
    // dialog.DefaultExt = “.MP4”;
    saveFileDialog1.AddExtension = true;
    saveFileDialog1.FileName = DateTime.Now.ToString();
    DialogResult dialogResult = saveFileDialog1.ShowDialog();
    if (dialogResult != DialogResult.OK)
    {
    return;
    }
    //videoWriter = new VideoWriter(dialog.FileName, 30, new Size(capture.Width, capture.Height), true);

    Image ImageFrame = capture.QuerySmallFrame().ToImage();
    // Image ImageFrame = capture.QuerySmallFrame().ToImage();
    //ImageFrame = capture.QueryFrame();
    // int width = Convert.ToInt32(imageBox1.Width);
    // int height = Convert.ToInt32(imageBox1.Height);

    // fourcc = cv2.VideoWriter_fourcc(*’XVID’);
    //out = cv2.VideoWriter(‘output.avi’,fourcc, 20.0, (640,480));
    videoWriter = new VideoWriter(saveFileDialog1.FileName, VideoWriter.Fourcc(‘M’, ‘P’, ‘4’, ‘2’), 20, new System.Drawing.Size(ImageFrame.Width, ImageFrame.Height), true);

  8. I am trying to record a real time video for my GUI using C# and emgucv in visual studio 2013 on 64 bits OS.But my code is not working .

    I am sending the block of code.

    recording = true;
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    //dialog.Filter = “Avi Files (*.avi)|*.avi”;
    saveFileDialog1.Filter = “Avi Files (*.avi)|*.avi”;
    // dialog.DefaultExt = “.MP4”;
    saveFileDialog1.AddExtension = true;
    saveFileDialog1.FileName = DateTime.Now.ToString();
    DialogResult dialogResult = saveFileDialog1.ShowDialog();
    if (dialogResult != DialogResult.OK)
    {
    return;
    }
    //videoWriter = new VideoWriter(dialog.FileName, 30, new Size(capture.Width, capture.Height), true);

    Image ImageFrame = capture.QuerySmallFrame().ToImage();
    // Image ImageFrame = capture.QuerySmallFrame().ToImage();
    //ImageFrame = capture.QueryFrame();
    // int width = Convert.ToInt32(imageBox1.Width);
    // int height = Convert.ToInt32(imageBox1.Height);

    // fourcc = cv2.VideoWriter_fourcc(*’XVID’);
    //out = cv2.VideoWriter(‘output.avi’,fourcc, 20.0, (640,480));
    videoWriter = new VideoWriter(saveFileDialog1.FileName, VideoWriter.Fourcc(‘M’, ‘P’, ‘4’, ‘2’), 20, new System.Drawing.Size(ImageFrame.Width, ImageFrame.Height), true);

  9. I am trying to record a real time video for my GUI using C# and emgucv in visual studio 2013 on 64 bits OS.But my code is not working .
    Please need a help from you.
    I am sending the block of code.

    recording = true;
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    //dialog.Filter = “Avi Files (*.avi)|*.avi”;
    saveFileDialog1.Filter = “Avi Files (*.avi)|*.avi”;
    // dialog.DefaultExt = “.MP4”;
    saveFileDialog1.AddExtension = true;
    saveFileDialog1.FileName = DateTime.Now.ToString();
    DialogResult dialogResult = saveFileDialog1.ShowDialog();
    if (dialogResult != DialogResult.OK)
    {
    return;
    }
    //videoWriter = new VideoWriter(dialog.FileName, 30, new Size(capture.Width, capture.Height), true);

    Image ImageFrame = capture.QuerySmallFrame().ToImage();
    // Image ImageFrame = capture.QuerySmallFrame().ToImage();
    //ImageFrame = capture.QueryFrame();
    // int width = Convert.ToInt32(imageBox1.Width);
    // int height = Convert.ToInt32(imageBox1.Height);

    // fourcc = cv2.VideoWriter_fourcc(*’XVID’);
    //out = cv2.VideoWriter(‘output.avi’,fourcc, 20.0, (640,480));
    videoWriter = new VideoWriter(saveFileDialog1.FileName, VideoWriter.Fourcc(‘M’, ‘P’, ‘4’, ‘2’), 20, new System.Drawing.Size(ImageFrame.Width, ImageFrame.Height), true);

  10. I am trying to record a real time video for my GUI using C#
    and emgucv in visual studio 2013 on 64 bits OS.But my code is not working .

    Please give me some solution of that.Need urgent help.

    I am sending the block of code.

    recording = true;
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    //dialog.Filter = “Avi Files (*.avi)|*.avi”;
    saveFileDialog1.Filter = “Avi Files (*.avi)|*.avi”;
    // dialog.DefaultExt = “.MP4”;
    saveFileDialog1.AddExtension = true;
    saveFileDialog1.FileName = DateTime.Now.ToString();
    DialogResult dialogResult = saveFileDialog1.ShowDialog();
    if (dialogResult != DialogResult.OK)
    {
    return;
    }
    //videoWriter = new VideoWriter(dialog.FileName, 30, new Size(capture.Width, capture.Height), true);

    Image ImageFrame = capture.QuerySmallFrame().ToImage();
    // Image ImageFrame = capture.QuerySmallFrame().ToImage();
    //ImageFrame = capture.QueryFrame();
    // int width = Convert.ToInt32(imageBox1.Width);
    // int height = Convert.ToInt32(imageBox1.Height);

    // fourcc = cv2.VideoWriter_fourcc(*’XVID’);
    //out = cv2.VideoWriter(‘output.avi’,fourcc, 20.0, (640,480));
    videoWriter = new VideoWriter(saveFileDialog1.FileName, VideoWriter.Fourcc(‘M’, ‘P’, ‘4’, ‘2’), 20, new System.Drawing.Size(ImageFrame.Width, ImageFrame.Height), true);

  11. Using this example after some interval how to remove a image frame from video?

  12. Big thanks for giving this tutorial. Coding is straightforward and comprehensive.
    Unfortunatly, mvvmlight throws an exception that WeakActions.cs were missing.
    After adding this manually WeakActions.cs itself throws an exception. Frustrating.
    See screenshot:
    https://ibb.co/ZcZ1pJw
    Any help would be appreciated. Merry x-Mas

  13. coding is working for me, how to change out video from .ts to mp4?

  14. Please help
    Unable to cast object of type ‘AForge.Video.DirectShow.VideoCaptureDevice’ to type ‘Accord.Video.IVideoSource’.

Leave a Reply

Your email address will not be published.