1# 使用AudioSession管理应用音频焦点(C/C++) 2<!--Kit: Audio Kit--> 3<!--Subsystem: Multimedia--> 4<!--Owner: @songshenke--> 5<!--Designer: @caixuejiang; @hao-liangfei; @zhanganxiang--> 6<!--Tester: @Filger--> 7<!--Adviser: @zengyawen--> 8 9对于涉及多个音频流并发播放的场景,系统已预设了默认的[音频焦点策略](audio-playback-concurrency.md#音频焦点策略),该策略将对所有音频流(包括播放和录制)实施统一的焦点管理。 10 11应用可利用音频会话管理(AudioSessionManager)提供的接口,通过AudioSession主动管理应用内音频流的焦点,自定义本应用音频流的焦点策略,调整本应用音频流释放音频焦点的时机,从而贴合应用特定的使用需求。 12 13本文档主要介绍AudioSession相关C API的使用方法和注意事项,更多音频焦点及音频会话的信息,可参考:[音频焦点和音频会话介绍](audio-playback-concurrency.md)。 14 15## 使用入门 16 17应用要使用OHAudio提供的音频会话管理(AudioSessionManager)能力,需要添加对应的头文件。 18 19### 在 CMake 脚本中链接动态库 20 21``` cmake 22target_link_libraries(sample PUBLIC libohaudio.so) 23``` 24 25### 添加头文件 26 27应用通过引入[native_audio_session_manager.h](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md)头文件,使用音频播放相关API。 28 29```cpp 30#include <ohaudio/native_audio_session_manager.h> 31``` 32 33## 获取音频会话管理器 34 35创建[OH_AudioSessionManager](../../reference/apis-audio-kit/capi-ohaudio-oh-audiosessionmanager.md)实例。在使用音频会话管理功能前,需要先通过[OH_AudioManager_GetAudioSessionManager](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiomanager_getaudiosessionmanager)创建音频会话管理实例。 36 37 ```cpp 38 OH_AudioSessionManager *audioSessionManager; 39 OH_AudioManager_GetAudioSessionManager(&audioSessionManager); 40 ``` 41 42## 激活音频会话 43 44应用可以通过[OH_AudioSessionManager_ActivateAudioSession](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosessionmanager_activateaudiosession)接口激活当前应用的音频会话。 45 46应用在[激活音频会话](#激活音频会话)时,需指定[音频会话策略(OH_AudioSession_Strategy)](../../reference/apis-audio-kit/capi-ohaudio-oh-audiosession-strategy.md),其中包含[音频并发模式(OH_AudioSession_ConcurrencyMode)](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosession_concurrencymode)参数,用于声明不同的音频并发策略。 47 48 ```cpp 49 OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS}; 50 51 OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy); 52 ``` 53 54## 查询音频会话是否已激活 55 56应用可以通过[OH_AudioSessionManager_IsAudioSessionActivated](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosessionmanager_isaudiosessionactivated)接口检查当前应用的音频会话是否已激活。 57 58 ```cpp 59 bool isActivated = OH_AudioSessionManager_IsAudioSessionActivated(audioSessionManager); 60 ``` 61 62## 停用音频会话 63 64应用可以通过[OH_AudioSessionManager_DeactivateAudioSession](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosessionmanager_deactivateaudiosession)接口停用当前应用的音频会话。 65 66 ```cpp 67 OH_AudioSessionManager_DeactivateAudioSession(audioSessionManager); 68 ``` 69 70## 监听音频会话停用事件 71 72在使用AudioSession功能的过程中,推荐应用监听[音频会话停用事件(OH_AudioSession_DeactivatedEvent)](../../reference/apis-audio-kit/capi-ohaudio-oh-audiosession-deactivatedevent.md)。 73 74当AudioSession被停用(非主动停用)时,应用会收到[音频会话停用事件(OH_AudioSession_DeactivatedEvent)](../../reference/apis-audio-kit/capi-ohaudio-oh-audiosession-deactivatedevent.md),其中包含[音频会话停用原因(OH_AudioSession_DeactivatedReason)](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosession_deactivatedreason)。 75 76在收到AudioSessionDeactivatedEvent时,应用可根据自身业务需求,做相应的处理,例如释放相应资源、重新激活AudioSession等。 77 78### 定义回调函数 79 80 ```cpp 81 int32_t MyAudioSessionDeactivatedCallback(OH_AudioSession_DeactivatedEvent event) 82 { 83 switch(event.reason) { 84 case DEACTIVATED_LOWER_PRIORITY: 85 // 应用焦点被抢占。 86 return 0; 87 case DEACTIVATED_TIMEOUT: 88 // 超时。 89 return 0; 90 } 91 } 92 ``` 93 94### 注册音频会话停用事件回调 95 96应用可以通过[OH_AudioSessionManager_RegisterSessionDeactivatedCallback](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosessionmanager_registersessiondeactivatedcallback)接口监听音频会话停用事件。 97 98```cpp 99OH_AudioSessionManager_RegisterSessionDeactivatedCallback(audioSessionManager, MyAudioSessionDeactivatedCallback); 100``` 101 102### 取消注册音频会话停用事件回调 103 104应用可以通过[OH_AudioSessionManager_UnregisterSessionDeactivatedCallback](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosessionmanager_unregistersessiondeactivatedcallback)接口取消监听音频会话停用事件。 105 106```cpp 107OH_AudioSessionManager_UnregisterSessionDeactivatedCallback(audioSessionManager, MyAudioSessionDeactivatedCallback); 108``` 109 110**音频会话从创建到激活并监听的完整示例:** 111 112参考以下示例,完成音频会话从创建到激活并监听的过程。 113 114 ```cpp 115 #include <cstdint> 116 #include "ohaudio/native_audio_session_manager.h" 117 118 int32_t MyAudioSessionDeactivatedCallback(OH_AudioSession_DeactivatedEvent event) 119 { 120 switch(event.reason) { 121 case DEACTIVATED_LOWER_PRIORITY: 122 // 应用焦点被抢占。 123 return 0; 124 case DEACTIVATED_TIMEOUT: 125 // 超时。 126 return 0; 127 } 128 } 129 130 OH_AudioSessionManager *audioSessionManager; 131 132 // 创建音频会话管理器。 133 OH_AudioCommon_Result resultManager = OH_AudioManager_GetAudioSessionManager(&audioSessionManager); 134 135 OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS}; 136 137 // 设置音频并发模式并激活音频会话。 138 OH_AudioCommon_Result resultActivate = OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy); 139 140 // 查询音频会话是否已激活。 141 bool isActivated = OH_AudioSessionManager_IsAudioSessionActivated(audioSessionManager); 142 143 // 监听音频会话停用事件。 144 OH_AudioCommon_Result resultRegister = OH_AudioSessionManager_RegisterSessionDeactivatedCallback(audioSessionManager, MyAudioSessionDeactivatedCallback); 145 146 // 音频会话激活后应用在此处正常执行音频播放、暂停、停止、释放等操作即可。 147 148 // 取消监听音频会话停用事件。 149 OH_AudioCommon_Result resultUnregister = OH_AudioSessionManager_UnregisterSessionDeactivatedCallback(audioSessionManager, MyAudioSessionDeactivatedCallback); 150 151 // 停用音频会话。 152 OH_AudioCommon_Result resultDeactivate = OH_AudioSessionManager_DeactivateAudioSession(audioSessionManager); 153 ``` 154## 通过设置AudioSession场景参数申请焦点 155应用通过AudioSession申请焦点。首先要调用接口[OH_AudioSessionManager_SetScene](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosessionmanager_setscene)设置场景参数,然后调用[OH_AudioSessionManager_ActivateAudioSession](../../reference/apis-audio-kit/capi-native-audio-session-manager-h.md#oh_audiosessionmanager_activateaudiosession)接口激活AudioSession。 156 157 ```cpp 158 159 OH_AudioSessionManager_SetScene(audioSessionManager, AUDIO_SESSION_SCENE_MEDIA); 160 161 OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS}; 162 163 OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy); 164 ``` 165 166## 监听AudioSession焦点状态变化事件 167通过[AudioSession焦点状态事件(OH_AudioSession_StateChangedEvent)](../../reference/apis-audio-kit/capi-ohaudio-oh-audiosession-statechangedevent.md)监听音频会话焦点状态的变化。 168 169**AudioSession申请焦点以及监听焦点变化事件的完整示例:** 170 171 ```cpp 172 173OH_AudioSessionManager *audioSessionManager; 174 175// 创建音频会话管理器。 176OH_AudioCommon_Result resultManager = OH_AudioManager_GetAudioSessionManager(&audioSessionManager); 177 178void AudioSessionStateChangedCallback(OH_AudioSession_StateChangedEvent event) 179 { 180 switch(event.stateChangeHint) { 181 case AUDIO_SESSION_STATE_CHANGE_HINT_PAUSE: 182 // 此分支表示系统已将音频流暂停(临时失去焦点),为保持状态一致,应用需切换至音频暂停状态。 183 // 临时失去焦点:其他音频流释放音频焦点后,本音频流会收到resume事件,可继续播放。 184 break; 185 case AUDIO_SESSION_STATE_CHANGE_HINT_RESUME: 186 // 此分支表示系统解除对AudioSession焦点的暂停操作。 187 break; 188 case AUDIO_SESSION_STATE_CHANGE_HINT_STOP: 189 // 此分支表示系统已将音频流停止(永久失去焦点),为保持状态一致,应用需切换至音频暂停状态。 190 // 永久失去焦点:后续不会再收到任何音频焦点事件,若想恢复播放,需要用户主动触发。 191 break; 192 case AUDIO_SESSION_STATE_CHANGE_HINT_TIME_OUT_STOP: 193 // 此分支表示由于长时间没有音频流播放,为防止系统资源被长时间无效占用,系统已将AudioSession停止(永久失去焦点),为保持状态一致,应用需切换至音频暂停状态。 194 // 永久失去焦点:后续不会再收到任何音频焦点事件,若想恢复播放,需要用户主动触发。 195 break; 196 case AUDIO_SESSION_STATE_CHANGE_HINT_DUCK: 197 // 此分支表示系统已将音频音量降低(默认降到正常音量的20%)。 198 break; 199 case AUDIO_SESSION_STATE_CHANGE_HINT_UNDUCK: 200 // 此分支表示系统已将音频音量恢复正常。 201 break; 202 default: 203 break; 204 } 205 } 206 207 OH_AudioCommon_Result result = OH_AudioSessionManager_RegisterStateChangeCallback(audioSessionManager, AudioSessionStateChangedCallback); 208 209 // AUDIO_SESSION_SCENE_MEDIA 仅为示例,实际使用时请根据具体情况进行修改。 210 OH_AudioSessionManager_SetScene(audioSessionManager, AUDIO_SESSION_SCENE_MEDIA); 211 212 // CONCURRENCY_MIX_WITH_OTHERS 是示例,实际使用时请根据情况修改 213 OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS}; 214 215 result = OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy); 216 217 // 根据实际业务,可以启动多个AudioRenderer等音频播放 218 219 result = OH_AudioSessionManager_DeactivateAudioSession(audioSessionManager); 220 221 result = OH_AudioSessionManager_UnregisterStateChangeCallback(audioSessionManager, AudioSessionStateChangedCallback); 222 223 ```