• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  ```