文档管理中心
我的
您当前正在浏览新版开发者文档中心,目录分类和层级有所调整。点击左侧当前文档分类名称前的“☰”图标,可切换文档分类。 了解新版目录
指南媒体Audio Kit(音频服务)音频焦点和音频会话管理使用OHAudio开发音频会话功能(C/C++)

使用OHAudio开发音频会话功能(C/C++)

对于涉及多个音频流并发播放的场景,系统已预设了默认的音频焦点策略,该策略将对所有音频流(包括播放和录制)实施统一的焦点管理。

应用可利用音频会话管理(AudioSessionManager)提供的接口,通过AudioSession主动管理应用内音频流的焦点,自定义本应用音频流的焦点策略,调整本应用音频流释放音频焦点的时机,从而贴合应用特定的使用需求。

本文主要介绍AudioSession相关C API的使用方法和注意事项,更多音频焦点及音频会话的信息,可参考:音频焦点介绍和音频会话管理。

使用入门

应用要使用OHAudio提供的音频会话管理(AudioSessionManager)能力,需要添加对应的头文件。

以下各步骤示例为片段代码,可通过示例代码右下方链接获取完整示例。

在 CMake 脚本中链接动态库

收起
自动换行
深色代码主题
复制
  1. target_link_libraries(sample PUBLIC libohaudio.so)

添加头文件

应用通过引入native_audio_session_manager.h头文件,使用音频播放相关API。

收起
自动换行
深色代码主题
复制
  1. #include "ohaudio/native_audio_session_manager.h"

获取音频会话管理器

创建OH_AudioSessionManager实例。在使用音频会话管理功能前,需要先通过OH_AudioManager_GetAudioSessionManager创建音频会话管理实例。

收起
自动换行
深色代码主题
复制
  1. OH_AudioSessionManager *audioSessionManager;
  2. // ...
  3. OH_AudioCommon_Result resultManager = OH_AudioManager_GetAudioSessionManager(&audioSessionManager);
  4. if (resultManager == 0) {
  5. OH_LOG_Print(LOG_APP, LOG_INFO, g_audioSessionVariable->globalResmgr, SESSION_TAG,
  6. " OH_AudioManager_GetAudioSessionManager success! ");
  7. }
  8. OH_AudioCommon_Result result = OH_AudioSessionManager_RegisterStateChangeCallback(audioSessionManager,
  9. AudioSessionStateChangedCallback);

激活音频会话

应用可以通过OH_AudioSessionManager_ActivateAudioSession接口激活当前应用的音频会话。

应用在激活音频会话时,需指定音频会话策略(OH_AudioSession_Strategy),其中包含音频并发模式(OH_AudioSession_ConcurrencyMode)参数,用于声明不同的音频并发策略。

收起
自动换行
深色代码主题
复制
  1. // CONCURRENCY_MIX_WITH_OTHERS 是示例,实际使用时请根据情况修改。
  2. OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS};
  3. // 设置音频并发模式并激活音频会话。
  4. OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy);

查询音频会话是否已激活

应用可以通过OH_AudioSessionManager_IsAudioSessionActivated接口检查当前应用的音频会话是否已激活。

收起
自动换行
深色代码主题
复制
  1. bool isActivated = OH_AudioSessionManager_IsAudioSessionActivated(audioSessionManager);

设置会话级录音流静音提示

从API version 24开始,当应用已在业务侧将当前音频会话内的录音流静音时,可以调用OH_AudioSessionManager_SetCaptureMuteHint接口将该状态上报给系统音频模块,系统音频模块会基于上报的状态调整策略以降低功耗。注意,此功能当前仅在部分PC/2in1设备上生效。该接口不会实际触发静音,也不会对录音数据做静音处理。它只是告知系统音频模块,应用已将当前音频会话内的录音流静音。应用仍需自行处理录音数据,例如不发送采集数据或发送静音数据。

该接口仅允许在当前音频会话存在运行中的录音流时调用,否则会返回AUDIOCOMMON_RESULT_ERROR_ILLEGAL_STATE。若某条录音流同时调用了流级静音提示接口OH_AudioCapturer_SetMuteHint和会话级静音提示接口,流级设置优先级更高,以流级设置值为准。因此,当应用内多条录音流的静音状态一致时,可以使用会话级接口统一上报;当不同录音流静音状态不一致时,建议对具体录音流使用流级接口。若为了调用会话级接口而创建Mic音频源录音流,需要申请麦克风权限ohos.permission.MICROPHONE。

