先说一下大概思路,然后再贴出代码:
首先,获取扬声器音量,根据扬声器音量和需要设置的音量计算一个音量值(例如,扬声器50%,需要设置当前程序音量为50%,所以最终设置音量合成器中的数值为50% * 50% = 25%)
然后,设置其他程序静音,在设置静音之前需要保存音量值
设置当前程序音量
最后,在播放完声音之后,还原其他程序音量,这个时候要用到第二步保存的音量值。
下面给出每个步骤代码,以下代码本人亲测有效
// 获取扬声器音量
void GetSpeakerAudio()
{
CComPtr<IMMDeviceEnumerator> pIMMEnumerator = NULL;
CComPtr<IMMDevice> pIMMDeivce = NULL;
CComPtr<IAudioEndpointVolume> pIAudioEndpointVolume = NULL;
HRESULT hr = S_OK;
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pIMMEnumerator);
if(SUCCEEDED(hr))
{
hr = pIMMEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pIMMDeivce);
if(SUCCEEDED(hr))
{
hr = pIMMDeivce->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, NULL, (void**)&pIAudioEndpointVolume);
if(SUCCEEDED(hr))
{
hr = pIAudioEndpointVolume->GetMasterVolumeLevelScalar(&m_fVolum);
}
}
}
}
//dwVolume:可以忽略,IsRecover:true恢复其他程序音量,false是设置当前程序音量
BOOL SetCurrentProcessVolume(DWORD dwVolume,BOOL IsRecover)
{
if(!IsRecover)
m_mapAppVolum.clear();
HRESULT hr = S_OK;
IMMDeviceCollection *pMultiDevice = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionEnumerator *pSessionEnum = NULL;
IAudioSessionManager2 *pASManager = NULL;
IMMDeviceEnumerator *m_pEnumerator = NULL;
const IID IID_ISimpleAudioVolume = __uuidof(ISimpleAudioVolume);
const IID IID_IAudioSessionControl2 = __uuidof(IAudioSessionControl2);
GUID m_guidMyContext;
CoInitialize(NULL);
hr = CoCreateGuid(&m_guidMyContext);
if(FAILED(hr))
return FALSE;
// Get enumerator for audio endpoint devices.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
NULL, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator),
(void**)&m_pEnumerator);
if(FAILED(hr))
return FALSE;
/*if (IsMixer)
{
hr = m_pEnumerator->EnumAudioEndpoints(eRender,DEVICE_STATE_ACTIVE, &pMultiDevice);
}
else
{
hr = m_pEnumerator->EnumAudioEndpoints(eCapture,DEVICE_STATE_ACTIVE, &pMultiDevice);
} */
hr = m_pEnumerator->EnumAudioEndpoints(eRender,DEVICE_STATE_ACTIVE, &pMultiDevice);
if(FAILED(hr))
return FALSE;
UINT deviceCount = 0;
hr = pMultiDevice->GetCount(&deviceCount);
if(FAILED(hr))
return FALSE;
if((int)dwVolume < 0)
dwVolume = 0;
if((int)dwVolume > 100)
dwVolume = 100;
for (UINT ii=0; ii<deviceCount; ii++)
{
pDevice = NULL;
hr = pMultiDevice->Item(ii,&pDevice);
if(FAILED(hr))
return FALSE;
hr = pDevice->Activate(__uuidof(IAudioSessionManager),CLSCTX_ALL, NULL,(void**)&pASManager);
if(FAILED(hr))
return FALSE;
hr = pASManager->GetSessionEnumerator(&pSessionEnum);
if(FAILED(hr))
return FALSE;
int nCount;
hr = pSessionEnum->GetCount(&nCount);
for (int i = 0; i < nCount; i++)
{
IAudioSessionControl *pSessionCtrl;
hr = pSessionEnum->GetSession(i, &pSessionCtrl);
if (FAILED(hr))
continue;
IAudioSessionControl2 *pSessionCtrl2;
hr = pSessionCtrl->QueryInterface(IID_IAudioSessionControl2, (void **)&pSessionCtrl2);
if(FAILED(hr))
continue;
ULONG pid;
hr = pSessionCtrl2->GetProcessId(&pid);
if (FAILED(hr))
continue;
ISimpleAudioVolume *pSimplevol;
hr = pSessionCtrl2->QueryInterface(IID_ISimpleAudioVolume, (void **)&pSimplevol);
if (FAILED(hr))
continue;
ULONG currentId = GetCurrentProcessId();
if (pid == currentId)
{
//pSimplevol->SetMasterVolume((float)dwVolume/100, NULL);
}
else
{
if(IsRecover)
{
auto iter = m_mapAppVolum.find(currentId);
if(iter != m_mapAppVolum.end())
{
pSimplevol->SetMasterVolume(iter->second,NULL);
}
}
else
{
float fLevel;
pSimplevol->GetMasterVolume(&fLevel);
m_mapAppVolum.insert(make_pair(currentId, fLevel));
pSimplevol->SetMasterVolume((float)0/100, NULL);
}
}
}
}
m_pEnumerator->Release();
return TRUE;
}
//设置当前程序音量
void SetApplicationVolume(int size)
{
CComPtr<IMMDeviceEnumerator > pIMMEnumerator = NULL; //主要用于枚举设备接口
CComPtr<ISimpleAudioVolume> pRenderSimpleVol = NULL; //扬声器的会话音量控制接口
HRESULT hr = S_OK;
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pIMMEnumerator);
if(SUCCEEDED(hr))
{
CComPtr<IMMDevice> pIMMDeivce = NULL;
hr = pIMMEnumerator->GetDefaultAudioEndpoint(eRender,eConsole,&pIMMDeivce);
if(SUCCEEDED(hr))
{
CComPtr<IAudioSessionManager> pSessionManager = NULL;
hr = pIMMDeivce->Activate(__uuidof(IAudioSessionManager), CLSCTX_INPROC_SERVER, NULL, (void **)(&pSessionManager));
if(SUCCEEDED(hr))
{
hr = pSessionManager->GetSimpleAudioVolume(NULL, FALSE, &pRenderSimpleVol);
if(SUCCEEDED(hr))
{
float fLevel = (float)size/100;
fLevel += 0.000001;
if(fLevel >= 1.000)
fLevel = 1.000;
hr = pRenderSimpleVol->SetMasterVolume(fLevel, NULL);
}
}
}
}
}