Capturing webcam using DirectShow.NET library


I’m using DirectShow.NET library to capture and preview all webcams connected to my PC.

Download Demo | Download Source Code | Latest file available here (.msi)

Origianl Source code of DirectShow.NET Library edited by Muaz Khan

What is DirectShow.NET?

DirectShow.NET is a library for manage code (.NET framework) that allows developers access (preview/capture) video devices (webcams, TV-tunnels, scanners etc.) by using simple objects like enums, structs and interfaces. Developers don’t have to worry about filters, memory addresses, and GUIDs as C++ and COM developers do all these things manually.

Filters filters = new Filters();

Filters” class do following jobs:

  1. Track all video devices attached to your PC
  2. Track all audio devices attached to your PC
  3. Track all video compressors
  4. Track all audio compressors

To access first video device (webcam) and first audio device connected to your PC:

Capture capture = new Capture(
    filters.VideoInputDevices[0],
    filters.AudioInputDevices[0]
);

By setting “PreviewWindow” property; you can preview the captured video into a panel or in any container windows forms control:

capture.PreviewWindow = panel;

In the above line, “panel” is System.Windows.Forms.Panel object.

And your last task is start previewing the video stream!

capture.Start();

To save the captured video into the Disk device; you’ve to set “FileName” property:

if (!capture.Cued) capture.Filename = "captured-video.wmv";

For tracking second or third video or audio device connected to your PC, just increment the index:

Capturecapture = new Capture(
    filters.VideoInputDevices[increment_index],
    filters.AudioInputDevices[increment_index]
);

It is better to use first audio device (index: 0) if all webcams are placed in the same room.

In case, when there is no video device attached to your PC, the program will throw an error. I recommend you use this technique instead of using try-catch blocks to handle the error:

if (filters.VideoInputDevices != null)
{

// all code goes here

}

To stop streaming (previewing or capturing into disk):

capture.Stop();

To capture as quickly as possible, use “capture.Cue()” method:

capture.Cue();

capture.Start();

This will speedup streaming/capturing into disk.

In the demo project, I’m not only previewing and capturing into disk but also using timer to automatically change file name after each 10 minutes.

I’m using timer because the size of video file goes into GB after some time; so we’ve to split video files for FTP upload or other uses!

timer.Interval = 600000; // 10 minutes!

In the “Tick” event of the “timer” object:

counter++;
if (!capture.Cued) capture.Filename = counter + ".wmv";

Where I’m incrementing “counter” object on each tick.

I’m capturing video into “WMV” file; you can also use “AVI” or other supported formats.

DirectShow supports ASF, WMA, WMV, AIFF, AU, AVI, MIDI, SND, and WAV video formats.

You can also compress the video:

capture.VideoCompressor = filters.VideoCompressors[0];
capture.AudioCompressor = filters.AudioCompressors[0];

DirectShow supports compression formats such as H.264, AAC, Cinepak, DV (Digital Video), ISO MPEG-4 video version 1.0, Microsoft MPEG-4 version 3, MJPEG, MPEG Audio Layer-3 (MP3) (decompression only), MPEG-1 layer I and layer II audio, MPEG-1 video, MPEG-2 audio, and MPEG-2 video.You can also use third party codecs.

Downloads:

  1. Download DirectShow.NET Library
  2. Download Demo
  3. Download Source Code of the Demo Project
  4. Origianl Source code of DirectShow.NET Library edited by Muaz Khan

Updated at March 1, 2013:

You can set width and height of the “panel” element to control frame size (i.e. min/max width/height) of the preview screen:

panel.Width = this.Width;
panel.Height = this.Height;

Above two lines will set panel’s width and height equal to current window’s width and height.