收起
自动换行
深色代码主题
复制
  1. bool mute = true;
  2. OH_AudioCommon_Result setResult = OH_AudioSessionManager_SetCaptureMuteHint(audioSessionManager, mute);
  3. if (setResult != AUDIOCOMMON_RESULT_SUCCESS) {
  4. // 根据返回值处理异常,如AUDIOCOMMON_RESULT_ERROR_ILLEGAL_STATE。
  5. }
  6. mute = false;
  7. OH_AudioCommon_Result unsetResult = OH_AudioSessionManager_SetCaptureMuteHint(audioSessionManager, mute);

停用音频会话

应用可以通过OH_AudioSessionManager_DeactivateAudioSession接口停用当前应用的音频会话。

收起
自动换行
深色代码主题
复制
  1. OH_AudioCommon_Result result;
  2. // ...
  3. result = OH_AudioSessionManager_DeactivateAudioSession(audioSessionManager);

监听音频会话停用事件

在使用AudioSession功能的过程中,推荐应用监听音频会话停用事件(OH_AudioSession_DeactivatedEvent)。

当AudioSession被停用(非主动停用)时,应用会收到音频会话停用事件(OH_AudioSession_DeactivatedEvent),其中包含音频会话停用原因(OH_AudioSession_DeactivatedReason)。

在收到AudioSessionDeactivatedEvent时,应用可根据自身业务需求,做相应的处理,例如释放相应资源、重新激活AudioSession等。

定义回调函数

收起
自动换行
深色代码主题
复制
  1. int32_t MyAudioSessionDeactivatedCallback(OH_AudioSession_DeactivatedEvent event)
  2. {
  3. switch (event.reason) {
  4. case DEACTIVATED_LOWER_PRIORITY:
  5. // 应用焦点被抢占。
  6. return 0;
  7. case DEACTIVATED_TIMEOUT:
  8. // 超时。
  9. return 0;
  10. }
  11. }
  12. OH_AudioSessionManager *audioSessionManager;

注册音频会话停用事件回调

应用可以通过OH_AudioSessionManager_RegisterSessionDeactivatedCallback接口监听音频会话停用事件。

收起
自动换行
深色代码主题
复制
  1. OH_AudioCommon_Result resultRegister = OH_AudioSessionManager_RegisterSessionDeactivatedCallback(
  2. audioSessionManager, MyAudioSessionDeactivatedCallback);

取消注册音频会话停用事件回调

应用可以通过OH_AudioSessionManager_UnregisterSessionDeactivatedCallback接口取消监听音频会话停用事件。

收起
自动换行
深色代码主题
复制
  1. OH_AudioCommon_Result resultUnregister = OH_AudioSessionManager_UnregisterSessionDeactivatedCallback(
  2. audioSessionManager, MyAudioSessionDeactivatedCallback);

音频会话从创建到激活并监听的完整示例:

参考以下示例,完成音频会话从创建到激活并监听的过程。

收起
自动换行
深色代码主题
复制
  1. #include <cstdint>
  2. #include "ohaudio/native_audio_session_manager.h"
  3. // ...
  4. int32_t MyAudioSessionDeactivatedCallback(OH_AudioSession_DeactivatedEvent event)
  5. {
  6. switch (event.reason) {
  7. case DEACTIVATED_LOWER_PRIORITY:
  8. // 应用焦点被抢占。
  9. return 0;
  10. case DEACTIVATED_TIMEOUT:
  11. // 超时。
  12. return 0;
  13. }
  14. }
  15. OH_AudioSessionManager *audioSessionManager;
  16. // ...
  17. OH_AudioCommon_Result resultManager = OH_AudioManager_GetAudioSessionManager(&audioSessionManager);
  18. // ...
  19. OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS};
  20. // 设置音频并发模式并激活音频会话。
  21. OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy);
  22. // 查询音频会话是否已激活。
  23. bool isActivated = OH_AudioSessionManager_IsAudioSessionActivated(audioSessionManager);
  24. if (isActivated) {
  25. OH_LOG_Print(LOG_APP, LOG_INFO, g_audioSessionVariable->globalResmgr, SESSION_TAG,
  26. " AudioSessionManager is activated! ");
  27. }
  28. // 监听音频会话停用事件。
  29. OH_AudioCommon_Result resultRegister = OH_AudioSessionManager_RegisterSessionDeactivatedCallback(
  30. audioSessionManager, MyAudioSessionDeactivatedCallback);
  31. // ...
  32. // 取消监听音频会话停用事件。
  33. result = OH_AudioSessionManager_UnregisterStateChangeCallback(audioSessionManager,
  34. AudioSessionStateChangedCallback);
  35. // ...
  36. // 停用音频会话。
  37. result = OH_AudioSessionManager_DeactivateAudioSession(audioSessionManager);

