Search code examples
c#directshowdirectshow.net

DirectShow Audio Device has no pins


I want to mux webcam capture with audio capture in an avi mux and write that file to disk.

This works in graphedit.enter image description here

I try to recreate this in c# with directshowlib. This works so far but the only without the microphone capture. My microphone filter is created but has no pins. I tried this on two different laptops. My code for the microphone filter:

Guid microphonFilter = new Guid("{E30629D2-27E5-11CE-875D-00608CB78066}"); 
IBaseFilter pMikrofonRealtekHighDefinitionAudio = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(microphonFilter));
hr = pGraph.AddFilter(pMikrofonRealtekHighDefinitionAudio, "Mikrofon (Realtek High Definition Audio) ");

I also tried:

IBaseFilter microphonFilter = (IBaseFilter) new AudioRecord();

My code for finding pins:

static IPin GetPin(IBaseFilter filter, string pinname)
{
    IEnumPins epins;
    int hr = filter.EnumPins(out epins);
    checkHR(hr, "Can't enumerate pins");
    IntPtr fetched = Marshal.AllocCoTaskMem(4);
    IPin[] pins = new IPin[1];
    while (epins.Next(1, pins, fetched) == 0)
    {
        PinInfo pinfo;
        pins[0].QueryPinInfo(out pinfo);
        bool found = (pinfo.name == pinname);
        DsUtils.FreePinInfo(pinfo);
        if (found)
            return pins[0];
    }
    checkHR(-1, "Pin not found");
    return null;
}

Solution

  • Audio (and video) capture devices like this cannot be instantiated using CoCreateInstance (using CLSID - Activator.CreateInstance in C#). You have to create them using monikers, typically through enumeration, as described on MSDN (with source code snippet): Selecting a Capture Device.

    Below is code snippet from DirectShow.NET samples for video capture, you need similar for audio device category.

    // This version of FindCaptureDevice is provide for education only.
    // A second version using the DsDevice helper class is define later.
    public IBaseFilter FindCaptureDevice()
    {
      // ...
    
      // Create the system device enumerator
      ICreateDevEnum devEnum = (ICreateDevEnum) new CreateDevEnum();
    
      // Create an enumerator for the video capture devices
      hr = devEnum.CreateClassEnumerator(FilterCategory.VideoInputDevice, out classEnum, 0);
      DsError.ThrowExceptionForHR(hr);
    
      // The device enumerator is no more needed
      Marshal.ReleaseComObject(devEnum);
    
      // If there are no enumerators for the requested type, then 
      // CreateClassEnumerator will succeed, but classEnum will be NULL.
      if (classEnum == null)
      {
        throw new ApplicationException("No video capture device was detected.\r\n\r\n" +
                                       "This sample requires a video capture device, such as a USB WebCam,\r\n" +
                                       "to be installed and working properly.  The sample will now close.");
      }