Is there a solution to setting the system's master volume from within my Swift app?
I read a lot about AudioToolbox and read some source examples in Objective-C. For example, I found this: Setting Mac OS X Volume Programatically after 10.6
But I can't get it working in Swift.
I am missing some example code in https://developer.apple.com/library/mac/documentation/AudioToolbox/Reference/AudioHardwareServicesReference/index.html#//apple_ref/c/func/AudioHardwareServiceGetPropertyData
(Code updated for Swift 4 and later, the Swift 2 and 3 versions can be found in the edit history.)
This is what I got from translating the answers to Change OS X system volume programmatically and Setting Mac OS X volume programmatically after 10.6 (Snow Leopard) to Swift (error checking omitted for brevity):
Required framework:
import AudioToolbox
Get default output device:
var defaultOutputDeviceID = AudioDeviceID(0)
var defaultOutputDeviceIDSize = UInt32(MemoryLayout.size(ofValue: defaultOutputDeviceID))
var getDefaultOutputDevicePropertyAddress = AudioObjectPropertyAddress(
mSelector: kAudioHardwarePropertyDefaultOutputDevice,
mScope: kAudioObjectPropertyScopeGlobal,
mElement: AudioObjectPropertyElement(kAudioObjectPropertyElementMaster))
let status1 = AudioObjectGetPropertyData(
AudioObjectID(kAudioObjectSystemObject),
&getDefaultOutputDevicePropertyAddress,
0,
nil,
&defaultOutputDeviceIDSize,
&defaultOutputDeviceID)
Set volume:
var volume = Float32(0.50) // 0.0 ... 1.0
var volumeSize = UInt32(MemoryLayout.size(ofValue: volume))
var volumePropertyAddress = AudioObjectPropertyAddress(
mSelector: kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
mScope: kAudioDevicePropertyScopeOutput,
mElement: kAudioObjectPropertyElementMaster)
let status2 = AudioObjectSetPropertyData(
defaultOutputDeviceID,
&volumePropertyAddress,
0,
nil,
volumeSize,
&volume)
Finally, for the sake of completeness, get the volume:
var volume = Float32(0.0)
var volumeSize = UInt32(MemoryLayout.size(ofValue: volume))
var volumePropertyAddress = AudioObjectPropertyAddress(
mSelector: kAudioHardwareServiceDeviceProperty_VirtualMasterVolume,
mScope: kAudioDevicePropertyScopeOutput,
mElement: kAudioObjectPropertyElementMaster)
let status3 = AudioObjectGetPropertyData(
defaultOutputDeviceID,
&volumePropertyAddress,
0,
nil,
&volumeSize,
&volume)
print(volume)
Error checking has been omitted for brevity. Of course one should check the status return values for success or failure in a real application.
Credits go to Set OS X volume in OS X 10.11 using Swift without using the deprecated AudioHardwareServiceSetPropertyData API for using AudioObjectSetPropertyData()
instead of the deprecated AudioHardwareServiceSetPropertyData().
As noamtm mentions in the comments, this works also for getting and setting the left-right balance, by passing
mSelector: kAudioHardwareServiceDeviceProperty_VirtualMasterBalance
to AudioObjectPropertyAddress().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With