Добавьте звуковые фильтры и подключите звуковые контакты

Контекст

Пользовательский интерфейс WPF с пользовательским элементом управления, который создает несколько COMS и использует фильтры с directshow.net

Проблема

Имена аудио контактов меняются в зависимости от того, какое видео воспроизводится. (оба являются файлами .avi). Как видно на скриншотах, звуковые контакты не совпадают. (один — «Поток 01», а другой — «01 Волновая форма Microsoft…»)

В своем коде я использую ConnectDirect и метод GetPin. Чтобы использовать GetPin, вам нужно указать имя контакта.

Графики

График сгенерирован точно таким же кодом, только изменены видеофайлы.

График создан с точно таким же кодом, только изменены видеофайлы.

Вопрос

Как мне подключить фильтры, когда имена пинов меняются в зависимости от того, какой файл .avi запущен? Кстати, один avi-файл «самодельный», а другой — образец файла Microsoft avi (12-секундные синие часы)

Соответствующий код

//sound filter linker
IBaseFilter pACMWrapper = (IBaseFilter)new ACMWrapper();
hr = m_FilterGraph.AddFilter(pACMWrapper, "ACM wrapper");


//add le default direct sound device

IBaseFilter pDefaultDirectSoundDevice = null;

try
{
    pDefaultDirectSoundDevice = (IBaseFilter)new DSoundRender();
    hr = m_FilterGraph.AddFilter(pDefaultDirectSoundDevice, "Default DirectSound Device");


    IBaseFilter aviSplitter;
    //find the avi splitter automatically added when I connect samp grabber to source filter.
    m_FilterGraph.FindFilterByName("AVI Splitter", out aviSplitter);

    System.Windows.MessageBox.Show(""); // graph screenshot is from here.

    hr = m_FilterGraph.Connect(GetPin(aviSplitter, "Stream 01"), GetPin(pACMWrapper, "Input"));
    DsError.ThrowExceptionForHR(hr);

    //connect audio filters 
    hr = m_FilterGraph.ConnectDirect(GetPin(pACMWrapper, "Output"), GetPin(pDefaultDirectSoundDevice, "Audio Input pin (rendered)"), null);
    DsError.ThrowExceptionForHR(hr);
}
catch (Exception)
{
    pDefaultDirectSoundDevice = null;
    //log error, play video without sound
    //throw;
}

ПолучитьPin-код

    private IPin GetPin(IBaseFilter destinationFilter, string pinName)
    {
        IEnumPins pinEnum;
        int hr = destinationFilter.EnumPins(out pinEnum);
        DsError.ThrowExceptionForHR(hr);

        IPin[] pins = new IPin[1];

        IntPtr fetched = Marshal.AllocCoTaskMem(4);

        while (pinEnum.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];
        }
        return null;
    }

person Dave    schedule 14.10.2014    source источник


Ответы (1)


Вам не нужно выбирать выходной контакт, используя жестко заданное имя. Вместо этого, и на самом деле это более надежный способ, вам нужно перечислить выводы — как уже делает ваша функция GetPin — а затем перечислить типы носителей на данном выводе. Можно смотреть только на первый тип носителя (если есть). Если его основной тип MEDIATYPE_Audio, то это ваша булавка, независимо от ее эффективного имени.

person Roman R.    schedule 14.10.2014
comment
Чувак. Вы хозяин и оракул той вавилонской башни, которой является Directshow. Вы получили мое уважение от Saguenay, королевский адвокат, Канада. - person Dave; 15.10.2014