1. What is AVAudioSession?

Official documents:

AVAudioSession is an object that communicates to the system how you will use audio in your application. Using AVAudioSession, you can describe to the operating system a general strategy for an application’s use of audio without having to detail how it behaves in a particular scenario or how it interacts with the audio hardware. You can delegate the management of these details to the AVAudioSession implementation to ensure that the operating system can best manage the user’s audio experience.

According to the document, AVAudioSession is a set of highly encapsulated minimalist APIS (hiding complex underlying logic and implementation details). Its purpose is to enable developers to manage audio more conveniently and quickly, which also conforms to apple’s consistent style of designing upper-level apis. This design style requires developers to pay no attention to the underlying details, but must clearly understand the audio performance and usage scenarios corresponding to each key parameter, so as to develop an excellent app in line with product expectations.

2. How to use AVAudioSession interface?

The API for AVAudioSession is very simple, and there are only two commonly used apis:

- (BOOL)setCategory:(AVAudioSessionCategory)category 
               mode:(AVAudioSessionMode)mode 
            options:(AVAudioSessionCategoryOptions)options 
              error:(NSError * _Nullable *)outError;  
              
- (BOOL)setActive:(BOOL)active 
      withOptions:(AVAudioSessionSetActiveOptions)options 
            error:(NSError * _Nullable *)outError;
Copy the code

The process of calling the API is also very simple. First set the working mode of AVAudioSession, then activate AVAudioSession, and the audio device can work normally. When audio finish work, in order to let other applications audio restoration, best to cancel the current AVAudioSession activated state and through AVAudioSessionSetActiveOptions to notice it.

Easy to make mistakes is to AVAudioSessionCategory, AVAudioSessionMode, AVAudioSessionCategoryOptions three parameters Settings. Due to the combination of parameters, mutual exclusion, or the high probability of binding Settings and other scenarios, the correct setting of the working mode has become a headache for developers.

The following takes AVAudioSessionCategory as the main line to sort out the audio usage scenarios corresponding to each parameter and the collaboration between parameters.

  • AVAudioSessionCategorySoloAmbient

If AudioSession is activated without setting the parameters, the system runs in SoloAmbient mode by default. The audio performance characteristics of this mode are as follows:

  1. When the user locks the screen or presses the mute button, the audio is muted.
  2. If it does not have the ability to mix, it will interrupt other app audio that also does not have the ability to mix.

As the default audio mode, SoloAmbient meets the most basic audio playback requirements, and developers do not need (and rarely can) configure any CategoryOptions for SoloAmbient.

  • AVAudioSessionCategoryAmbient

The performance is exactly the same as SoloAmbient, except that it allows mixing.

  • AVAudioSessionCategoryPlayback

‘Playing Audio is central to the successful use of your app’ is how the official document describes Playback working mode. When audio is a core feature of an app, Playback is the best choice. The audio performance characteristics of this mode are as follows:

  1. When the user locks the screen or presses the mute button, the audio continues to play. (Background play permission must be enabled for lock screen play)
  2. Mixing is not supported by default.

Can be realized by setting AVAudioSessionCategoryOptionMixWithOthers mixing Playback mode. Can be realized by setting AVAudioSessionCategoryOptionDuckOthers also at the same time reduce the volume of the other app audio mixing.

  • AVAudioSessionCategoryRecord

When the app only needs to record audio, you need to set Recod as the category. It is worth noting that the Record mode usually require binding options: AVAudioSessionCategoryOptionAllowBluetooth, to support bluetooth audio input function.

  • AVAudioSessionCategoryPlayAndRecord

Playback is a combination of Playback and Record. When your app needs to Record and play, set PlayAndRecord. PlayAndRecord mode has two special features:

  1. Audio output device default will choose the receiver, can be set up by AVAudioSessionCategoryOptionDefaultToSpeaker, instead of the default route to the speaker.
  2. Support for the bluetooth device, can set AVAudioSessionCategoryOptionAllowBluetoothA2DP as output, Can also be AVAudioSessionCategoryOptionAllowBluetooth set as the input/output. When both options are set, the HFP port on the Bluetooth device is given a higher routing priority.
  • AVAudioSessionCategoryMultiRoute

If multiple audio input and output devices need to work at the same time, you need to set CategoryMultiRoute.

Once AVAudioSession runs in this mode, the operating system no longer automatically selects the optimal audio routing path for the developer. You need to manually obtain AVAudioSessionChannelDescription and audio should be determined according to the needs of the business by which a channel input/output. When audio equipment to add or remove, through AVAudioSessionRouteChangeNotification monitoring, timely update the routing policy.


The above combination can meet most business requirements. However, imagine a business scenario where a navigation app playing navigation audio should be able to mix with the audio of other music apps (lowering the volume of music), but must interrupt other voice apps to avoid confusing users.

To achieve this requirement, we set the category for AVAudioSessionCategoryPlayback, and configure AVAudioSessionCategoryOptionDuckOthers parameters for the options, To achieve the effect of mixing and reducing the volume of music audio. In addition, also need to give the options to join AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers parameters to interrupt other voice app audio playback. Finally, we put the mode parameter set to AVAudioSessionModeSpokenAudio, to alert system, the current app is also a voice products, so that when other speech class AVAudioSession work, our app can break on the right and restored.

Here’s a typical example of how category, options, and mode work together: AVAudioSessionCategory to set the tone for the overall performance of the audio, AVAudioSessionCategoryOptions under the current tone on some strategies for audio fine-tuned, AVAudioSessionMode AVAudioSession set For a specific application scenario, it may optimize the input/output of the audio to correspond to the Mode scenario, or it may directly change the default performance of the audio under certain conditions.

3. When should AVAudioSession be set/activated?

AVAudioSession can be set and activated at any time.

My advice is to set the parameters as early as possible (preferably only once) and activate AVAudioSession as late as possible.

A complex audio app may have many audio-related components, some of which only need to be played, and some of which need to be recorded and played. If each module sets its own AVAudioSession parameters that are most appropriate for it, the audio components that require more permissions will not work properly when the business needs to combine them. Developers in didFinishLaunchingWithOptions best stage, therefore, is to determine the most suitable for app AVAudioSession parameters, and as far as possible not to do business later modify (or change AVAudioSessionMode only).

By activating AVAudioSession as late as possible, your app can affect the audio performance of other apps only when it really needs to play audio. Interrupting other AVAudioSession too soon, or lowering its volume, often leaves users confused.

4. How do third-party frameworks tamper with AVAudioSession?

The development of an APP usually requires the introduction of third-party SDK. In order to ensure the smooth execution of its own business logic, the AUDIO SDK generally directly sets appropriate AVAudioSession parameters internally (some excellent SDK will expose interfaces). The problem of parameter conflict between multiple SDKS and AVAudioSession can only be solved by the upper developers.

Unfortunately, the system does not provide notification or callback to AVAudioSession of parameter changes, and attributes such as category are marked as readonly (no set method is called internally), making the KVO solution unworkable. It seems difficult to directly monitor the changes of AVAudioSession parameters.

Through the analysis can be found, tamper with the behavior of business interaction caused by abnormal usually change the routing audio equipment, so listen AVAudioSessionRouteChangeNotification notice, And value judgment in the AVAudioSessionRouteChangeReasonKey AVAudioSessionRouteChangeReasonCategoryChange, conflict can capture all parameters of tamper with the behavior, Developers can reset the appropriate AVAudioSession parameters here to ensure the normal operation of the app.