关于HarmonyOS 鸿蒙Next SoundPool播放音频的问题
关于HarmonyOS 鸿蒙Next SoundPool播放音频的问题
项目需要使用SoundPool播放音频。音频文件放在工程下的rawFile下,请问如何转化为参数uri
3 回复
以下是SoundPool实现音频播放功能的参考demo,看能否解决你的问题:
调用createSoundPool方法创建SoundPool实例。
import media from '@ohos.multimedia.media';
import audio from '@ohos.multimedia.audio';
import { BusinessError } from '@ohos.base';
let soundPool: media.SoundPool;
let audioRendererInfo: audio.AudioRendererInfo = {
usage : audio.StreamUsage.STREAM_USAGE_MUSIC,
rendererFlags : 0
}
media.createSoundPool(5, audioRendererInfo).then((soundpool_: media.SoundPool) => {
if (soundpool_ != null) {
soundPool = soundpool_;
console.info('create SoundPool success');
} else {
console.error('create SoundPool fail');
}
}).catch((error: BusinessError) => {
console.error(`soundpool catchCallback, error message:${error.message}`);
});
注册监听(资源加载完成,播放完成,错误类型监听)
soundPool.on('loadComplete', (soundId: number) => {
console.info('loadComplete, soundId: ' + soundId);
});
soundPool.on('playFinished', () => {
console.info("receive play finished message");
});
soundPool.on('error', (error) => {
console.info('error happened,message is :' + error.message);
});
调用load方法进行音频资源加载。
可以传入uri或fd加载资源,此处使用传入uri的方式为例,更多方法请参考API文档。
const audioViewPicker = new picker.AudioViewPicker();
audioViewPicker.select(audioSelectOptions).then(async (audioSelectResult: Array<string>) => {
urii = audioSelectResult[0];
console.info('audioViewPicker.select to file succeed and uri is:' + urii);
if(urii){
await fs.open(urii, fs.OpenMode.READ_ONLY).then((file_: fs.File) => {
let file=file_;
console.info("file fd: " + file.fd);
uri = 'fd://' + (file.fd).toString()
}); // '/test_01.mp3' 作为样例,使用时需要传入文件对应路径。
soundPool.load(uri).then((soundIdd: number) => {
console.info('soundPool load uri success');
soundId=soundIdd;
}).catch((err: BusinessError) => {
console.error('soundPool load failed and catch error is ' + err.message);
})
}
}).catch((err: BusinessError) => {
console.error(`Invoke audioViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
配置播放参数PlayParameters,并调用play方法播放音频。多次调用play播放同一个soundID,只会播放一次。
let PlayParameters: media.PlayParameters = {
loop: 3, // 循环4次
rate: audio.AudioRendererRate.RENDER_RATE_NORMAL, // 正常倍速
leftVolume: 0.9, // range = 0.0-1.0
rightVolume: 0.9, // range = 0.0-1.0
priority: 3, // 最低优先级
}
// 开始播放,这边play也可带播放播放的参数PlayParameters
streamId = await soundPool.play(soundId,PlayParameters);
释放资源
async function release() {
// 终止指定流的播放
soundPool.stop(streamId);
// 卸载音频资源
await soundPool.unload(soundId);
//关闭监听
setOffCallback();
// 释放SoundPool
await soundPool.release();
}
//关闭监听
function setOffCallback() {
soundPool.off('loadComplete');
soundPool.off('playFinished');
soundPool.off('error');
}
可以使用这个方法加载音频资源:
load(fd: number, offset: number, length: number): Promise<number>;
代码如下:
try {
let file = getContext().resourceManager.getRawFdSync("rawFile下文件的名字")
await this.soundPool.load(file.fd, file.offset, file.length)
} catch (e) {
debugger
}