Поделиться через


Получение событий утки

Приложение мультимедиа, которое хочет предоставить пользовательский интерфейс утки, должно прослушивать уведомления о событиях при открытии или закрытии потока коммуникации в системе. Пользовательская реализация может быть предоставлена с помощью MediaFoundation, DirectShow или DirectSound, которые используют ОСНОВНЫЕ API аудио. Прямой клиент WASAPI также может переопределить обработку по умолчанию, если он знает, когда сеанс связи начинается и заканчивается.

Чтобы обеспечить пользовательскую реализацию, приложению мультимедиа необходимо получать уведомления из системы при запуске или завершении потока коммуникации. Приложение мультимедиа должно реализовать интерфейс IAudioVolumeDuckNotification и зарегистрировать реализацию в звуковой системе. После успешной регистрации приложение мультимедиа получает уведомления о событиях в виде обратных вызовов с помощью методов в интерфейсе. Дополнительные сведения см. в разделе "Рекомендации по реализации" для уведомлений о утках.

Чтобы отправлять уведомления о утках, звуковая система должна знать, какой звуковой сеанс прослушивает события утки. Каждый звуковой сеанс однозначно идентифицируется с идентификатором GUID-экземпляра сеанса. Диспетчер сеансов позволяет приложению получать сведения о сеансе, например название звукового сеанса, состояние отрисовки и идентификатор экземпляра сеанса. Идентификатор можно получить с помощью интерфейса управления политикой IAudioSessionControl2.

Ниже приведены инструкции по получению идентификатора экземпляра сеанса приложения мультимедиа:

  1. Создайте экземпляр перечислителя устройства и используйте его для получения ссылки на конечную точку устройства, используемого приложением мультимедиа для отрисовки потока, не связанного с обменом данными.
  2. Активируйте диспетчер сеансов из конечной точки устройства и получите ссылку на интерфейс IAudioSessionManager2 диспетчера сеансов.
  3. Используя указатель IAudioSessionManager2, получите ссылку на интерфейс IAudioSessionControl диспетчера сеансов.
  4. Запрос на IAudioSessionControl2 из интерфейса IAudioSessionControl.
  5. Вызовите IAudioSessionControl2::GetSessionInstanceIdentifier и получите строку, содержащую идентификатор сеанса для текущего звукового сеанса.

Чтобы получить уведомления о потоках связи, приложение мультимедиа вызывает IAudioSessionManager2::RegisterDuckNotification. Приложение мультимедиа предоставляет идентификатор экземпляра сеанса звуковой системе и указатель на реализацию IAudioVolumeDuckNotification. Теперь приложение может получать уведомления о событиях при открытии потока на устройстве связи. Чтобы остановить получение уведомлений, приложение мультимедиа должно вызвать IAudioSessionManager2::UnregisterDuckNotification.

В следующем коде показано, как приложение может зарегистрировать для получения утихих уведомлений. Класс CMediaPlayer определен в разделе "Рекомендации по реализации" для утиющих уведомлений. Пример DuckingMediaPlayer реализует эту функцию.

////////////////////////////////////////////////////////////////////
//Description: Registers for duck notifications depending on the 
//             the ducking options specified by the caller.
//Parameters: 
//    If DuckingOptOutChecked is TRUE, the client is registered for
//    to receive ducking notifications; 
//    FALSE, the client's registration is deleted.
////////////////////////////////////////////////////////////////////

HRESULT CMediaPlayer::DuckingOptOut(bool DuckingOptOutChecked)
{
    HRESULT hr = S_OK;

    IMMDeviceEnumerator* pDeviceEnumerator NULL;
    IMMDevice* pEndpoint = NULL;
    IAudioSessionManager2* pSessionManager2 = NULL;
    IAudioSessionControl* pSessionControl = NULL;
    IAudioSessionControl2* pSessionControl2 = NULL;

    LPWSTR sessionId = NULL;

    //  Start with the default endpoint.

    hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), 
                          NULL, 
                          CLSCTX_INPROC_SERVER, 
                          IID_PPV_ARGS(&pDeviceEnumerator));
    
    if (SUCCEEDED(hr))
    {
        hr = pDeviceEnumerator>GetDefaultAudioEndpoint(
              eRender, eConsole, &pEndpoint);

        pDeviceEnumerator>Release();
        pDeviceEnumerator = NULL;
    }

    // Activate the session manager.
    if (SUCCEEDED(hr))
    {
        hr = pEndpoint->Activate(__uuidof(IAudioSessionManager2), 
                                 CLSCTX_INPROC_SERVER,
                                 NULL, 
                                 reinterpret_cast<void **>
                                 (&pSessionManager2));
        pEndpoint->Release();
        pEndpoint = NULL;
    }
    if (SUCCEEDED(hr))
    {
        hr = pSessionManager2->GetAudioSessionControl(
                                  NULL, 0, &pSessionControl);
        
    }

    if (SUCCEEDED(hr))
    {
        hr = pSessionControl->QueryInterface(
                               IID_PPV_ARGS(&pSessionControl2));
                
        pSessionControl->Release();
        pSessionControl = NULL;
    }

    // Get the session instance identifier.
    
    if (SUCCEEDED(hr))
    {
        hr = pSessionControl2->GetSessionInstanceIdentifier(
                                 sessionId);
                
        pSessionControl2->Release();
        pSessionControl2 = NULL;
    }

    //  Register for ducking events depending on 
    //  the specified preference.

    if (SUCCEEDED(hr))
    {
        if (DuckingOptOutChecked)
        {
            hr = pSessionManager2->RegisterDuckNotification(
                                    sessionId, this);
        }
        else
        {
            hr = pSessionManager2->UnregisterDuckNotification
                                      (FALSE);
        }
        pSessionManager2->Release();
        pSessionManager2 = NULL;
    }
    return hr;
}

Использование устройства связи

Взаимодействие с утками по умолчанию

Отключение интерфейса утки по умолчанию

Предоставление пользовательского поведения утки

Рекомендации по реализации для уведомлений о утках