天天看点

mac扬声器音量获取和设置 objective-c c++

//依赖库

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;
}
           

注:扬声器音量的设置应该是异步的,测试发现设置过扬声器音量后,立马获取扬声器音量,获取到的音量还是之前的

继续阅读