//依赖库
LIBS += -framework CoreAudio
LIBS += -framework AudioToolbox
//头文件
#include <AVFoundation/AVFoundation.h>
#include <string>
//代码
bool isOutputDevice(AudioDeviceID deviceID)
{
UInt32 propertySize = 256;
// if there are any output streams, then it is an output
AudioDeviceGetPropertyInfo(deviceID, 0, false, kAudioDevicePropertyStreams, &propertySize, NULL);
if (propertySize > 0)
return true;
return false;
}
void getDeviceName(AudioDeviceID deviceID, char * deviceName)
{
UInt32 propertySize = 256;
AudioDeviceGetProperty(deviceID, 0, false, kAudioDevicePropertyDeviceName, &propertySize, deviceName);
}
AudioDeviceID getDeviceID(const std::string &deviceName)
{
UInt32 propertySize;
AudioDeviceID dev_array[64];
int numberOfDevices = 0;
char tmpdeviceName[256];
AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propertySize, NULL);
AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propertySize, dev_array);
numberOfDevices = (propertySize / sizeof(AudioDeviceID));
for(int i = 0; i < numberOfDevices; ++i)
{
if (isOutputDevice(dev_array[i]))
{
getDeviceName(dev_array[i], tmpdeviceName);
if (deviceName == std::string(tmpdeviceName))
return dev_array[i];
}
}
return kAudioDeviceUnknown;
}
/*
* 设置扬声器音量
* deviceName:扬声器名称
* value:音量 0-100
*/
void setSpeakerVolume(const std::string &deviceName, const int value) {
Float32 outputVolume = value / 100.0;
// get output device device
UInt32 propertySize = 0;
OSStatus status = noErr;
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mScope = kAudioDevicePropertyScopeOutput;
if (outputVolume < 0.001)
{
propertyAOPA.mSelector = kAudioDevicePropertyMute;
}
else
{
propertyAOPA.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume;
}
AudioDeviceID outputDeviceID = getDeviceID(deviceName);
if (outputDeviceID == kAudioObjectUnknown)//Unknown device
{
return;
}
if (!AudioHardwareServiceHasProperty(outputDeviceID, &propertyAOPA))//Device does not support volume control
{
return;
}
Boolean canSetVolume = NO;
status = AudioHardwareServiceIsPropertySettable(outputDeviceID, &propertyAOPA, &canSetVolume);
if (status || canSetVolume == NO)//Device does not support volume control
{
return;
}
if (propertyAOPA.mSelector == kAudioDevicePropertyMute)
{
propertySize = sizeof(UInt32);
UInt32 mute = 1;
status = AudioHardwareServiceSetPropertyData(outputDeviceID, &propertyAOPA, 0, NULL, propertySize, &mute);
}
else
{
propertySize = sizeof(Float32);
status = AudioHardwareServiceSetPropertyData(outputDeviceID, &propertyAOPA, 0, NULL, propertySize, &outputVolume);
if (status)//Unable to set volume for device 0x%0x
{
}
// make sure we're not muted
propertyAOPA.mSelector = kAudioDevicePropertyMute;
propertySize = sizeof(UInt32);
UInt32 mute = 0;
if (!AudioHardwareServiceHasProperty(outputDeviceID, &propertyAOPA))//Device does not support muting
{
return;
}
Boolean canSetMute = NO;
status = AudioHardwareServiceIsPropertySettable(outputDeviceID, &propertyAOPA, &canSetMute);
if (status || !canSetMute)//Device does not support muting
{
return;
}
status = AudioHardwareServiceSetPropertyData(outputDeviceID, &propertyAOPA, 0, NULL, propertySize, &mute);
}
if (status)//Unable to set volume for device
{
}
}
/*
* 获取扬声器音量
* deviceName:扬声器名称
* return:音量值 0-100
*/
int getSpeakerVolume(const std::string &deviceName) {
Float32 outputVolume;
UInt32 propertySize = 0;
OSStatus status = noErr;
AudioObjectPropertyAddress propertyAOPA;
propertyAOPA.mElement = kAudioObjectPropertyElementMaster;
propertyAOPA.mSelector = kAudioHardwareServiceDeviceProperty_VirtualMasterVolume;
propertyAOPA.mScope = kAudioDevicePropertyScopeOutput;
AudioDeviceID outputDeviceID = getDeviceID(deviceName);
if (outputDeviceID == kAudioObjectUnknown)//Unknown device
{
return 0;
}
if (!AudioHardwareServiceHasProperty(outputDeviceID, &propertyAOPA))//No Volume returned for device
{
return 0;
}
propertySize = sizeof(Float32);
status = AudioHardwareServiceGetPropertyData(outputDeviceID, &propertyAOPA, 0, NULL, &propertySize, &outputVolume);
if (status)//No Volume returned for device
{
return 0;
}
if (outputVolume < 0.0 || outputVolume > 1.0)
return 0;
//mac获得音量范围是0.0~1.0,转换为百分制
return outputVolume * 100;
}
注:扬声器音量的设置应该是异步的,测试发现设置过扬声器音量后,立马获取扬声器音量,获取到的音量还是之前的