通过设置AudioSession场景参数申请焦点

应用通过AudioSession申请焦点。首先要调用接口OH_AudioSessionManager_SetScene设置场景参数,然后调用OH_AudioSessionManager_ActivateAudioSession接口激活AudioSession。

收起
自动换行
深色代码主题
复制
  1. // AUDIO_SESSION_SCENE_MEDIA 仅为示例,实际使用时请根据具体情况进行修改。
  2. OH_AudioSessionManager_SetScene(audioSessionManager, AUDIO_SESSION_SCENE_MEDIA);
  3. // ...
  4. // CONCURRENCY_MIX_WITH_OTHERS 是示例,实际使用时请根据情况修改。
  5. OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS};
  6. // 设置音频并发模式并激活音频会话。
  7. OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy);

启用混音播放下静音建议通知

从API version 23开始,当本应用在并发模式为CONCURRENCY_MIX_WITH_OTHERS下进行播放时,如果有其他应用的音频同时播放,此时两者会混合播放。部分场景下(如游戏或广播),应用可以通过启用静音建议通知,以给用户提供更好的体验。

启用静音建议通知后,本应用播放音频的同时,其他应用播放了不可与本应用并发播放的音频,本应用会收到静音建议通知,此时本应用可以选择不做处理,让本应用和其他应用进行并发播放;也可以选择将自身静音播放,让其他应用单独播放音频。

启用混音播放下静音建议通知,需要先调用接口OH_AudioSessionManager_SetScene设置场景参数,并调用OH_AudioSessionManager_EnableMuteSuggestionWhenMixWithOthers开启功能,同时订阅音频会话状态更改事件OH_AudioSession_StateChangeHint,最后调用OH_AudioSessionManager_ActivateAudioSession接口激活AudioSession。启用静音建议通知的前提是OH_AudioSession_ConcurrencyMode模式必须为CONCURRENCY_MIX_WITH_OTHERS。

收起
自动换行
深色代码主题
复制
  1. // AUDIO_SESSION_SCENE_MEDIA 仅为示例,实际使用时请根据具体情况进行修改。
  2. OH_AudioSessionManager_SetScene(audioSessionManager, AUDIO_SESSION_SCENE_MEDIA);
  3. // 启用混音播放下静音建议。
  4. OH_AudioSessionManager_EnableMuteSuggestionWhenMixWithOthers(audioSessionManager, true);
  5. // ...
  6. OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS};
  7. // 设置音频并发模式并激活音频会话。
  8. OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy);

监听AudioSession焦点状态变化事件

通过AudioSession焦点状态事件(OH_AudioSession_StateChangedEvent)监听音频会话焦点状态的变化。

AudioSession申请焦点以及监听焦点变化事件的完整示例:

