HarmonyOS 鸿蒙Next如何解决多个应用播放音频冲突问题?
HarmonyOS 鸿蒙Next如何解决多个应用播放音频冲突问题?
概述
当智能终端上运行多个具备音频播放能力的应用时,会出现多个音频流同时播放的场景。根据并发应用播放音频类型的不同,有时希望多个应用可以同时播放对应的音频(比如玩游戏的同时后台播放音乐,允许音乐和游戏音效混音播放),有时则希望根据其音频类型分先后播放(比如看视频的同时打来视频通话,需要先暂停视频声音,优先播放通话铃声提醒用户来电)。为了解决这个问题,系统采用了音频焦点机制,只有获得音频焦点的音频流可以正常播放,失去音频焦点的音频流则不能播放。音频焦点的获得与失去由系统统一调控,在音频流创建时可以配置对应的音频流类型,系统按照预设的焦点策略为对应的音频流类型进行焦点的申请、持有、释放等动作,并在新的音频流到来时执行相应的音频打断策略。如果开发者想要保证自己应用与其他应用并发时能按用户喜好执行正确的音频播放行为,通常需要做以下两点:
1、创建音频流时配置正确的音频流类型。
2、监听音频打断事件,并执行相应的业务处理。
配置正确的音频流类型
开发者需要在创建音频流时配置正确的音频流类型。如果配置错了类型,可能导致系统的打断策略不会按照开发者预期的进行。比如,一般希望导航类应用在播放导航语音时,暂时地降低后台音乐应用的音量,在语音播放完毕后恢复音乐音量。如果错把导航音频流的音频流类型配置为STREAM_USAGE_MUSIC(音乐)而不是STREAM_USAGE_NAVIGATION(导航),就会在播放导航语音时停止后台音乐的播放,并且使其永远失焦,除非用户重新手动点击播放音乐。
对于纯ArkTS应用的开发,如果使用AudioRender音频渲染器的方案来实现音频播放,那么在创建音频渲染器时就可以根据音频流的使用场景配置对应的音频流类型。参考代码如下:
import { audio } from ‘@kit.AudioKit’;
// 配置音频流的相关参数,比如音频采样率、通道数、采样格式、编码格式等
let audioStreamInfo: audio.AudioStreamInfo = {
samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
channels: audio.AudioChannel.CHANNEL_1,
sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
};
// 配置音频渲染器的相关参数,在此处即可配置音频流类型,这里设置为STREAM_USAGE_VOICE_COMMUNICATION(VoIP语音通话)
let audioRendererInfo: audio.AudioRendererInfo = {
usage: audio.StreamUsage.STREAM_USAGE_VOICE_COMMUNICATION,
rendererFlags: 0
};
let audioRendererOptions: audio.AudioRendererOptions = {
streamInfo: audioStreamInfo,
rendererInfo: audioRendererInfo
};
// 根据预设的配置创建音频渲染器
audio.createAudioRenderer(audioRendererOptions, (err, data) => {
if (err) {
console.error(AudioRenderer Created: <span class="hljs-built_in">Error</span>: ${err}
);
} else {
console.info(‘AudioRenderer Created: Success: SUCCESS’);
let audioRenderer = data;
}
});
使用AudioRenderer开发音频播放功能的具体指南可参考此处。
当前HarmonyOS提供的音频流类型可参考此处,下表给出了不同音频流类型播放冲突时系统的处理方案,开发者可根据自己应用的具体场景选用合适的音频流类型。为方便阅读,去掉了音频流类型的“STREAM_USAGE_”前缀,使用特殊符号表示系统处理策略。
后播音频流 | ||||||||||||||
先 播 音 频 流 | 音频类型 | MUSIC | VOICE_COMMUNICATION | VOICE_ASSISTANT | ALARM | VOICE_MESSAGE | RINGTONE | NOTIFICATION | ACCESSIBILITY | MOVIE | GAME | AUDIOBOOK | NAVIGATION | VIDEO_COMMUNICATION |
MUSIC | ▢ | ‖ | ◑ | ‖ | ‖ | ‖ | ◑ | ◑ | ▢ | ▶ | ▢ | ◑ | ‖ | |
VOICE_COMMUNICATION | ◐ | ‖ | × | ◐ | ◐ | ▶ | ▶ | ◑ | ◐ | ◐ | ◐ | ▶ | ‖ | |
VOICE_ASSISTANT | ◐ | ▢ | ▢ | ◐ | ◐ | ▢ | ▶ | ▶ | ◐ | ▢ | ◐ | ▢ | ▢ | |
ALARM | ▢ | ▢ | ◑ | ▢ | ▢ | ▢ | ▶ | ▶ | ▢ | ▢ | ▢ | ▶ | ▢ | |
VOICE_MESSAGE | ▢ | ▢ | ◑ | ▢ | ▢ | ▢ | ◑ | ▶ | ▢ | ▶ | ▢ | ◐ | ▢ | |
RINGTONE | ◐ | ▢ | × | ▶ | ◐ | ▶ | ▶ | ◑ | ◐ | ◐ | ◐ | ▶ | ▢ | |
NOTIFICATION | ▶ | ▢ | ▢ | ▶ | ▶ | ▶ | ▢ | ▶ | ▶ | ▶ | ▶ | ▶ | ▢ | |
ACCESSIBILITY | ◐ | ◐ | ▶ | ◐ | ▶ | ◑ | ▶ | ▢ | ◐ | ◐ | ◐ | ▶ | ◐ | |
MOVIE | ▢ | ‖ | ◑ | ‖ | ‖ | ‖ | ◑ | ◑ | ▢ | ▶ | ▢ | ◑ | ‖ | |
GAME | ▶ | ‖ | ◑ | ‖ | ‖ | ‖ | ◑ | ◑ | ▶ | ▢ | ▶ | ◑ | ‖ | |
AUDIOBOOK | ▢ | ‖ | ◑ | ‖ | ‖ | ‖ | ◑ | ◑ | ▢ | ▶ | ▢ | ◑ | ‖ | |
NAVIGATION | ◐ | ▢ | ▢ | ▶ | ◑ | ▶ | ▶ | ▶ | ◐ | ◐ | ◐ | ▢ | ▢ | |
VIDEO_COMMUNICATION | ◐ | ‖ | × | ◐ | ◐ | ▶ | ▶ | ◑ | ◐ | ◐ | ◐ | ▶ | ‖ |
*系统处理策略解释:
◑:降低先播音频流音量,被降低音量的音频流在另一个音频流播放完毕后会恢复正常音量,开发者无需处理。
◐:降低后播音频流音量,被降低音量的音频流在另一个音频流播放完毕后会恢复正常音量,开发者无需处理。
▶:同时播放。
‖:暂停先播音频流,先播音频流被暂停后,待后播音频流播放完毕,系统会发送中断事件,如果想要恢复被暂停的音频流,需要在应用中监听对应的音频中断事件并恢复播放,具体可参考下文。
▢:停止先播音频流,被停止的音频流无法主动恢复,除非用户手动操作起播。
×:拒绝后播音频流。
如果选用AVPlayer开发音视频播放的功能,需要注意如果媒体源包含视频,则音频流类型默认为STREAM_USAGE_MOVIE,否则默认为STREAM_USAGE_MUSIC。如果音频流不满足需求,同样需要主动配置audio.AudioRendererInfo中的usage值,且只允许在initialized状态下设置。使用AVPlayer开发音视频播放功能可参考指南Media Kit(媒体服务)。
如果开发Native侧的音频播放功能,可以使用OHAudio接口来设置音频流类型,其类型分类可参考此处,系统对于音频流播放冲突的处理方案同上表。
监听音频打断事件
除了配置正确的音频流类型,开发者往往还需要在代码中监听音频打断事件。这一步不是必选的,比如瞬时的按键音、提示音等等,一般只需配置正确的音频流类型即可。但对于音视频类应用,一旦被打断播放,通常需要在页面状态上有所展示,如播放按钮切换为暂停按钮、显示相应的提示消息等,另外正如上文提到的,系统只负责音频的打断,对于音频流恢复播放,如被暂停播放的后台音乐应用,需要应用自行监听系统传递的打断事件,在合适的时机恢复播放。
根据系统对于音频流播放冲突的处理方案,应用的音频流播放场景可以概括为四类:
1、暂停后恢复播放
应用的先播音频流被后播音频流打断,进入暂停状态。此时需要根据音频流类型决定是否监听打断事件INTERRUPT_HINT_PAUSE,并更新UI状态等。待后播音频流播放完毕,应用需要监听INTERRUPT_HINT_RESUME事件,并主动调用播放方法来恢复音频流播放,更新UI状态等。
2、降低音量后恢复音量
被降低音量的音频流所在的应用会接收到INTERRUPT_HINT_DUCK事件,恢复音量时会接收到INTERRUPT_HINT_UNDUCK事件,应用根据自身需要决定是否监听事件并进行业务处理等。
3、停止后不恢复播放
音频流被停止后无法主动恢复,在接收到INTERRUPT_HINT_STOP事件时处理相应业务逻辑。
4、并发播放
不同音频流会同时播放,无需做处理。
以音乐应用为例,通常需要做如下处理:
// 监听音频打断事件
private setInterruptCallback() {
if (!this.audioRenderer) {
return;
}
this.audioRenderer.on(‘audioInterrupt’, this.interruptCallback);
}
// 在回调中处理各类打断事件
private interruptCallback: (interruptEvent: audio.InterruptEvent) => void =
(interruptEvent: audio.InterruptEvent) => {
if (interruptEvent.forceType === audio.InterruptForceType.INTERRUPT_FORCE) {
switch (interruptEvent.hintType) {
case audio.InterruptHint.INTERRUPT_HINT_PAUSE:
// 系统将音频流暂停,为保持状态一致,应用需切换至音频暂停状态
// 处理相应业务逻辑
break;
case audio.InterruptHint.INTERRUPT_HINT_STOP:
// 系统将音频流停止,为保持状态一致,应用需切换至音频暂停状态
// 处理相应业务逻辑
break;
case audio.InterruptHint.INTERRUPT_HINT_DUCK:
// 系统将音频流音量降低(默认降到正常音量的20%)
// 处理相应业务逻辑
break;
case audio.InterruptHint.INTERRUPT_HINT_UNDUCK:
// 系统将音频流音量恢复
// 处理相应业务逻辑
break;
default:
break;
}
} else if (interruptEvent.forceType === audio.InterruptForceType.INTERRUPT_SHARE) {
switch (interruptEvent.hintType) {
case audio.InterruptHint.INTERRUPT_HINT_RESUME:
// 被暂停的音频流此时可以继续播放,建议应用继续播放,切换至音频播放状态
// 若应用此时不想继续播放,可以忽略此音频打断事件,不进行处理即可
// 处理相应业务逻辑
break;
default:
break;
}
}
}
*特殊场景:如果需要音乐后台播放的同时,前台音视频应用能静音播放,需要前台应用开启静音并发模式,否则会按照系统默认的处理方案中断前台应用的播放。具体实现可参考音频播放类应用交互场景实践。
如果开发Native侧的音频播放功能,相应的业务处理可以参考处理音频焦点事件。
总结
为了保证多应用并发时音频流的播放行为符合用户一般认知,开发者需根据音频流的播放场景配置正确的音频流类型,并根据需要决定是否监听音频中断事件。基于当前的HarmonyOS音频冲突解决方案,开发者可参考下表,配置一些应用的典型音频流类型和监听事件,也可根据实际的需求,决定应用的音频流类型等。
音频流类型 | 典型音频流 |
STREAM_USAGE_MUSIC | 音乐 |
STREAM_USAGE_VOICE_COMMUNICATION | VoIP语音通话 |
STREAM_USAGE_VOICE_ASSISTANT | 语音播报 |
STREAM_USAGE_ALARM | 闹钟 |
STREAM_USAGE_VOICE_MESSAGE | 语音消息(即时通讯软件、论坛等) |
STREAM_USAGE_RINGTONE | 铃声 |
STREAM_USAGE_NOTIFICATION | 应用通知 |
STREAM_USAGE_ACCESSIBILITY | 无障碍(听障辅助等) |
STREAM_USAGE_MOVIE | 视频(短视频,影视剧等) |
STREAM_USAGE_GAME | 游戏 |
STREAM_USAGE_AUDIOBOOK | 有声读物(听书、相声、评书等)、听新闻、播客 |
STREAM_USAGE_NAVIGATION | 地图导航 |
STREAM_USAGE_VIDEO_COMMUNICATION | VoIP视频通话 |
检测应用音频冲突适配完整性
这里提供了一个音频检测应用,开发者可以用来检测自己开发的音频应用在不同场景下的功能完备度和准确性等,帮助开发者修复音频焦点类的应用功能问题。
针对HarmonyOS鸿蒙Next系统中多个应用播放音频冲突的问题,可通过以下方式解决:
HarmonyOS系统预设了音频打断策略,以管控多音频播放的并发情况。该策略规定,只有持有音频焦点的音频流才可以正常播放,避免多个音频流无序并发播放。当应用开始播放音频时,系统会为相应的音频流申请音频焦点,获得焦点的音频流可以播放,若焦点申请被拒绝,则不能播放。
此外,为满足应用对多音频并发策略的不同需求,音频打断策略预设了两种焦点模式:
- 共享焦点模式(SHARE_MODE):由同一应用创建的多个音频流共享一个音频焦点,这些音频流之间的并发规则由应用自主决定。
- 独立焦点模式(INDEPENDENT_MODE):应用创建的每一个音频流均独立拥有一个音频焦点,当多个音频流并发播放时,会触发音频打断策略的管控。
应用可以按需选择合适的焦点模式,在创建音频流时,系统默认采用共享焦点模式,应用也可主动设置所需的模式。
如果问题依旧没法解决请联系官网客服,官网地址是: https://www.itying.com/category-93-b0.html 。