Obtendo eventos de redução de som
Uma aplicação de media que deseje fornecer uma experiência personalizada de ajuste de volume deve monitorizar as notificações de eventos quando um fluxo de comunicação é aberto ou fechado no sistema. A implementação personalizada pode ser fornecida usando MediaFoundation, DirectShow ou DirectSound, que usam as APIs de áudio principal. Um cliente WASAPI direto também pode substituir o tratamento padrão se souber quando a sessão de comunicação começa e termina.
Para fornecer uma implementação personalizada, um aplicativo de mídia precisa receber notificações do sistema quando um aplicativo de comunicação inicia ou termina um fluxo de comunicação. A aplicação de mídia deve implementar a interface IAudioVolumeDuckNotification e registar a implementação com o sistema de áudio. Após o registo bem-sucedido, a aplicação de mídia recebe notificações de eventos sob a forma de callbacks através dos métodos na interface. Para obter mais informações, consulte Considerações de implementação para notificações de desvio.
Para enviar notificações de ducking, o sistema de áudio deve saber qual sessão de áudio está monitorizando os eventos de ducking. Cada sessão de áudio é identificada exclusivamente com um GUID — identificador de instância de sessão. O gerenciador de sessões permite que um aplicativo obtenha informações sobre a sessão, como o título da sessão de áudio, o estado de renderização e o identificador de instância da sessão. O identificador pode ser recuperado usando a interface de controle de política, IAudioSessionControl2.
As etapas a seguir resumem o processo de obtenção do identificador de instância de sessão do aplicativo de mídia:
- Instancie o enumerador de dispositivos e use-o para obter uma referência ao ponto de extremidade do dispositivo que a aplicação de media está a usar para renderizar o fluxo não relacionado à comunicação.
- Ative o gestor de sessão a partir do ponto de extremidade do dispositivo e obtenha uma referência à interfaceIAudioSessionManager2 do gestor de sessão.
- Usando o ponteiro IAudioSessionManager2, obtenha uma referência à interface IAudioSessionControl do gestor de sessão.
- Consulta para o IAudioSessionControl2 a partir da interface IAudioSessionControl.
- Chame IAudioSessionControl2::GetSessionInstanceIdentifier e recupere uma cadeia de caracteres que contém o identificador de sessão para a sessão de áudio atual.
Para receber notificações sobre fluxos de comunicação, o aplicativo de mídia chama IAudioSessionManager2::RegisterDuckNotification. O aplicativo de mídia fornece o seu identificador de instância de sessão ao sistema de áudio e um ponteiro para a implementação da IAudioVolumeDuckNotification. O aplicativo agora pode receber notificação de evento quando um fluxo é aberto no dispositivo de comunicação. Para parar de receber notificação, o aplicativo de mídia deve chamar IAudioSessionManager2::UnregisterDuckNotification.
O código a seguir mostra como um aplicativo pode se registrar para obter notificações de desvio. A classe CMediaPlayer é definida em Considerações de Implementação para Notificações de Ducking. O DuckingMediaPlayer exemplo implementa essa funcionalidade.
////////////////////////////////////////////////////////////////////
//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;
}
Tópicos relacionados