Set OS X volume in OS X 10.11 using Swift without using the deprecated AudioHardwareServiceSetPropertyData API
As also suggested in this answer to a similar Objective-C question, I'd suggest using ISSoundAdditions, which you can call from Swift as such:
NSSound.setSystemVolume(0.5)
The implementation of -setSystemVolume
begins around line 113 in ISSoundAdditions.m in case you're curious of how they accomplish setting the system volume.
To clarify a factually challenged comment to my answer (since deleted, apparently), there is no use of deprecated APIs in ISSoundAdditions when compiling with the El Capitan SDK – AudioHardwareServiceSetPropertyData
is not used. AudioObjectSetPropertyData
is indeed the API one should switch to if using the deprecated AudioHardwareServiceSetPropertyData
, though as you can see from the ISSoundAdditions implementation I linked to, there's a bit of work involved (hence I linked to the implementation in the first place).
Capture system volume changes in Swift
I used (Swift 4):
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(eventFunction(_:)),
name: NSNotification.Name(rawValue: "com.apple.sound.settingsChangedNotification"),
object: nil)
Where the function is defined like:
@objc func volumeChangeEvent(_ evt: NSEvent) { }
Using AudioToolbox from Swift to access OS X master volume
(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()
.
Related Topics
Uitextview Change Text Color of Specific Text
Ui Testing Failure - Neither Element Nor Any Descendant Has Keyboard Focus on Textview
Swift Task Continuation Misuse: Leaked Its Continuation - for Delegate
How to Read a Property List from Data in Swift 3
Animating a Navigation Bar Color
How to Access Firebase Variable Outside Firebase Function
Firebase Uid VS Document-Id and Firestore Rules
Xcode Playgrounds Can't Access Swift Files in Sources Folder
How to Identify Uppercase and Lowercase Characters in a String with Swift
Slide Sidebar Menu iOS 8 Swift
Fatal Error: Array Index Out of Range in Swift Xcode6
Playing a Sound in a Swift Playground
Why Do Integers Not Conform to the Anyobject Protocol
Iphonex Not Call Prefersstatusbarhidden
Pickers Are Overlapping in iOS 15 Preventing Some of Them to Be Scrolled
Executing Text-To-Speech in Order