Audio output as a hardware resource is unique for iOS systems, so how do you reconcile and hold relationships between apps for this scarce hardware?
The solution given by iOS is "avaudiosession", which enables control over the current context audio resources of the app, such as
Plug and unplug headphones, answer phones, and mix audio data. When you encounter:
- Is it a recording or a play?
- How do I behave when the system mute key is pressed?
- Do you play the sound from the speaker or from the earpiece?
- How do I behave after I Plug and unplug headphones?
- How do you behave when the phone/alarm clock rings?
- How does the other audio app behave after it's started?
- ...
These scenes, you can consider the "avaudiosession".
??????
A long time ago (in fact, it is not too long--ios7 before) there is a audiosession, its function and avaudiosession similar, but after IOS7 has been marked as
"Not applicable", so if Google to say audiosession content instead of avaudiosession, then you can pass directly, of course, if you want to be compatible with iOS6
It is a matter of other things, but now qq/are required iOS7, whether the need for compatibility iOS6 look at the boss's meaning it.
Session default behavior
- Can be played, but not recorded.
- When the user dials the mute dial on the phone to mute, the playback is muted if the audio is playing.
- When the user presses the phone's lock screen key or the phone automatically locks the screen, if the audio is playing, then the playback will be muted and paused.
- If your app starts playing, and other apps such as QQ Music are playing, the other players will be muted and paused.
The default behavior is equivalent to setting the category "Avaudiosessioncategorysoloambient"
See demo.
Demo_player
This player demo allows you to verify the default session behavior above.
Avaudiosession
Avaudiosession exists in the form of a singleton entity, through the class method:
+ (AVAudioSession *)sharedInstance;
Get a single case.
Although the system activates this unique avaudiosession when the app is launched, it's best to activate it again in your own Viewcontroller viewDidLoad
:
- (BOOL)setActive:(BOOL)active error:(NSError * _Nullable *)outError;
By setting the active
session to "YES", set the session to "NO" to dismiss the activation status. The bool return value indicates whether it was successful, and if it fails, the cause of the error can be viewed by Nserror error.localizedDescription
.
Because Avaudiosession will affect the performance of other apps, when the session of their app is activated, the other apps will be deactivated, how to get their session deactivated after the other app session activation state?
At this point you can use:
- (BOOL) SetActive: (BOOL) Active
Withoptions: (avaudiosessionsetactiveoptions) options
Error: (Nserror * _nullable *) Outerror;
Here's the options to pass in AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation
.
Of course, you can also use otherAudioPlaying
variables to determine in advance whether any other apps are currently playing audio.
You can do this by:
@property(readonly) NSString *category;
property to get the current category, such as playing it above, the default is
NSLog(@"Current Category:%@", [AVAudioSession sharedInstance].category);
Output:
Current Category:AVAudioSessionCategorySoloAmbien
Seven major category
Avaudiosession can control the performance of the app and how to control it? First avaudiosession will use the audio scene into seven categories, by setting the session for different categories, you can control:
- When the app activates the session, does it interrupt other app sounds that don't support the mix
- when the user triggers the mute button on the phone or when the lock screen is muted
- current status supports recording
- Whether the current status supports playback
Each app is set to the default state stated above, which means that other apps will be interrupted with the corresponding "mute" key playback mode. The following table provides a breakdown of the support scenarios for each category:
category |
when you press "mute" or if the lock screen is muted |
whether to cause app interrupts that don't support mixing |
whether to support recording and playback |
Avaudiosessioncategoryambient |
Is |
Whether |
Supports playback only |
Avaudiosessioncategoryaudioprocessing |
- |
are not supported |
Avaudiosessioncategorymultiroute |
Whether |
Is |
Can be recorded or played |
Avaudiosessioncategoryplayandrecord |
Whether |
Default does not cause |
Can be recorded or played |
Avaudiosessioncategoryplayback |
Whether |
Caused by default |
Only for playback |
Avaudiosessioncategoryrecord |
Whether |
Is |
For recording only |
Avaudiosessioncategorysoloambient |
Is |
Is |
Only for playback |
As you can see, the default is the "avaudiosessioncategorysoloambient" category. From the table we can summarize the following:
- Avaudiosessioncategoryambient: Only for playing music, and can play with QQ music at the same time, such as playing the game also want to listen to QQ music songs, then the game play background sound set to this category. At the same time, when the user lock screen or mute will also be muted, this category basically use all the background scenes of the app.
- Avaudiosessioncategorysoloambient: It is only used for play, but unlike "avaudiosessioncategoryambient", it is not to listen to QQ music, such as the app that does not want QQ music interference, Like a master of rhythm. Also when the user lock screen or mute will be mute, lock screen will not play the master rhythm.
- Avaudiosessioncategoryplayback: What if I lock the screen and want to hear the sound? Use this category, such as the app itself is the player, while the app plays, other similar QQ music can not be played. So this category is generally used in the player class app
- Avaudiosessioncategoryrecord: With the player, definitely to the recorder, such as voice recording, it is necessary to use this category, since to quiet recording, certainly do not want to have QQ music, so other playback sound will be interrupted. Think about the speech scene and know when to use him.
- Avaudiosessioncategoryplayandrecord: What mode do you want to record if you want to play it? such as VoIP, call this scene, Playandrecord is specifically designed for such a scene.
- Avaudiosessioncategorymultiroute: Imagine a DJ with the app, the phone attached to the HDMI to the speaker to play the current music, and then play the next song in the headset, this ordinary people do not understand the scene, this category can support multiple device input and output.
- Avaudiosessioncategoryaudioprocessing: Mainly used for audio format processing, generally can be used in conjunction with AudioUnit
By understanding the seven categories, we can set the corresponding categories according to our own needs:
- (BOOL)setCategory:(NSString *)category error:(NSError **)outError;
The corresponding list enumeration can be passed in. If you return "NO" You can view the reason by Nserror error.localizedDescription
.
You can do this by:
@property(readonly) NSArray<NSString *> *availableCategories;
property to see which categories are supported by the current device, and then set up to ensure that the incoming parameters are legitimate and reduce the likelihood of errors.
For example, modify the demo example above:
NSLog(@"Current Category:%@", [AVAudioSession sharedInstance].category); NSError *error = nil; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error]; if (nil != error) { NSLog(@"set Option error %@", error.localizedDescription); } NSLog(@"Current Category:%@", [AVAudioSession sharedInstance].category);
At this time when playing music, and then to press the mute button, you will find that the music continues to play, will not be muted.
Options for categories
The seven categories described above can be thought of as setting up seven main scenarios, and these seven classes must not meet the needs of developers. CoreAudio provides a way to first set a tone of seven kinds, and then fine-tune it. CoreAudio provides a few options for fine-tuning each category.
After you have set up the categories, you can
@property(readonly) AVAudioSessionCategoryOptions categoryOptions;
property to see what options are set for the current category, note that the return value here is avaudiosessioncategoryoptions, which is actually multiple options ' | ' Operation. By default, it is 0.
option |
applicable category |
role |
avaudioses Sioncategoryoptionmixwithothers |
Avaudiosessioncategoryplayandrecord, Avaudiosessioncategoryplayback, and Avaudiosessioncategorymultiroute |
can mix with other background apps |
Avaudiosessioncategoryoptionducko Thers |
avaudiosessioncategoryambient, Avaudiosessioncategoryplayandrecord, Avaudiosessioncategoryplayback , and Avaudiosessioncategorymultiroute |
suppress other app sounds |
Avaudiosessioncategoryoptionallo Wbluetooth |
Avaudiosessioncategoryrecord and Avaudiosessioncategoryplayandrecord |
support for Bluetooth headphones |
avaudiosessioncategoryoptiondefaulttospeaker |
avaudiosessioncategoryplayandrecord |
whether to use hands-free audio |
At present, the main options have these, there are corresponding use scenes, in addition, in IOS9 also provides the AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
latest iOS10 plus two new AVAudioSessionCategoryOptionAllowBluetoothA2DP
, AVAudioSessionCategoryOptionAllowAirPlay
to support Bluetooth A2DP headphones and airplay.
Consider the basic role of each option:
- Avaudiosessioncategoryoptionmixwithothers: If you do use the avaudiosessioncategoryplayback to achieve a background sound, but also want to coexist with QQ music, Then you can set this option under the Avaudiosessioncategoryplayback category, and you can achieve coexistence.
- Avaudiosessioncategoryoptionduckothers: In real-time call scenes, such as QQ music, when the video call, you will find that QQ music automatic voice decreased, this is the option to set this to the other music app to suppress.
- Avaudiosessioncategoryoptionallowbluetooth: If you want to support a Bluetooth headset phone, you need to set this option
- Avaudiosessioncategoryoptiondefaulttospeaker: If you want to turn on the handsfree function by default in VoIP mode, you need to set this option
Via interface:
-(BOOL) Setcategory: (NSString *) category withoptions: (avaudiosessioncategoryoptions) Options Error: (Nserror *) Outerror
To set the options for the current category.
Like in the demo:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error]; if (nil != error) { NSLog(@"set Option error %@", error.localizedDescription); } options = [[AVAudioSession sharedInstance] categoryOptions]; NSLog(@"Category[%@] has %lu options", [AVAudioSession sharedInstance].category, options);
At this point, first open the QQ music player, and then start playing, you will find that QQ and our players are playing, and the automatic mixing.
However, this process, feel CoreAudio missing an setOption
interface, since it is currently in the category, why do you want to set the options again when you specify category?? Doubts...
Seven modes
Just finished the seven categories, now another seven models. Through the seven categories above, we basically cover the main scenes that are commonly used and can be fine-tuned in each main scene by option. This coreaudio provides seven more common fine-tuning sub-scenes. A pattern called each category.
Mode |
Applicable Categories |
Scene |
avaudiosessionmodedefault |
All categories |
default mode |
Avaudiosessionmodev Oicechat |
avaudiosessioncategoryplayandrecord |
VoIP |
avaudiosessionmodegamechat |
Avaudiosessioncategoryplayandrecord |
game recording, automatically set by Gkvoicechat, without manually calling |
avaudioses Sionmodevideorecording |
avaudiosessioncategoryplayandrecord avaudiosessioncategoryrecord |
when recording video |
avaudiosessionmodemovieplayback |
avaudiosessioncategoryplayback |
video playback | /tr>
avaudiosessionmodemeasurement |
Avaudiosessioncategoryplayandrecord Avaudiosessioncategoryrecord avaudiosessioncategoryplayback |
min system |
avaudiosessionmodevid Eochat |
avaudiosessioncategoryplayandrecord |
Video Call |
Each pattern has its applicable category, so there is not a "7,749" combination. If the current category does not have this pattern, then the setting is unsuccessful. After the category is set, you can pass:
@property(readonly) NSArray<NSString *> *availableModes;
property to see which properties it supports, and to check for legitimacy.
To see the specific application:
- Avaudiosessionmodedefault: This mode is the default for each category and is set to this mode if you want to restore it.
- Avaudiosessionmodevoicechat: Mainly used in VoIP scenarios, when the system will choose the best input device, such as plug-in headphones to use the microphone on the headset to collect. There is a side effect, and he will set the category option to "Avaudiosessioncategoryoptionallowbluetooth" to support the Bluetooth headset.
- Avaudiosessionmodevideochat: Mainly used for video calls, such as QQ video, FaceTime. The system will also choose the best input device, such as plug-in headphones to use the microphone on the headset to collect and set the options for the category "Avaudiosessioncategoryoptionallowbluetooth" and " Avaudiosessioncategoryoptiondefaulttospeaker ".
- Avaudiosessionmodegamechat: For the game app acquisition and playback, such as "Gkvoicechat" object, generally do not need to manually set
Other types of audio apps are not very related, we just need to focus on VoIP or video calls.
by calling:
- (BOOL)setMode:(NSString *)mode error:(NSError **)outError
You can set the mode after you set the category.
Of course, these models are only Coreaduio summary, not necessarily fully meet the requirements, for the specific mode, in the iOS10 can be fine-tuned. Via interface:
- (BOOL) Setcategory: (NSString *) Category mode: (NSString *) mode options: (avaudiosessioncategoryoptions) Options Error: ( Nserror * *) outerror
But in the iOS9 and below can only be raised in the category, in fact, the essence is the same, can be considered an API sugar, interface encapsulation.
System Interrupt Response
These are the category, option, and mode are the performance of their own as the main player, but assume that it is now playing, the sudden call, the alarm clock or you sing in the background but the user to start other apps with the above method influence, How is our app supposed to behave? The most common scenario is, of course, to pause before resuming. So how does our app perceive this terminal and when to recover it?
Avaudiosession provides a variety of notifications to inform such situations. In the future, telephone calls, alarm bells and so on are classified as general interruptions, with
AVAudioSessionInterruptionNotification
to inform. The userinfo of the callback comes back with a main two keys:
- Avaudiosessioninterruptiontypekey: value to
AVAudioSessionInterruptionTypeBegan
indicate the beginning of the interruption, we should pause playback and capture, value to AVAudioSessionInterruptionTypeEnded
indicate the end of the interruption, we can continue to play and capture.
- Avaudiosessioninterruptionoptionkey: There is currently only one value
AVAudioSessionInterruptionOptionShouldResume
indicating that playback and capture should resume at this time.
Use other apps to make notifications when they occupy Audiosession AVAudioSessionSilenceSecondaryAudioHintNotification
. The UserInfo key returned by its callback is:
AVAudioSessionSilenceSecondaryAudioHintTypeKey
The values that may be included:
- Avaudiosessionsilencesecondaryaudiohinttypebegin: Indicates that other apps are starting to occupy the session
- Avaudiosessionsilencesecondaryaudiohinttypeend: Means other apps start releasing session
Peripheral changes
In addition to other apps and system services, the user's hand can have an impact on our app. By default, Audiosession will select an optimal output scheme when the app is launched, such as headphones when plugged in. But in this process, the user may unplug the headset, how can our app perceive such a situation?
The same avaudiosession is also a notification of such conditions through notifications.
Suppose you have such an app:
Route_change
At the very beginning of the recording, the user plugs in and out of the headset we all stop recording, here through the notification to notify the new device, or the device was exited, and then we control stop recording. Or when playing, when the headset is unplugged, notification gives notice, we pause the music playback, when the headset is plugged back in, continue to play.
Register the Avaudiosessionroutechangenotification in the Nsnotificationcenter. There are keys in their userinfo:
- Avaudiosessionroutechangereasonkey: The reason for the change
enumeration Values |
meaning |
Avaudiosessionroutechangereasonunknown |
Unknown cause |
Avaudiosessionroutechangereasonnewdeviceavailable |
A new device is available |
Avaudiosessionroutechangereasonolddeviceunavailable |
Old device Not available |
Avaudiosessionroutechangereasoncategorychange |
The category has changed. |
Avaudiosessionroutechangereasonoverride |
The app resets the output settings |
Avaudiosessionroutechangereasonwakefromsleep |
Waking up from a sleep state |
Avaudiosessionroutechangereasonnosuitablerouteforcategory |
There are no suitable devices under the current category |
Avaudiosessionroutechangereasonrouteconfigurationchange |
The configuration of the Rotuer has changed |
- Avaudiosessionsilencesecondaryaudiohinttypekey: And the meaning of the interrupt above.
Summarize:
Avaudiosession constructs a context for the audio usage lifecycle. Whether the current state can record, how to affect other apps, whether to respond to the system's mute key, how to perceive the phone, etc. can be achieved through it. It is particularly important that avaudiosession not only cooperate with the Avaudioplyaer/avaudiorecorder in Avfoundation, but also other recording/playback tools such as AudioUnit, Audioqueueservice also need him to record, mute and other contextual cooperation.
In this demo see GitHub
Reference documents
- Audio Session Programming Guide
- Avaudiosession Class Reference
- Audio Session Services Reference
Cz_ios
Links: Https://www.jianshu.com/p/3e0a399380df
Source: Pinterest
The copyright of the book is owned by the author, and any form of reprint should be contacted by the author for authorization and attribution.
iOS Audio Dispensers--avaudiosession