简体   繁体   English

以编程方式更改OS X系统卷

[英]Change OS X system volume programmatically

How can I change the volume programmatically from Objective-C? 如何从Objective-C以编程方式更改卷?

I found this question, Controlling OS X volume in Snow Leopard which suggests to do: 我发现了这个问题, 在Snow Leopard中控制OS X卷 ,建议:

Float32 volume = 0.5;
UInt32 size = sizeof(Float32);

AudioObjectPropertyAddress address = {
    kAudioDevicePropertyVolumeScalar,
    kAudioDevicePropertyScopeOutput,
    1 // Use values 1 and 2 here, 0 (master) does not seem to work
};

OSStatus err;
err = AudioObjectSetPropertyData(kAudioObjectSystemObject, &address, 0, NULL, size, &volume);
NSLog(@"status is %i", err);

This does nothing for me, and prints out status is 2003332927 . 这对我没什么用,打印输出status is 2003332927

I also tried using values 2 and 0 in the address structure, same result for both. 我也尝试在address结构中使用值20 ,两者的结果相同。

How can I fix this and make it actually decrease the volume to 50%? 我如何解决这个问题并使其实际减少到50%?

You need to get the default audio device first: 您需要先获取默认音频设备:

#import <CoreAudio/CoreAudio.h>

AudioObjectPropertyAddress getDefaultOutputDevicePropertyAddress = {
  kAudioHardwarePropertyDefaultOutputDevice,
  kAudioObjectPropertyScopeGlobal,
  kAudioObjectPropertyElementMaster
};

AudioDeviceID defaultOutputDeviceID;
UInt32 volumedataSize = sizeof(defaultOutputDeviceID);
OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
                                             &getDefaultOutputDevicePropertyAddress,
                                             0, NULL,
                                             &volumedataSize, &defaultOutputDeviceID);

if(kAudioHardwareNoError != result)
{
  // ... handle error ...
}

You can then set your volume on channel 1 (left) and channel 2 (right). 然后,您可以在通道1(左)和通道2(右)上设置音量。 Note that channel 0 (master) does not seem to be supported (the set command returns 'who?') 注意,似乎不支持通道0(主)(set命令返回'who?')

AudioObjectPropertyAddress volumePropertyAddress = {
  kAudioDevicePropertyVolumeScalar,
  kAudioDevicePropertyScopeOutput,
  1 /*LEFT_CHANNEL*/
};

Float32 volume;
volumedataSize = sizeof(volume);

result = AudioObjectSetPropertyData(defaultOutputDeviceID,
                                    &volumePropertyAddress,
                                    0, NULL,
                                    sizeof(volume), &volume);
if (result != kAudioHardwareNoError) {
  // ... handle error ...
}

Hope this answers your question! 希望这能回答你的问题!

I ran the HALLab utility that comes with the developer tools (ie Audio Tools for Xcode). 我运行了开发人员工具附带的HALLab实用程序(即Xcode的Audio Tools)。 That allows you to open an info window for individual devices and that window has a tab showing notifications. 这允许您打开单个设备的信息窗口,该窗口有一个显示通知的选项卡。 When I change my system volume, I do indeed see that the kAudioDevicePropertyVolumeScalar property changes for each channel of the output device as Thomas O'Dell's answer suggests. 当我更改系统音量时,我确实看到了输出设备的每个通道的kAudioDevicePropertyVolumeScalar属性都发生了变化,正如Thomas O'Dell的回答所暗示的那样。 However, I also see the property kAudioHardwareServiceDeviceProperty_VirtualMasterVolume change on the master channel. 但是,我也看到主通道上的属性kAudioHardwareServiceDeviceProperty_VirtualMasterVolume发生了变化。 That seems much more promising since you don't have to manually set it for all channels and maintain the balance across them. 这似乎更有希望,因为您不必为所有通道手动设置它并保持它们之间的平衡。

You would use the function AudioHardwareServiceSetPropertyData() from Audio Hardware Services to set that on the default output device. 您可以使用Audio Hardware Services中的 AudioHardwareServiceSetPropertyData()函数在默认输出设备上设置它。 To be safe, you might first check that it's settable using AudioHardwareServiceIsPropertySettable() . 为安全起见,您可以先使用AudioHardwareServiceIsPropertySettable()检查它是否可AudioHardwareServiceIsPropertySettable()

The documentation for that property says: 该属性的文档说:

kAudioHardwareServiceDeviceProperty_VirtualMasterVolume

A Float32 value that represents the value of the volume control. Float32值,表示音量控件的值。

The range for this property's value is 0.0 (silence) through 1.0 (full level). 此属性值的范围是0.0(静音)到1.0(完整级别)。 The effect of this property depends on the hardware device associated with the HAL audio object. 此属性的效果取决于与HAL音频对象关联的硬件设备。 If the device has a master volume control, this property controls it. 如果设备具有主音量控制,则此属性对其进行控制。 If the device has individual channel volume controls, this property applies to those identified by the device's preferred multichannel layout, or the preferred stereo pair if the device is stereo only. 如果设备具有单独的通道音量控制,则此属性适用于由设备首选多声道布局标识的设备,或者如果设备仅为立体声设备,则适用于首选立体声对。 This control maintains relative balance between the channels it affects. 该控件保持其影响的通道之间的相对平衡。

You could run a bash script that will change the master volume. 您可以运行将更改主卷的bash脚本。 This prevents setting the audio first to one side: 这可以防止首先将音频设置为一侧:

Muted: 静音:

execlp("osascript", "osascript", "-e", "set volume output muted true", NULL);

Change volume (scale 0-10): 改变音量(音阶0-10):

    execlp("osascript", "osascript", "-e", "set volume 5", NULL);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM