取得躲避事件
想要提供自定義音量降低體驗的媒體應用程式,必須在系統中開啟或關閉音訊串流時接聽事件通知。 您可以使用 MediaFoundation、DirectShow 或 DirectSound 來提供自定義實作,其使用核心音訊 API。 如果 WASAPI 直接用戶端知道通訊工作階段的開始和結束時間,也可以覆寫預設處理。
若要提供自定義實作,媒體應用程式必須在通訊應用程式啟動或結束通訊數據流時,從系統取得通知。 媒體應用程式必須實作 IAudioVolumeDuckNotification 介面,並且向音訊系統註冊實作。 成功註冊後,媒體應用程式會透過介面中的方法,以回呼的形式接收事件通知。 如需詳細資訊,請參閱 靜音通知的實施考慮事項。
若要傳送避讓通知,音訊系統必須知道哪些音訊工作階段正在接聽避讓事件。 每個音訊會話都會以 GUID —會話實例識別碼唯一識別。 會話管理員可讓應用程式取得會話的相關信息,例如音訊會話的標題、轉譯狀態和會話實例標識符。 您可以使用原則控制介面來擷取識別碼,IAudioSessionControl2。
下列步驟總結了取得媒體應用程式會話實例識別碼的過程:
- 初始化裝置列舉器,並用它來取得媒體應用程式用來播放非通訊串流的裝置端點的參考。
- 從裝置端點啟動會話管理員,並取得會話管理員 IAudioSessionManager2 介面的參考。
- 使用 IAudioSessionManager2 指標,取得會話管理員 IAudioSessionControl 介面的參考。
- 從 IAudioSessionControl 介面中查詢 IAudioSessionControl2。
- 呼叫 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;
}
相關主題
-
躲避通知 的實作考慮