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

Pump up the volume

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