47 thoughts on “Capturing webcam using DirectShow.NET library

  1. hi
    hi,
    i am doing a bsc computer science project.I had used your DShowNET.dll to capture video.I had created a file 1.wmv using it.but when i tried to take it to database it says a process is already using this file.How to solve this? also how to use 3rd party decoders?

  2. Hi Anoop Rajasekharan,

    Did you call “capture.stop” to stop recording in that file?

    Windows 7 uses its own codecs for decoding several audio and video formats. Using third party DirectShow filters instead of the native filters is not possible without making difficult changes to the Windows Registry.

    The Win7DSFilterTweaker tool allows you to configure your preferred DirectShow decoders with just a few mouse clicks. It is quick, easy, and changes can always be undone.

    http://codecguide.com/windows7_preferred_filter_tweaker.htm

    1. yes i had called capture.Stop();But it will not unload 1.wmv.I had checked your source code it works but every time i call for record a second window appears showing camera video.Is it possible to record video without showing second window.i am using windows 8.Is it possible to add a 3rd party dll and point out this dll as compressor from DShowNET.At present in dll shows
      0 – Cinepack
      1- DV video encoder
      2- Fraps Decompressor
      3- Intel iyuv
      4- intel iyuv
      5- Microsfot RE
      6- Microsoft Video 1
      7- mjpeg
      8- ms screen 9 encoder dmo
      9- wmv 8 encoder dmo
      10- wmv 9 encoder dmo
      will this change according to os ?
      Any solution ?

  3. thanks for replay.can you share the source code of DirectShow(Modified version by you)and also compilation procedure so i can compile it in visual studio 2012.Is it possible to use DirectShow to play video files captured by it ?

  4. Hello muaz,

    thanks a lot for this code! I searched several ages for a solution but u give me the right direction.

    I have one question, on my cam (a lil old one with a bad resolution) it works fine with a 800 x 600 frame, on a really good cam (hd resolution) the panel grows up (over the border of the screen)… I set the size with “FrameSize = new Size(…)” but it change nothing.

    What can I do to set a hard resolution for all cams? Maybe I have make something with the device? Please help me out with this.

    Thank you again,
    best regards!

    Basty

  5. Hi Bastian Friedrich,

    You can set preview panel by calling “capture.PreviewWindow=panel“.
    So, “panel” is a wrapper or container element that you used to preview the captured stream.

    You can set width and height of that “panel” element to control frame size (i.e. min/max width/height) of the preview screen:

    panel.Width = this.Width;
    panel.Height = this.Height;

    Above two lines will set panel’s width and height equal to current window’s width and height.

  6. Hi, very good job! Thanks!
    I need to take screenshots insted of videorecording and I need to set resolution before taking them. Even though it is not possible with your lib don’t you know Is it possible with DirectShow.NET at all? So I will try to find solution. I tested and tried to redesign many DirectShow.NET samples but no luck so far.

  7. Hi, nice work.
    how can i change the capturing or previewing resolution.
    for now it always are 640, 480
    but i have the Microsoft lifecam cinema which can show up to 1280,720
    I’m tried to change some code like this:
    capture.FrameSize = new Size(1280, 720);
    but it drop down to initial resolution 640,480 and no changes in the picture..
    some assistance would be appreciated.

  8. Hi, Muaz.
    Many thanks for this article! It was very helpful!
    But how can i take a picture of streaming(captured by this code) video from my webcam?

  9. HI,Muaz
    Its nice article..im working on video capturing software using directshow.my need is im previewing the video in a panel on full screen mode through IVideoInterface.But how to bring notifications while i capture image in full screen mode like VLC.is there any possible for my need.thanks in advance.

  10. This is a great library. Thanks for Posting it. Wondering if there is a way to rotate the camera preview. My built-in camera needs a 270 degree rotation in Landscape and I think a 90 in Portrait. This is on a tablet in Windows 7.

  11. Dear Dr. Khan,

    This is great and very transparent code. Do you know how to implement code to adjust the settings of the camera? Also do you know how to take single frames instead of videos?

  12. @wjwalecki, you can directly change settings of the camera like this:

    capture.FrameRate = 29.997;
    capture.FrameSize = new Size( 640, 480 );
    capture.AudioSamplingRate = 44100;
    capture.AudioSampleSize = 16;

    What you meant by “…do you know how to take single frames instead of videos?…”?

  13. @arko_go, you can access list of all video compressors using “VideoCompressors” collection:

    for (var i = 0; i < Filters.VideoCompressors.Count; i++ ) {
    Console.WriteLine(Filters.VideoCompressors[i]);
    }

    You can set whatever compressor you want, like this:

    capture.VideoCompressor = Filters.VideoCompressors[1];
    capture.AudioCompressor = Filters.AudioCompressors[1];

    Remember, set compressors immediately after creating the “Capture” class. Because when these properties are changed the internal filter graph is rebuilt. This means that some properties will be reset. Set these properties as early as possible to avoid losing changes. These properties cannot be changed while capturing.

    You can access compressors used to capture streams:

    string videoCompressor = capture.VideoCompressor.MonikerString;
    string audioCompressor = capture.AudioCompressor.MonikerString;

  14. Hi sir..can u give me the code to interface with camera..actually i want to capture video and also having zoom in and out option..i dont have any idea about DirectShow control..plz suggest me any code..

  15. Hi here !! I’m working on something like that niw and i’ve a problem. I need to rotate the camera by 90° to the left. I’ve searched and nothing. So coul you help me please ? Thanks.

  16. Hi, good job on the write up. I’ve tried compiling the demo on MS visual studio 2013 but it keeps getting a System.NotSupportedException error when trying to create a Filter object during form show. Any idea what I’m doing wrong? I’m working on Windows 7 64bit.
    Thanks in advance.

  17. Hi, thanks for this great job! I have a problem with the Capture.Stop() method. When I invoke this method, the preview will be shown in another window called ‘ActiveMovie Window’, thus there will be two windows showing the preview. I fix it by commenting out the following code in the derenderGraph() method. Is there any negative side affect?
    //if (this.videoWindow != null)
    //{
    // this.videoWindow.put_Visible(0);
    // this.videoWindow.put_Owner(IntPtr.Zero);
    // this.videoWindow = null;
    //}

  18. Hi, how can i take only one frame during preview? I tryed:

    capture.PreviewWindow = Panel1
    .
    .
    .
    Panel1.DrawToBitmap(bmp, New Rectangle(0, 0, Panel1.Width, Panel1.Height))
    bmp.Save(“./test.jpg”, System.Drawing.Imaging.ImageFormat.Jpeg)

    but the image is black. Any way to save one picture?

  19. Hi, I used your code for capturing the video and audio. I can get the video file.But I cannot get the audio of related capturing video file . I also connected the micro phone with my laptop.

    Can I get the both audio and video, Get video along with audio?

  20. Thank for nice solution. But I want to catch image and store in data base. also set camera device manually in code side means user not allow to select it. please reply me fast. Its urgent

    Thanks in advance

  21. Hi All,

    I use this dll in Wxp and operate OK, but in Windows 7 generate this error
    System.NotSupportedException: No devices of the category AudioInputDevice
    at DirectX.Capture.FilterCollection.getFilters(Guid category)

  22. Hi @Muaz Khan,

    First of all thanks for a great library

    i am using your library and able to create captures but i am getting stuck at enabling the autofocus for my external camera, due to which i am not getting clear images…

    what my app does is detect eyes and a pattern which i use to convert pixels to mm.

    Looking forward to hear back.

    Thanks,
    Nishant

  23. Hi ,
    I used DShowNET to take a picture from the inbuilt cam. the feature is not working in windows 10 surface tablet.The issue is Could not setup graph Exception H RESULT(0*80040217). Any workaround for this issue.

    Regards,
    Karthikeyan

    1. Did you ever find a resolution to the 0x80040217 error with the Windows 10 surface tablet? I have 3 machines and 2 of them are having this issue. So far cannot find out what makes the working one differ form the others.

  24. Hi. I am just want to thank you for this post. It helps me a lot for finish some work here in my job.

    My problem was that my video and audio were unsynchronized (with 1 or 2 seconds of delay). The audio was starting first. After a long search that brough me here I found the solution.

    I realize that my codecs are not assigned.
    //the following attributes were null
    capture.VideoCompressor
    capture.AudioCompressor

    after listing all my codecs using the post’s example
    (filters.VideoCompressors and filters.AudioCompressors)
    I just set the codecs and tested until I find which ones worked for me

    //final code
    capture.VideoCompressor = filters.VideoCompressors[6];
    capture.AudioCompressor = filters.AudioCompressors[6];

    bye

Leave a comment