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