Pump up the volume! Control volume for audio on iOS using Swift

In most circumstances, you’ll want audio playback to use the volume settings on the device – users are typically not going to be happy if they turn down their volume, then hear something loud. But occasionally there may be a need to override the device settings – say an important alarm. We wouldn’t want to use this for sustained playback, but we recently wrote a function to play a specified sound, and optionally override volume to a specified level – 0 being silent and 1.0 being full-blast.

Here’s what the code looks like in Swift:

// Play a sound, optionally setting volume to the specified level
func playSound(audioURL: URL?, setVolume: Bool = false, level: Float = 1.0) {
    if let audioUrl = audioURL {
        do {
            // Create an audio session for playback
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: .mixWithOthers)
            try AVAudioSession.sharedInstance().setActive(true)
            
            var volumeSlider: UISlider = UISlider()
            var origVolume: Float = 0.0
            if (setVolume) {
                // Save the original volume level, then turn up the system volume
                volumeSlider = (MPVolumeView().subviews.filter{NSStringFromClass($0.classForCoder) == "MPVolumeSlider"}.first) as! UISlider
                origVolume = AVAudioSession.sharedInstance().outputVolume
                volumeSlider.setValue(level, animated: false)
            }
            
            // Sound the alarm
            let player = try AVAudioPlayer(contentsOf: audioUrl)
            DispatchQueue.main.asyncAfter(deadline: .now() + player.duration) {
                // Capture the AVPlayer instance in this closure to ensure is remains in scope until playback finishes
                _ = player
                if (setVolume) {
                    // After the duration of the audio, turn set the volume back to the previous level
                    volumeSlider.setValue(origVolume, animated: false)
                }
            }
            player.play()
        } catch {
            print(error)
        }
    }
}

Remember: with loud volume comes loud user reactions, so use this sparingly!

Leave a Reply

Your email address will not be published.

top