HarmonyOS 鸿蒙Next PC音频控制最佳实践
HarmonyOS 鸿蒙Next PC音频控制最佳实践
1. API 使用指导
系统提供了多样化的API,根据不同的开发语言以及不同的音频使用场景,主要介绍以下三种API:
- AudioRenderer:用于音频输出的ArkTS/JS API,仅支持PCM格式,需要应用持续写入音频数据进行工作。应用可以在输入前添加数据预处理,如设定音频文件的采样率、位宽等。
- OHAudio:用于音频输出的Native API,此API在设计上实现归一,同时支持普通音频通路和低时延通路。仅支持PCM格式,适用于依赖Native层实现音频输出功能的场景。
- AVPlayer:用于音频播放的ArkTS/JS API,集成了流媒体和本地资源解析、媒体资源解封装、音频解码和音频输出功能。可用于直接播放mp3、m4a等格式的音频文件,不支持直接播放PCM格式文件。
参考链接:音频播放开发概述。
2. 音频控制及示例
2.1 选择合适的音频流
音频流类型是定义音频数据播放和录制方式的关键属性。对于音频流,其类型由StreamUsage确定。
下表中列举常用的播放音频流类型,由StreamUsage定义:
音频流使用类型(StreamUsage) | 适用场景 |
---|---|
STREAM_USAGE_MOVIE | 适用于播放短视频、电影、电视剧等各类视频内容。 |
STREAM_USAGE_AUDIOBOOK | 适用于播放有声读物、新闻、播客等。 |
STREAM_USAGE_GAME | 适用于游戏内配乐、配音,游戏类型音频流播放时,后台播放的音乐不会被打断;游戏内语音,建议使用STREAM_USAGE_VOICE_COMMUNICATION。 |
STREAM_USAGE_NAVIGATION | 适用于导航场景的语音播报功能。 |
STREAM_USAGE_VOICE_MESSAGE | 适用于播放语音短消息。 |
STREAM_USAGE_VOICE_COMMUNICATION | 适用于VoIP语音通话。 |
STREAM_USAGE_ALARM | 适用于播放闹铃。 |
STREAM_USAGE_RINGTONE | 适用于VoIP来电响铃等。 |
STREAM_USAGE_NOTIFICATION | 适用于播放通知音、提示音。 |
参考链接:播放音频流类型。
2.1.1 ArkTS侧应用适配, 使用AudioRenderer开发音频播放功能:
可以在调用createAudioRenderer
获取音频渲染器时,传入对应的StreamUsage。
createAudioRenderer
的参数options类型为AudioRendererOptions,包含AudioRendererInfo渲染器信息,使用AudioRendererInfo.usage可指定StreamUsage音频流类型。
2.1.2 C侧应用适配,使用OHAudio开发音频播放功能:
可以在调用OH_AudioStreamBuilder_SetRendererInfo()
接口时,传入对应的OH_AudioStream_Usage指定音频流类型。
2.1.3 ArkTS侧应用,使用AVPlayer开发全量的音频播放功能:
可以通过设置AVPlayer的属性audioRendererInfo来实现。AVPlayer.audioRendererInfo的类型为audio.AudioRendererInfo。使用AudioRendererInfo.usage可指定StreamUsage音频流类型。
2.1.4 C侧应用,使用AVPlayer开发全量的音频播放功能:
可以在调用OH_AVPlayer_SetAudioRendererInfo
接口时,传入对应的OH_AudioStream_Usage指定音频流类型。
参考链接:设置音频流类型。
2.2 音量控制
播放流类型(StreamUsage)决定了音频流所属的音量类型(AudioVolumeType),各类音量类型(如媒体、铃声、闹钟、通话等)拥有独立的音量值,在用户界面上可独立调节,相互之间不会影响。
常见的播放流类型与音量类型的对应关系为:
音频流使用类型(StreamUsage) | 音量类型(AudioVolumeType) |
---|---|
MUSIC、MOVIE、AUDIOBOOK、GAME | 媒体音量(MEDIA) |
RINGTONE、NOTIFICATION | 铃声音量(RINGTONE) |
VOICE_COMMUNICATION | 通话音量(VOICE_CALL) |
ALARM | 闹钟音量(ALARM) |
2.2.1 应用获取音量大小
2.2.1.1 TS侧应用获取当前音频流的音量
获取当前音量值,同步返回音量大小,音量范围[0.0-1.0],默认值为1.0,非系统音量。
import { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
try {
let value: number = audioRenderer.getVolume();
console.info(`Indicate that the volume is obtained ${value}.`);
} catch (err) {
let error = err as BusinessError;
console.error(`Failed to obtain the volume, error ${error}.`);
}
参考API:getVolume。
2.2.1.2 C侧应用获取当前音量
获取当前音频流音量值,其中volume为指向一个获取当前音频流音量值的指针,音量值的范围是[0.0, 1.0]。
OH_AudioStream_Result OH_AudioRenderer_GetVolume(OH_AudioRenderer *renderer, float *volume)
参考API:OH_AudioRenderer_GetVolume()。
2.2.2 应用调整应用音量大小
2.2.2.1 使用AVPlayer设置音频流音量的示例代码如下:
let volume = 1.0; // 指定的音量大小,取值范围为[0.00-1.00],1表示最大音量
avPlayer.setVolume(volume);
2.2.2.2 TS侧应用设置音频流音量的示例代码:
import { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
audioRenderer.setVolume(0.5).then(() => { // 音量范围为[0.0-1.0]。
console.info('Invoke setVolume succeeded.');
}).catch((err: BusinessError) => {
console.error(`Invoke setVolume failed, code is ${err.code}, message is ${err.message}`);
});
参考文档:音频流音量。
2.2.2.3 C侧应用设置音频流音量的示例代码 :
OH_AudioStream_Result OH_AudioRenderer_SetVolume (OH_AudioRenderer *renderer, float volume)
参数:
参数名 | 描述 |
---|---|
renderer | 指向OH_AudioStreamBuilder_GenerateRenderer创建的音频流实例。 |
volume | 设置当前音频流音量,音量值的范围是[0.0, 1.0]。 |
返回:
参考API:[OH_AudioRenderer_SetVolume()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-audiorenderer-h#oh_audiorenderer_setvolume)。
## 2.3 音频焦点策略
系统预设了默认的音频焦点策略,根据音频流的类型及启动的先后顺序,对所有播放和录制音频流进行统一管理。
在启动播放或录制功能前,应用需要先申请音频焦点;而在播放或录制结束后,应适时释放音频焦点。在播放或录制的过程中,可能会因其他音频流的介入而失去焦点,此时,应用需要采取相应措施处理音频焦点变化。
- 在启动播放或录制操作前,应根据音频的具体用途,选择并使用合适的音频流类型,即准确设置StreamUsage或SourceType。
- 在播放或录制的过程中,需监听音频焦点事件,并在接收到音频焦点中断事件(InterruptEvent)时,采取相应的处理措施。
- 若应用程序有意主动管理音频焦点,可使用音频会话(AudioSession)相关的接口进行操作。
参考文档:[音频焦点和音频会话介绍](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/audio-playback-concurrency)。
### 2.3.1 TS侧应用处理音频焦点变化的指导
使用AudioRenderer开发音频播放功能,可以调用on('audioInterrupt')接口,监听音频焦点事件InterruptEvent。
```typescript
audioRenderer.on('audioInterrupt', (interruptEvent: audio.InterruptEvent) => {
switch (interruptEvent.hintType) {
case audio.InterruptHint.INTERRUPT_HINT_PAUSE: // 音频流已被暂停,临时失去焦点,应用更新UX界面状态
break;
case audio.InterruptHint.INTERRUPT_HINT_STOP: // 音频流已被停止,永久失去焦点,若想恢复渲染,需用户主动触发
break;
case audio.InterruptHint.INTERRUPT_HINT_RESUME: // 音频已经恢复,应用更新UX界面状态等
break;
case audio.InterruptHint.INTERRUPT_HINT_DUCK:
break;
case audio.InterruptHint.INTERRUPT_HINT_UNDUCK:
break;
}
})
参考API:on(‘audioInterrupt’)。
2.3.2 C侧应用处理音频焦点变化的指导
使用OHAudio开发音频播放功能(C/C++),可以调用OH_AudioStreamBuilder_SetRendererCallback接口,监听音频焦点事件OH_AudioRenderer_OnInterruptEvent。
int32_t MyOnInterruptEvent(OH_AudioRenderer* renderer, void* userData, OH_AudioInterrupt_ForceType type,OH_AudioInterrupt_Hint hint) {
switch(hint) {
case AUDIOSTREAM_INTERRUPT_HINT_RESUME: // 音频已经恢复,应用更新UX界面状态等
break;
case AUDIOSTREAM_INTERRUPT_HINT_PAUSE: // 音频流已被停止,永久失去焦点,若想恢复渲染,需用户主动触发
break;
case AUDIOSTREAM_INTERRUPT_HINT_STOP: // 音频流已被暂停,临时失去焦点,应用更新UX界面状态
break;
case AUDIOSTREAM_INTERRUPT_HINT_DUCK:
break;
case AUDIOSTREAM_INTERRUPT_HINT_UNDUCK:
break;
}
}
2.4 音频设备变更
系统会根据音频流的类型,指定默认的输出设备,典型的场景如下:
- 音乐(Music)类型音频流的默认输出设备为扬声器。
- 语音通话(VoiceCommunication)类型音频流的默认输入设备为麦克风,默认输出设备为听筒。
- 闹铃(Alarm)类型音频流的默认输出设备为扬声器。若先连接蓝牙耳机,再开始播放Alarm音频,则扬声器和蓝牙耳机会同时播放。
2.4.1 TS侧应用 处理音频设备变更的指导
2.4.1.1 指定默认发声设备
import { BusinessError } from '[@kit](/user/kit).BasicServicesKit';
// 可注明下本接口主要服务于语音消息和语音通话场景,允许在AudioRenderer创建以后的任何时间被调用。
// 未播放时调用,系统会记录应用设置的默认本机内置发声设备,当应用启动播放时从设置的默认本机内置发声设备发声。
// 正在播放时调用,在没有外接设备如蓝牙耳机/有线耳机,系统会立即切换到设置的默认本机内置发声设备发声;否则系统会先记录应用设置的默认本机内置发声设备,等外接设备移除后再切换到设置的默认本机内置发声设备发声。
audioRenderer.setDefaultOutputDevice(audio.DeviceType.SPEAKER).then(() => {
console.info('setDefaultOutputDevice Success!');
}).catch((err: BusinessError) => {
console.error(`setDefaultOutputDevice Fail: ${err}`);
});
参考API:setDefaultOutputDevice。
2.4.1.2 处理音频设备变更
(audioRenderer as audio.AudioRenderer).on('outputDeviceChangeWithInfo',
async (deviceChangeInfo: audio.AudioStreamDeviceChangeInfo) => {
switch (deviceChangeInfo.changeReason) {
case audio.AudioStreamDeviceChangeReason.REASON_OLD_DEVICE_UNAVAILABLE:
// 响应设备不可用事件,如果应用处于播放状态,应暂停播放,更新UX界面。
// await audioRenderer.pause();
break;
case audio.AudioStreamDeviceChangeReason.REASON_NEW_DEVICE_AVAILABLE:
// 应用根据业务情况响应设备可用事件。
break;
case audio.AudioStreamDeviceChangeReason.REASON_OVERRODE:
// 应用根据业务情况响应设备强选事件。
break;
case audio.AudioStreamDeviceChangeReason.REASON_UNKNOWN:
// 应用根据业务情况响应未知原因事件。
break;
}
});
触发场景:普通蓝牙设备(耳机、眼镜、音箱、车机等)连接、支持佩戴检测的蓝牙设备(耳机、眼镜等)佩戴、有线设备(3.5mm耳机、Type-C耳机、USB耳机、USB音箱等)插入、分布式设备上线等。
触发场景:普通蓝牙设备(耳机、眼镜、音箱、车机等)断开、支持佩戴检测的蓝牙耳机双耳摘下、支持佩戴检测的蓝牙眼镜摘下、有线设备(3.5mm耳机、Type-C耳机、USB耳机、音箱等)拔出、分布式设备下线等。
触发场景:用户从界面选择切换音频流输出设备、从外设选择接听蜂窝或VoIP来电。
参考文档:音频流输出设备信息。
2.4.2 C侧应用 处理音频设备变更的指导
2.4.2.1 指定默认发声设备
OH_AudioStream_Result OH_AudioRenderer_SetDefaultOutputDevice(OH_AudioRenderer* renderer, OH_AudioDevice_Type deviceType)
接口仅适用于音频流为语音消息、VoIP语音通话或者VoIP视频通话的场景使用,可选默认发声设备类型为听筒、扬声器和系统默认设备。
在应用启动播放时,若有外接设备如蓝牙耳机/有线耳机接入,系统优先从外接设备发声;否则系统遵循应用设置的默认本机内置发声设备发声。
2.4.2.2 处理音频设备变更
OH_AudioStream_Result OH_AudioStreamBuilder_SetRendererOutputDeviceChangeCallback(OH_AudioStreamBuilder * builder, OH_AudioRenderer_OutputDeviceChangeCallback callback, void * userData)
// 输出音频流设备变更的回调函数
void (*OH_AudioRenderer_OutputDeviceChangeCallback)(OH_AudioRenderer *renderer, void *userData, OH_AudioStream_DeviceChangeReason reason) {
switch (reason) {
case REASON_OLD_DEVICE_UNAVAILABLE: // 旧设备不可用。当报告此原因时,应用程序应考虑暂停音频播放。
break;
case REASON_NEW_DEVICE_AVAILABLE: // 新设备可用。
break;
case REASON_OVERRODE: // 用户或系统强制选择切换。
break;
case REASON_UNKNOWN: //未知原因
break;
}
}
更多关于HarmonyOS 鸿蒙Next PC音频控制最佳实践的实战教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next PC音频控制可通过AudioManager API实现。关键操作包括:
- 获取音频管理器:
audioManager.getAudioManager()
- 控制音量:
audioManager.setVolume(AudioVolumeType.MEDIA, level)
- 静音控制:
audioManager.mute(AudioVolumeType.MEDIA, muteState)
- 监听音频变化:注册
VolumeEvent
监听器
示例代码片段:
let audioManager = audio.getAudioManager()
audioManager.setVolume(audio.AudioVolumeType.MEDIA, 50)
audioManager.mute(audio.AudioVolumeType.MEDIA, false)
注意音频权限声明:
ohos.permission.ACCESS_NOTIFICATION_POLICY
,
更多关于HarmonyOS 鸿蒙Next PC音频控制最佳实践的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
针对HarmonyOS Next PC音频控制的最佳实践,以下是关键要点总结:
- API选择:
- 对于PCM格式音频输出,推荐使用AudioRenderer(ArkTS/JS)或OHAudio(Native API)
- 播放MP3/M4A等压缩格式,使用AVPlayer更高效
- 音频流管理:
- 根据场景选择正确的StreamUsage类型(如STREAM_USAGE_MUSIC用于媒体播放)
- 示例:创建AudioRenderer时指定流类型:
let options = {
rendererInfo: {
usage: audio.StreamUsage.STREAM_USAGE_MUSIC,
// 其他参数...
}
};
audio.createAudioRenderer(options);
- 音量控制:
- 音量类型与流类型自动关联(如MEDIA对应音乐流)
- 设置音量范围0.0-1.0:
audioRenderer.setVolume(0.5).then(() => {
console.info('Volume set successfully');
});
- 焦点管理:
- 必须处理中断事件:
audioRenderer.on('audioInterrupt', (event) => {
if(event.hintType === audio.InterruptHint.INTERRUPT_HINT_PAUSE) {
// 处理暂停逻辑
}
});
- 设备切换:
- 监听设备变更:
audioRenderer.on('outputDeviceChangeWithInfo', (info) => {
if(info.changeReason === audio.AudioStreamDeviceChangeReason.REASON_OLD_DEVICE_UNAVAILABLE) {
// 处理设备断开
}
});
- Native开发:
- 使用OH_AudioRenderer_SetVolume()等C接口实现相同功能
- 设备回调通过OH_AudioStreamBuilder_SetRendererOutputDeviceChangeCallback设置
完整示例可参考官方Demo,关键是要根据音频场景选择合适的流类型,并正确处理中断和设备变更事件以保证用户体验。