Menu

Error when record audio from webcam

Thuan Tran
2010-02-25
2012-10-29
  • Thuan Tran

    Thuan Tran - 2010-02-25

    I am new with DirectShow.Net. I am implementing an C# application to record
    video and audio from a webcam to a file (the webcam has a micro). Recording
    video is fine but when I add a filter to record audio then it occurs exception
    "One or more arguments are invalid". I do not know how to put valid arguments
    since I put arguments similarly to rednering the video. Following is my code
    and exception occurs at the second last line. Does anyone know how to put
    correct arguments?

    //Create the Graph
    graphBuilder = (IGraphBuilder)new FilterGraph();

    //Create the Capture Graph Builder
    ICaptureGraphBuilder2 captureGraphBuilder = null;
    captureGraphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();

    //Create the media control for controlling the graph
    mediaControlList = (IMediaControl)this.graphBuilder;

    // Attach the filter graph to the capture graph
    int hr = captureGraphBuilder.SetFiltergraph(this.graphBuilder);
    DsError.ThrowExceptionForHR(hr);

    //Add the Video input device to the graph
    IBaseFilter sourceFilter = (IBaseFilter)devices;
    hr = graphBuilder.AddFilter(sourceFilter, "The webcam " + (indexOfCamera +
    1).ToString());
    DsError.ThrowExceptionForHR(hr);

    //Add the Video compressor filter to the graph
    IBaseFilter videoCompressor = getVideoCompressor();
    if (videoCompressor != null)
    {
    hr = graphBuilder.AddFilter(videoCompressor, "video compressor filter");
    DsError.ThrowExceptionForHR(hr);
    }

    //Add the Video compressor filter to the graph
    IBaseFilter audioCompressor = getAudioCompressor();
    if (audioCompressor != null)
    {
    hr = graphBuilder.AddFilter(audioCompressor, "audio compressor filter");
    DsError.ThrowExceptionForHR(hr);
    }

    //Create the file writer part of the graph. SetOutputFileName does this for
    us, and returns the mux and sink
    IBaseFilter mux = null;
    IFileSinkFilter sink = null;
    hr = captureGraphBuilder.SetOutputFileName(MediaSubType.Avi, fileName, out
    mux, out sink);
    DsError.ThrowExceptionForHR(hr);

    //Render any preview pin of the device
    hr = captureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video,
    sourceFilter, null, null);
    DsError.ThrowExceptionForHR(hr);

    //Connect the device and compressor to the mux to render the capture part of
    the graph
    hr = captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Video,
    sourceFilter, null, mux);
    DsError.ThrowExceptionForHR(hr);

    //Render with audio
    hr = captureGraphBuilder.RenderStream(PinCategory.Capture, MediaType.Audio,
    sourceFilter, null, mux);
    DsError.ThrowExceptionForHR(hr);

    Thanks,

     
  • snarfle

    snarfle - 2010-02-25

    Let's take a look at what you are doing to connect the audio:

                   //Render with audio
                    hr = captureGraphBuilder.RenderStream(PinCategory.Capture,MediaType.Audio, sourceFilter, null, mux);
    

    Now, where do you get the value for sourceFilter?

    You don't show where you get "devices", but presumably from using DsDevice? If
    so, then the solution here should be obvious.

     
  • Thuan Tran

    Thuan Tran - 2010-02-26

    Here is how I get the webcams.

    // Find all cameras
    private void findAllCaptureDevices()
    {
    System.Collections.ArrayList availableDevices = new
    System.Collections.ArrayList();
    devices = new System.Collections.ArrayList();

    // Get all video input devices
    availableDevices.AddRange(DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDe
    vice));
    foreach (object obj in availableDevices)
    {
    DsDevice device = (DsDevice)obj;

    // Bind Moniker to a filter object
    Guid iid = typeof(IBaseFilter).GUID;
    object source;
    device.Mon.BindToObject(null, null, ref iid, out source);

    devices.Add((IBaseFilter)source);
    }
    }

    It seems DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice) does not
    include audio. if yes, could you help me to get webcams including both video
    and audio since I need to save both video and audio into a file.

     
  • snarfle

    snarfle - 2010-02-26

    C'mon man. You've got a statement that reads:

    DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)

    And you can't figure out what you have to change to get audio devices? You're
    kidding, right?

     
  • Thuan Tran

    Thuan Tran - 2010-02-26

    Your first question help me to figure the problem. I now figured out how to
    get video and audio devices separately and successfully recorded audio and
    video into a file. But with this solution, the audio devices could not be the
    micro of webcams. Is there any way to get both video and audio of webcam into
    a device object?

    // Find all cameras
    private void findAllCaptureDevices()
    {
    System.Collections.ArrayList availableDevices = new
    System.Collections.ArrayList();
    videoDevices = new System.Collections.ArrayList();

    // Get all video input devices
    availableDevices.AddRange(DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDe
    vice));
    foreach (object obj in availableDevices)
    {
    DsDevice device = (DsDevice)obj;

    // Bind Moniker to a filter object
    Guid iid = typeof(IBaseFilter).GUID;
    object source;
    device.Mon.BindToObject(null, null, ref iid, out source);

    videoDevices.Add((IBaseFilter)source);
    }

    audioDevices = new System.Collections.ArrayList();

    // Get usb audio input devices
    availableDevices.RemoveRange(0, videoDevices.Count);
    availableDevices.AddRange(DsDevice.GetDevicesOfCat(FilterCategory.AudioInputDe
    vice));
    foreach (object obj in availableDevices)
    {
    DsDevice device = (DsDevice)obj;
    if(device.Name.Contains("USB Audio Device"))
    {
    // Bind Moniker to a filter object
    Guid iid = typeof(IBaseFilter).GUID;
    object source;
    device.Mon.BindToObject(null, null, ref iid, out source);

    audioDevices.Add((IBaseFilter)source);
    }
    }
    }

     

Log in to post a comment.