AVAudioPlayer - AVFoundation
AVAudioPlayer makes easy to playback the audio data from local files and memory. It is built on top of Core Audio’s C-based Audio Queue Service. It provides all core functions we can find in Audio Queue Service.
Things that AVAudioPlayer can’t do:
- Play audio from a network stream
- Access the raw audio sample
- Require very low latency
Create AVAudioPlayer
The AVAudioPlayer can be created by NSData or NSURL.
1 | // Initializer for AVAudioPlayer |
Controlling Playback
AVAudioPlayer provides ways for us to modify the player’s volume, panning, playback rate, number of looping and preform audio metering.
Calling play() will play a sound asynchronously. It will implicitly call the prepareToPlay() if the audio player is not already prepared to play. We can call the prepareToPlay() method after we created a audio player to minimize the lag between calling the play() method. Calling stop() method will stop the playback and undo the setup from prepareToPlay().
1 | /* set the audio player’s stereo pan position, value from -1.0 to 1.0. A value of -1.0 is full left, 0.0 is center, 1.0 is full right. */ |
Audio Level Metering
AVAudioPlayer doesn’t meter the audio-level by default. We can turn it on and get average sound decibel and peak decibel.
1 | /* default is not enabled */ |
Configure AVAudioSession
In order to make our app playback sound when we lock the screen or we turn our cellphones to silent mode, we need to choose the correct AVAudioSessionCategory to AVAudioSession.AVAudioSession is a global singleton instance. We can configure it after app launched. There are several categories. https://developer.apple.com/documentation/avfoundation/avaudiosession/audio_session_categories
| Category | Allows Mixing | Audio Input | Audio Output | When Screen Lock | When Silent |
|---|---|---|---|---|---|
| Ambient | yes | no | yes | off | off |
| Solo Ambient | no | no | yes | off | off |
| Playback | optional | no | yes | on | on |
| Record | no | yes | no | on | on |
| Play and Record | optional | yes | yes | on | on |
| Multi-Route | no | yes | yes | on | on |
1 | // Configure AVAudioSession |
In order to make the app play in the background, we also need change the info.plist file. Add following code to the file.
1 | <key>UIBackgroundModes</key> |
Adding this setting specifies that the application is now allowed to play audio in the background.
Handle Interruption
When we got a call or alarm, our app will automatically pause the sound, but it will not play the sound after the interruption. We can listen the AVAudioSessionInterruptionNotification notification and code the behavior we want.
1 | // add notification for audio player controller |
Handle Route Change
When we switch the audio output route, iOS will send a route change notification. Suppose we want to stop the playback when users unplug their headphone, we can check the notification’s userInfo dictionary for the route change reason and for a description of the previous audio route. If previous portType is AVAudioSessionPortHeadphones, we stop the playback.
1 | // Note This is not calling from main thread |
AVAudioPlayer Delegate
1 | // Called when audioplayer finished playing. |
Here is the link for the test app: AVAudioPlayer Test App
