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