收起
自动换行
深色代码主题
复制
  1. OH_AudioSessionManager *audioSessionManager;
  2. void AudioSessionStateChangedCallback(OH_AudioSession_StateChangedEvent event)
  3. {
  4. switch (event.stateChangeHint) {
  5. case AUDIO_SESSION_STATE_CHANGE_HINT_PAUSE:
  6. // 此分支表示系统已将音频流暂停(临时失去焦点),为保持状态一致,应用需切换至音频暂停状态。
  7. // 临时失去焦点:其他音频流释放音频焦点后,本音频流会收到resume事件,可继续播放。
  8. break;
  9. case AUDIO_SESSION_STATE_CHANGE_HINT_RESUME:
  10. // 此分支表示系统解除对AudioSession焦点的暂停操作。
  11. break;
  12. case AUDIO_SESSION_STATE_CHANGE_HINT_STOP:
  13. // 此分支表示系统已将音频流停止(永久失去焦点),为保持状态一致,应用需切换至音频暂停状态。
  14. // 永久失去焦点:后续不会再收到任何音频焦点事件,若想恢复播放,需要用户主动触发。
  15. break;
  16. case AUDIO_SESSION_STATE_CHANGE_HINT_TIME_OUT_STOP:
  17. // 此分支表示由于长时间没有音频流播放,为防止系统资源被长时间无效占用,系统已将AudioSession停止(永久失去焦点),
  18. // 为保持状态一致,应用需切换至音频暂停状态。
  19. // 永久失去焦点:后续不会再收到任何音频焦点事件,若想恢复播放,需要用户主动触发。
  20. break;
  21. case AUDIO_SESSION_STATE_CHANGE_HINT_DUCK:
  22. // 此分支表示系统已将音频音量降低(默认降到正常音量的20%)。
  23. break;
  24. case AUDIO_SESSION_STATE_CHANGE_HINT_UNDUCK:
  25. // 此分支表示系统已将音频音量恢复正常。
  26. break;
  27. case AUDIO_SESSION_STATE_CHANGE_HINT_MUTE_SUGGESTION:
  28. // 此分支表示其他应用开始播放非混音音频,系统可自行决定是否静音。
  29. break;
  30. case AUDIO_SESSION_STATE_CHANGE_HINT_UNMUTE_SUGGESTION:
  31. // 此分支表示其他应用的非混音音频播放结束,系统可自行决定是否取消静音。
  32. break;
  33. case AUDIO_SESSION_STATE_CHANGE_HINT_MUTE:
  34. // 此分支表示系统已将音频静音。
  35. break;
  36. case AUDIO_SESSION_STATE_CHANGE_HINT_UNMUTE:
  37. // 此分支表示系统已将音频解除静音。
  38. break;
  39. default:
  40. break;
  41. }
  42. }
  43. // ...
  44. OH_AudioCommon_Result result = OH_AudioSessionManager_RegisterStateChangeCallback(audioSessionManager,
  45. AudioSessionStateChangedCallback);
  46. // ...
  47. // AUDIO_SESSION_SCENE_MEDIA 仅为示例,实际使用时请根据具体情况进行修改。
  48. OH_AudioSessionManager_SetScene(audioSessionManager, AUDIO_SESSION_SCENE_MEDIA);
  49. // 启用混音播放下静音建议。
  50. OH_AudioSessionManager_EnableMuteSuggestionWhenMixWithOthers(audioSessionManager, true);
  51. // CONCURRENCY_MIX_WITH_OTHERS 是示例,实际使用时请根据情况修改。
  52. OH_AudioSession_Strategy strategy = {CONCURRENCY_MIX_WITH_OTHERS};
  53. // 设置音频并发模式并激活音频会话。
  54. OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy);
  55. // ...
  56. result = OH_AudioSessionManager_DeactivateAudioSession(audioSessionManager);
  57. // ...
  58. OH_AudioCommon_Result resultUnregister = OH_AudioSessionManager_UnregisterSessionDeactivatedCallback(
  59. audioSessionManager, MyAudioSessionDeactivatedCallback);

设置音频会话行为

从API version 24开始,应用可以通过OH_AudioSessionManager_SetBehavior接口设置音频会话行为参数,在特定场景下获得更优的音频焦点体验。

在用户观看直播的场景中,当其他应用启动音频流(如使用键盘录音转文字)打断直播时,会导致直播的音频和画面暂停,影响用户的观看体验。直播应用可以通过设置OH_AudioSession_BehaviorFlags.MUTE_WHEN_INTERRUPTED会话行为,使直播在被打断时保持静音播放而非暂停,避免画面中断。

如果本应用未使用音频会话管理,也可以针对单条音频流设置独立的音频会话行为。对于播放流,详情请参考OH_AudioRenderer_SetIndependentAudioSessionStrategy。对于录音流,详情请参考OH_AudioCapturer_SetIndependentAudioSessionStrategy。

收起
自动换行
深色代码主题
复制
  1. // AUDIO_SESSION_SCENE_MEDIA 仅为示例,实际使用时请根据具体情况进行修改。
  2. OH_AudioSessionManager_SetScene(audioSessionManager, AUDIO_SESSION_SCENE_MEDIA);
  3. // 本接口应在激活音频会话前调用。
  4. // 若音频会话在激活状态时调用此接口后,必须重新激活音频会话使其生效。
  5. uint32_t behavior = OH_AudioSession_BehaviorFlags::MUTE_WHEN_INTERRUPTED;
  6. OH_AudioSessionManager_SetBehavior(audioSessionManager, behavior);
  7. OH_AudioSession_Strategy strategy = {CONCURRENCY_PAUSE_OTHERS};
  8. // 设置音频并发模式并激活音频会话。
  9. OH_AudioSessionManager_ActivateAudioSession(audioSessionManager, &strategy);