Захват аудио с помощью DirectShow - PullRequest
0 голосов
/ 07 октября 2011

Я пишу программу, которая записывает аудио в C # с использованием библиотеки DirectShow и записывает его в контейнер 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;
  }
}

Когда я пытаюсь выполнить этот код, программа выдает мне сообщение «PIN-код не найден» после попытки подключения фильтров микрофона и кодировщика vorbis. После отладки я обнаружил, что он не может найти контакт микрофона. Кто-нибудь знает, где моя ошибка?

Ответы [ 2 ]

0 голосов
/ 13 октября 2016

Попробуйте сделать что-то подобное, когда вы ищете булавки

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

    Graph.Connect(pinout, pinin);

Это лучше, чем в зависимости от имен.

0 голосов
/ 07 октября 2011

Не следует искать контакты по их именам, так как это не совсем надежно.Возможно, это будет все еще более или менее приемлемо, если вы абсолютно уверены, с каким фильтром / классом вы имеете дело, но это определенно не тот способ, который используется с универсальным фильтром аудиоисточника (более конкретно: никто не дает обещание, что пин-код захвата назван«Захват», вместо штырьков необходимо указать IKsPropertySet).

Ваш лучший подход - использовать ICaptureGraphBuilder::RenderStream с аргументом PIN_CATEGORY_CAPTURE, чтобы он мог подобрать для вас пин-код захвата.Подробности смотрите в MSDN http://msdn.microsoft.com/en-us/library/dd311932%28v=vs.85%29.aspx, и я уверен, что вы легко найдете образец кода для этого тоже.

...