Получение событий утки
Приложение мультимедиа, которое хочет предоставить пользовательский интерфейс утки, должно прослушивать уведомления о событиях при открытии или закрытии потока коммуникации в системе. Пользовательская реализация может быть предоставлена с помощью MediaFoundation, DirectShow или DirectSound, которые используют ОСНОВНЫЕ API аудио. Прямой клиент WASAPI также может переопределить обработку по умолчанию, если он знает, когда сеанс связи начинается и заканчивается.
Чтобы обеспечить пользовательскую реализацию, приложению мультимедиа необходимо получать уведомления из системы при запуске или завершении потока коммуникации. Приложение мультимедиа должно реализовать интерфейс IAudioVolumeDuckNotification и зарегистрировать реализацию в звуковой системе. После успешной регистрации приложение мультимедиа получает уведомления о событиях в виде обратных вызовов с помощью методов в интерфейсе. Дополнительные сведения см. в разделе "Рекомендации по реализации" для уведомлений о утках.
Чтобы отправлять уведомления о утках, звуковая система должна знать, какой звуковой сеанс прослушивает события утки. Каждый звуковой сеанс однозначно идентифицируется с идентификатором GUID-экземпляра сеанса. Диспетчер сеансов позволяет приложению получать сведения о сеансе, например название звукового сеанса, состояние отрисовки и идентификатор экземпляра сеанса. Идентификатор можно получить с помощью интерфейса управления политикой IAudioSessionControl2.
Ниже приведены инструкции по получению идентификатора экземпляра сеанса приложения мультимедиа:
- Создайте экземпляр перечислителя устройства и используйте его для получения ссылки на конечную точку устройства, используемого приложением мультимедиа для отрисовки потока, не связанного с обменом данными.
- Активируйте диспетчер сеансов из конечной точки устройства и получите ссылку на интерфейс IAudioSessionManager2 диспетчера сеансов.
- Используя указатель IAudioSessionManager2, получите ссылку на интерфейс IAudioSessionControl диспетчера сеансов.
- Запрос на IAudioSessionControl2 из интерфейса IAudioSessionControl.
- Вызовите 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;
}
См. также