• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 使用AudioSession管理应用音频焦点(ArkTS)
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相关ArkTS API的使用方法和注意事项,更多音频焦点及音频会话的信息,可参考:[音频焦点和音频会话介绍](audio-playback-concurrency.md)。
14
15## 获取音频会话管理器
16
17创建AudioSessionManager实例。在使用AudioSessionManager的API前,需要先通过[getSessionManager](../../reference/apis-audio-kit/arkts-apis-audio-AudioManager.md#getsessionmanager12)创建实例。
18
19  ```ts
20  import { audio } from '@kit.AudioKit';
21
22  let audioManager = audio.getAudioManager();
23  let audioSessionManager: audio.AudioSessionManager = audioManager.getSessionManager();
24  ```
25
26## 激活音频会话
27
28应用可以通过[AudioSessionManager.activateAudioSession](../../reference/apis-audio-kit/arkts-apis-audio-AudioSessionManager.md#activateaudiosession12)接口激活当前应用的音频会话。
29
30应用在激活AudioSession时,需指定[音频会话策略(AudioSessionStrategy)](audio-playback-concurrency.md#音频会话策略audiosessionstrategy)。策略中包含参数concurrencyMode,其类型为[AudioConcurrencyMode](../../reference/apis-audio-kit/arkts-apis-audio-e.md#audioconcurrencymode12),用于声明音频并发策略。
31
32  ```ts
33  import { audio } from '@kit.AudioKit';
34  import { BusinessError } from '@kit.BasicServicesKit';
35
36  let strategy: audio.AudioSessionStrategy = {
37    concurrencyMode: audio.AudioConcurrencyMode.CONCURRENCY_MIX_WITH_OTHERS
38  };
39
40  audioSessionManager.activateAudioSession(strategy).then(() => {
41    console.info('Succeeded in doing activateAudioSession.');
42  }).catch((err: BusinessError) => {
43    console.error(`Failed to activateAudioSession. Code: ${err.code}, message: ${err.message}`);
44  });
45  ```
46
47## 查询音频会话是否已激活
48
49应用可以通过[isAudioSessionActivated](../../reference/apis-audio-kit/arkts-apis-audio-AudioSessionManager.md#isaudiosessionactivated12)接口检查当前应用的音频会话是否已激活。
50
51  ```ts
52  let isActivated = audioSessionManager.isAudioSessionActivated();
53  ```
54
55## 停用音频会话
56
57应用可以通过[deactivateAudioSession](../../reference/apis-audio-kit/arkts-apis-audio-AudioSessionManager.md#deactivateaudiosession12)接口停用当前应用的音频会话。
58
59  ```ts
60  import { BusinessError } from '@kit.BasicServicesKit';
61
62  audioSessionManager.deactivateAudioSession().then(() => {
63    console.info('Succeeded in doing deactivateAudioSession.');
64  }).catch((err: BusinessError) => {
65    console.error(`Failed to deactivateAudioSession. Code: ${err.code}, message: ${err.message}`);
66  });
67  ```
68
69## 监听音频会话停用事件
70
71应用可以通过[on('audioSessionDeactivated')](../../reference/apis-audio-kit/arkts-apis-audio-AudioSessionManager.md#onaudiosessiondeactivated12)接口监听[音频会话停用事件(AudioSessionDeactivatedEvent)](../../reference/apis-audio-kit/arkts-apis-audio-i.md#audiosessiondeactivatedevent12)。
72
73当AudioSession被停用(非主动停用)时,应用会收到[音频会话停用事件(AudioSessionDeactivatedEvent)](../../reference/apis-audio-kit/arkts-apis-audio-i.md#audiosessiondeactivatedevent12),其中包含[音频会话停用原因(AudioSessionDeactivatedReason)](../../reference/apis-audio-kit/arkts-apis-audio-e.md#audiosessiondeactivatedreason12)。
74
75在收到AudioSessionDeactivatedEvent时,应用可根据自身业务需求,做相应的处理,例如释放相应资源、重新激活AudioSession等。
76
77  ```ts
78  import { audio } from '@kit.AudioKit';
79
80  audioSessionManager.on('audioSessionDeactivated', (audioSessionDeactivatedEvent: audio.AudioSessionDeactivatedEvent) => {
81    console.info(`reason of audioSessionDeactivated: ${audioSessionDeactivatedEvent.reason} `);
82  });
83  ```
84
85## 取消监听音频会话停用事件
86
87应用可以通过[off('audioSessionDeactivated')](../../reference/apis-audio-kit/arkts-apis-audio-AudioSessionManager.md#offaudiosessiondeactivated12)接口取消监听音频会话停用事件。
88
89  ```ts
90  audioSessionManager.off('audioSessionDeactivated');
91  ```
92
93
94**音频会话从创建到激活并监听的完整示例:**
95
96  ```ts
97  import { audio } from '@kit.AudioKit';
98  import { BusinessError } from '@kit.BasicServicesKit';
99
100  let audioManager = audio.getAudioManager();
101  // 创建音频会话管理器。
102  let audioSessionManager: audio.AudioSessionManager = audioManager.getSessionManager();
103  // 设置音频并发模式。
104  let strategy: audio.AudioSessionStrategy = {
105    concurrencyMode: audio.AudioConcurrencyMode.CONCURRENCY_MIX_WITH_OTHERS
106  };
107
108  // 激活音频会话。
109  audioSessionManager.activateAudioSession(strategy).then(() => {
110    console.info('Succeeded in doing activateAudioSession.');
111  }).catch((err: BusinessError) => {
112    console.error(`Failed to activateAudioSession. Code: ${err.code}, message: ${err.message}`);
113  });
114
115  // 查询音频会话是否已激活。
116  let isActivated = audioSessionManager.isAudioSessionActivated();
117
118  // 监听音频会话停用事件。
119  audioSessionManager.on('audioSessionDeactivated', (audioSessionDeactivatedEvent: audio.AudioSessionDeactivatedEvent) => {
120    console.info(`reason of audioSessionDeactivated: ${audioSessionDeactivatedEvent.reason} `);
121  });
122
123  // 音频会话激活后,应用在此处正常执行音频播放、暂停、停止、释放等操作即可。
124
125  // 停用音频会话。
126  audioSessionManager.deactivateAudioSession().then(() => {
127    console.info('Succeeded in doing deactivateAudioSession.');
128  }).catch((err: BusinessError) => {
129    console.error(`Failed to deactivateAudioSession. Code: ${err.code}, message: ${err.message}`);
130  });
131
132  // 取消监听音频会话停用事件。
133  audioSessionManager.off('audioSessionDeactivated');
134  ```
135
136## 通过设置AudioSession场景参数申请焦点
137应用通过AudioSession申请焦点。首先要调用接口[setAudioSessionScene](../../reference/apis-audio-kit/arkts-apis-audio-AudioSessionManager.md#setaudiosessionscene20)设置场景参数,然后调用[activateAudioSession](../../reference/apis-audio-kit/arkts-apis-audio-AudioSessionManager.md#activateaudiosession12)接口激活AudioSession。
138  ```ts
139  import { audio } from '@kit.AudioKit';
140  import { BusinessError } from '@kit.BasicServicesKit';
141
142  audioSessionManager.setAudioSessionScene(audio.AudioSessionScene.AUDIO_SESSION_SCENE_MEDIA);
143
144  let strategy: audio.AudioSessionStrategy = {
145    concurrencyMode: audio.AudioConcurrencyMode.CONCURRENCY_MIX_WITH_OTHERS
146  };
147
148  audioSessionManager.activateAudioSession(strategy).then(() => {
149    console.info('activateAudioSession SUCCESS');
150  }).catch((err: BusinessError) => {
151    console.error(`ERROR: ${err}`);
152  });
153  ```
154
155## 监听AudioSession焦点状态变化事件
156通过[AudioSession焦点状态事件(AudioSessionStateChangedEvent)](../../reference/apis-audio-kit/arkts-apis-audio-i.md#audiosessionstatechangedevent20)监听音频会话焦点状态的变化。
157
158**AudioSession申请焦点以及监听焦点变化事件的完整示例:**
159
160```ts
161import { audio } from '@kit.AudioKit';  // 导入audio模块。
162import { BusinessError } from '@kit.BasicServicesKit'; // 导入BusinessError。
163
164let audioSessionStateChangedCallback = (audioSessionStateChangedEvent: audio.AudioSessionStateChangedEvent) => {
165  console.info(`hint of audioSessionStateChanged: ${audioSessionStateChangedEvent.stateChangeHint} `);
166
167  switch (audioSessionStateChangedEvent.stateChangeHint) {
168  case audio.AudioSessionStateChangeHint.AUDIO_SESSION_STATE_CHANGE_HINT_PAUSE:
169    // 此分支表示系统已将音频流暂停,应用需切换至音频暂停状态。
170    // 临时失去焦点:其他音频流释放音频焦点后,本音频流会收到resume事件,可继续播放。
171    break;
172  case audio.AudioSessionStateChangeHint.AUDIO_SESSION_STATE_CHANGE_HINT_RESUME:
173    // 此分支表示系统解除AudioSession焦点的暂停操作。
174    break;
175  case audio.AudioSessionStateChangeHint.AUDIO_SESSION_STATE_CHANGE_HINT_STOP:
176    // 此分支表示系统已将音频流停止(永久失去焦点),为保持状态一致,应用需切换至音频暂停状态。
177    // 永久失去焦点:后续不会再收到音频焦点事件,恢复播放需用户主动触发。
178    break;
179  case audio.AudioSessionStateChangeHint.AUDIO_SESSION_STATE_CHANGE_HINT_TIME_OUT_STOP:
180    // 此分支表示由于长时间无音频流播放,系统已将AudioSession停止(永久失去焦点),应用需切换至音频暂停状态。
181    // 永久失去焦点:后续不会再收到音频焦点事件,恢复播放需用户主动触发。
182    break;
183  case audio.AudioSessionStateChangeHint.AUDIO_SESSION_STATE_CHANGE_HINT_DUCK:
184    // 此分支表示系统已将音频音量降低(默认降到正常音量的20%)。
185    break;
186  case audio.AudioSessionStateChangeHint.AUDIO_SESSION_STATE_CHANGE_HINT_UNDUCK:
187    // 此分支表示系统已将音频音量恢复正常。
188    break;
189  default:
190    break;
191  }
192};
193
194let audioManager = audio.getAudioManager();
195let audioSessionManager = audioManager.getSessionManager();
196
197audioSessionManager.on('audioSessionStateChanged', audioSessionStateChangedCallback);
198
199// 示例中选择了AUDIO_SESSION_SCENE_MEDIA会话场景,实际情况请根据具体场景修改该参数。
200audioSessionManager.setAudioSessionScene(audio.AudioSessionScene.AUDIO_SESSION_SCENE_MEDIA);
201
202// 示例中选择了CONCURRENCY_MIX_WITH_OTHERS策略,请根据具体场景修改该参数。
203let strategy: audio.AudioSessionStrategy = {
204  concurrencyMode: audio.AudioConcurrencyMode.CONCURRENCY_MIX_WITH_OTHERS
205};
206
207// 激活AudioSession,即抢占焦点
208audioSessionManager.activateAudioSession(strategy).then(() => {
209  console.info('activateAudioSession SUCCESS');
210}).catch((err: BusinessError) => {
211  console.error(`ERROR: ${err}`);
212});
213
214// 根据实际业务,可以启动多个AudioRenderer等音频播放。
215
216// 结束AudioSession,即释放焦点
217audioSessionManager.deactivateAudioSession().then(() => {
218  console.info('deactivateAudioSession SUCCESS');
219}).catch((err: BusinessError) => {
220  console.error(`ERROR: ${err}`);
221});
222
223audioSessionManager.off('audioSessionStateChanged', audioSessionStateChangedCallback);
224
225```
226