HarmonyOS NEXT 6.1(API 23)对音频套件 Audio Kit 进行了多项实用升级,其中 ArkTS 层可以直接调用的三个新特性——音量变化事件新增 previousVolume 字段、系统音效播放器 SystemSoundPlayer、以及音频渲染器的路由预估时延 getLatency,为音量感知、系统音效管理和音视频同步提供了更精确的控制能力。本文通过一个完整的控制台示例,演示这三个特性的集成方法与关键细节。
项目结构与环境
示例工程 AudioKitDemo 基于 Stage 模型构建,主页面 AudioKitDemo.ets 集中实现了三大交互模块:音量变化监听舱、路由时延诊断舱和系统音效播放舱。工程需要 DevEco Studio 搭配 HarmonyOS SDK API 23,语言使用 ArkTS。项目路由表 main_pages.json 注册了两个页面入口。
核心模块对应三个独立 @Builder 子卡片,数据流通过组件的 @State 变量和私有方法串联。
实战一:音量变化感知(previousVolume)
此前应用监听音量变化只能获得当前音量值,若要知道变化方向和幅度,必须在外部维护上一次音量值。API 23 的 StreamVolumeEvent 新增了可选字段 previousVolume,在回调中直接携带变化前的音量。
注册监听的典型代码如下:- import { audio } from '@kit.AudioKit';
- const volMgr: audio.AudioVolumeManager = audio.getAudioManager().getVolumeManager();
- volMgr.on('streamVolumeChange', audio.StreamUsage.STREAM_USAGE_MUSIC,
- (event: audio.StreamVolumeEvent) => {
- const prevVol = event.previousVolume ?? -1;
- const currVol = event.volume;
- const direction = (currVol > (event.previousVolume ?? currVol)) ? '⬆️' : '⬇️';
- console.info(`音量变化 ${direction} 旧=${prevVol} 新=${currVol}`);
- }
- );
复制代码
要点:previousVolume 可能为 undefined(例如快速设置静音时),建议用空值合并运算符提供默认值。回调参数 updateUi 标记系统是否已显示音量 UI,应用可根据此字段决定是否自行弹窗。
在控制台页面中,我们将上一音量和当前音量分别以紫色和绿色大字显示,并自动附加方向箭头,让开发者直观体验新字段的效果。
实战二:系统音效播放器(SystemSoundPlayer)
系统音效播放器是 API 23 全新引入的能力,专门用于管理拍照快门、录制开始/结束等系统提示音。它提供了完整的生命周期:预加载→播放→卸载→释放,开发者必须在调用 play() 之前调用 load(),使用完毕后依次调用 unload() 和 release() 才能正确释放资源。
创建播放器并播放快门音效的示例:- import { systemSoundManager } from '@kit.AudioKit';
- let soundPlayer: systemSoundManager.SystemSoundPlayer | null = null;
- try {
- soundPlayer = await systemSoundManager.createSystemSoundPlayer();
- if (!soundPlayer) {
- console.error('createSystemSoundPlayer 返回 null');
- return;
- }
- // 预加载
- await soundPlayer.load(systemSoundManager.SystemSoundType.PHOTO_SHUTTER);
- // 播放
- await soundPlayer.play(systemSoundManager.SystemSoundType.PHOTO_SHUTTER);
- console.info('快门音效播放成功');
- // 卸载并释放
- await soundPlayer.unload(systemSoundManager.SystemSoundType.PHOTO_SHUTTER);
- await soundPlayer.release();
- soundPlayer = null;
- } catch (err) {
- console.error(`系统音效异常: ${err.code} - ${err.message}`);
- }
复制代码
需要注意:SystemSoundType 目前包含 PHOTO_SHUTTER、RECORD_START、RECORD_STOP 三种类型。load() 和 play() 都是异步操作,建议在初始化页面时预加载,避免用户点击时出现首次加载延迟。如果连续播放同一音效,只需加载一次,但每次播放前确保未卸载。release() 必须最后调用,否则后续无法再使用该实例。
实战三:路由预估时延(getLatency)
音视频精确同步需要知道音频渲染链路的延迟。AudioRenderer 新增的 getLatency 方法可同步返回全链路、纯软件层和纯硬件层的预估时延(毫秒级)。
使用时需注意:仅 Stage 模型可用;必须先调用 start() 后查询;无线设备返回值误差较大;建议只在播放开始时查询一次,避免高频轮询。
集成示例:- import { audio } from '@kit.AudioKit';
- async function queryLatency() {
- const opt: audio.AudioRendererOptions = {
- streamInfo: {
- samplingRate: audio.AudioSamplingRate.SAMPLE_RATE_44100,
- channels: audio.AudioChannel.CHANNEL_2,
- sampleFormat: audio.AudioSampleFormat.SAMPLE_FORMAT_S16LE,
- encodingType: audio.AudioEncodingType.ENCODING_TYPE_RAW
- },
- rendererInfo: {
- usage: audio.StreamUsage.STREAM_USAGE_MUSIC,
- rendererFlags: 0
- }
- };
- const renderer = await audio.createAudioRenderer(opt);
- await renderer.start();
- try {
- const latencyAll = renderer.getLatency(audio.AudioLatencyType.LATENCY_TYPE_ALL);
- const latencySW = renderer.getLatency(audio.AudioLatencyType.LATENCY_TYPE_SOFTWARE);
- const latencyHW = renderer.getLatency(audio.AudioLatencyType.LATENCY_TYPE_HARDWARE);
- console.info(`全链路:${latencyAll}ms 软件:${latencySW}ms 硬件:${latencyHW}ms`);
- } catch (err) {
- console.error(`getLatency 失败: ${err.code} - ${err.message}`);
- }
- }
复制代码
若未调用 start() 直接查询,会抛出 6800103 错误。此外,精确的 A/V 同步还应配合 getAudioTimestampInfo() 或 getAudioTimestampInfoSync() 接口使用。
总结
本文演示了 HarmonyOS NEXT 6.1 Audio Kit 在 ArkTS 层的三个实用新特性。previousVolume 减少了音量状态管理的复杂度;SystemSoundPlayer 规范了系统音效的生命周期;getLatency 为音视频同步调优提供了数据底座。同时还提及了 NDK 层新增的变声效果 C API,供有 Native 编创需求的开发者参考。这些能力均可直接集成到现有应用中,提升音频特性的精准度和开发效率。 |