在元服务中可以采用AVPlayer实现低延迟、可重播的短音频功能。
该解决方案的核心策略如下:
完整代码如下:
src/main/ets/pages/Index.ets:
import common from '@ohos.app.ability.common'; import { SoundManager } from './SoundManager'; @Entry @Component struct Index { private soundManager: SoundManager = new SoundManager(); private context = this.getUIContext().getHostContext() as common.UIAbilityContext; // 定义要播放的文件名 private targetFileName: string = 'sample.mp3'; // 显示正在播放的音效文件 @State displayFileName: string = ''; aboutToAppear() { // 初始化音频 this.soundManager.init(this.context, this.targetFileName); // 初始化显示文案 this.displayFileName = `正在播放 ${this.targetFileName}`; } aboutToDisappear() { this.soundManager.release(); } build() { Column() { Text(this.displayFileName) .fontSize(12) .fontColor(Color.Gray) .margin({ bottom: 10 }) Button('播放音效') .width(200) .height(50) .onClick(() => { this.soundManager.play(); }) } .width('100%') .height('100%') .justifyContent(FlexAlign.Center) } }
其中sample.mp3文件放置在src/main/resources/rawfile文件夹中,请按需替换为其他音频文件。
src/main/ets/pages/SoundManager.ets:
import media from '@ohos.multimedia.media'; import common from '@ohos.app.ability.common'; import { BusinessError } from '@ohos.base'; export class SoundManager { private avPlayer: media.AVPlayer | undefined = undefined; private isPrepared: boolean = false; async init(context: common.UIAbilityContext, rawFileName: string) { try { this.avPlayer = await media.createAVPlayer(); this.avPlayer.on('stateChange', (state: media.AVPlayerState) => { switch (state) { case 'initialized': this.avPlayer?.prepare(); break; case 'prepared': this.isPrepared = true; console.info('AVPlayer: Prepared.'); break; case 'completed': console.info('AVPlayer: Play completed.'); // 不要在这里 stop 或 reset,保持 prepared/completed 状态 // 这样下次点击 play 才能直接播放 break; case 'error': console.error('AVPlayer: Error state.'); break; } }); let fileDescriptor = await context.resourceManager.getRawFd(rawFileName); this.avPlayer.fdSrc = { fd: fileDescriptor.fd, offset: fileDescriptor.offset, length: fileDescriptor.length }; } catch (error) { console.error(`SoundManager Init Failed: ${(error as BusinessError).message}`); } } play() { if (!this.avPlayer || !this.isPrepared) { return; } // 支持打断播放和重复播放 // 如果正在播放(playing) 或者 已经放完(completed),都把进度拉回 0 if (this.avPlayer.state === 'playing' || this.avPlayer.state === 'completed') { this.avPlayer.seek(0); // 瞬间回到开头 } // 只要不是 error 或 released,调用 play 都是安全的 if (this.avPlayer.state !== 'playing') { this.avPlayer.play(); } } release() { if (this.avPlayer) { this.avPlayer.release(); this.avPlayer = undefined; this.isPrepared = false; } } }