【问题标题】:Capturing audio using DirectShow使用 DirectShow 捕获音频
【发布时间】:2011-10-07 11:04:57
【问题描述】:

我正在编写程序,该程序使用 DirectShow 库在 C# 中捕获音频并将其写入 ogg 容器。我在 GraphEditPlus 中创建了一个图表。它会生成一个 GraphBuilder 方法代码,我将其复制到我的代码中。这段代码是:

class AudioCapture
{
  public static void checkHR(int hr, string msg)
  {
    if (hr < 0)
    {
      MessageBox.Show(msg);
      DsError.ThrowExceptionForHR(hr);
    }
  }

  public static void BuildGraph (IGraphBuilder pGraph, string dstFile)
  {
    int hr = 0;

    //graph builder
    ICaptureGraphBuilder2 pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
    hr = pBuilder.SetFiltergraph(pGraph);
    checkHR(hr, "Can't SetFiltergraph");

    Guid CLSID_XiphOrgVorbisEncoder = new Guid("{5C94FE86-B93B-467F-BFC3-BD6C91416F9B}");
    Guid CLSID_XiphOrgOggMuxer = new Guid("{1F3EFFE4-0E70-47C7-9C48-05EB99E20011}");

    //add microphone
    IBaseFilter pMicrophone = (IBaseFilter) new AudioRecord();
    hr = pGraph.AddFilter(pMicrophone, "Microphone");
    checkHR(hr, "Can't add microphone to graph");

    //add Vorbis Encoder
    IBaseFilter pVorbisEncoder = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_XiphOrgVorbisEncoder));
    checkHR(hr, "Can't add Vorbis Encoder to graph");

    //connect Microphone and Vorbis Encoder
    hr = pGraph.ConnectDirect(GetPin(pMicrophone, "Capture"), GetPin(pVorbisEncoder, "PCM In"), null);
    checkHR(hr, "Can't connect Microphone and Vorbis Encoder");

    //add Ogg Muxer
    IBaseFilter pOggMuxer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_XiphOrgOggMuxer));
    checkHR(hr, "Can't add Ogg Muxer to graph");

    //set destination filename
    IFileSinkFilter pOggMuxer_sink = pOggMuxer as IFileSinkFilter;
    if (pOggMuxer_sink == null)
      checkHR(unchecked((int)0x80004002), "Can't get IFileSinkFilter");
    hr = pOggMuxer_sink.SetFileName(dstFile, null);
    checkHR(hr, "Can't set filename");

    //connect Vorbis Encoder and Ogg Muxer
    hr = pGraph.ConnectDirect(GetPin(pVorbisEncoder, "VorbisOut"), GetPin(pOggMuxer, "Ogg Packet In"), null);
    checkHR(hr, "Can't connect Vorbis Encoder and Ogg Muxer");
  }

  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;
  }
}

当我尝试执行此代码程序时,在尝试连接麦克风和 vorbis 编码器过滤器后,会向我抛出一条消息“找不到 Pin”。调试后我发现它找不到麦克风引脚。有人知道我的错误在哪里吗?

【问题讨论】:

  • 最好搜索音频输入设备。只是new AudioRecord() 不会自动创建麦克风输入。
  • 您好,如何同时录制视频和音频并将其保存到单个视频文件中?我可以通过单独的文件来做到这一点。你能帮帮我吗?

标签: c# audio directshow


【解决方案1】:

你不应该通过他们的名字来寻找别针,因为这不太可靠。如果您绝对确定要处理的过滤器/类,也许它或多或少还是可以接受的,但这绝对不是通用音频源过滤器的方法(更具体地说:没有人承诺命名捕获引脚“捕获”,而不是引脚实现IKsPropertySet 来指示)。

您最好的方法是使用 ICaptureGraphBuilder::RenderStreamPIN_CATEGORY_CAPTURE 参数,以便它可以为您获取捕获引脚。有关详细信息,请参阅 MSDN http://msdn.microsoft.com/en-us/library/dd311932%28v=vs.85%29.aspx,我很确定您也可以轻松找到执行此操作的示例代码。

【讨论】:

    【解决方案2】:

    在寻找图钉时尝试这样做

        pinout = FindPinByDirection( Source, PinDirection.Output);
        pinin = FindPinByDirection( Target, PinDirection.Input);
    
        Graph.Connect(pinout, pinin);
    

    这是更好的方法,然后取决于名称。

    【讨论】:

      猜你喜欢
      • 2018-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多