HarmonyOS鸿蒙Next中解码base64音频数据,播放音频报错5400102
HarmonyOS鸿蒙Next中解码base64音频数据,播放音频报错5400102 【问题描述】:解码base64音频数据,播放音频报错5400102
【问题现象】:
解码代码:
this.audioFilePath = context.tempDir + '/test.mp3';
let result = new util.Base64Helper().decodeSync(this.base64Str);
const file = fs.openSync(this.audioFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
const writeLen = fs.writeSync(file.fd, result.buffer);
this.url = 'fd://' + file.fd
fs.closeSync(file);
console.info(`Base64解码写入成功,字节数:${writeLen}`);
在播放按钮的点击事件只执行了
this.avPlayer.url = this.url
avplayer的对象创建和监听stateChange用的是官方文档里的案例,应该是没有问题的,但是点击播放按钮就会报错
【版本信息】:api20
【复现代码】:同上
【尝试解决方案】:无
更多关于HarmonyOS鸿蒙Next中解码base64音频数据,播放音频报错5400102的实战教程也可以访问 https://www.itying.com/category-93-b0.html
可以参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-file-fs#fsclosesync

因此,需要先打开file对象,fd拼接出的路径才有效,示例代码:
let fdPath = ‘fd://’;
let file = fs.openSync(this.audioFilePath);
fdPath = fdPath + ‘’ + file.fd;
this.avPlayer.url = fdPath
这样就可以播放了,然后在监听事件中及时执行fs.closesync来关闭file对象防止内存泄漏
更多关于HarmonyOS鸿蒙Next中解码base64音频数据,播放音频报错5400102的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
错误码5400102通常表示AVPlayer在设置播放源(URL)时遇到了问题,具体是AV_ERROR_IO_INVALID,即无效的输入/输出。根据你提供的代码,问题很可能出在文件描述符(fd)的处理上。
核心问题在于:你在将文件描述符(file.fd)拼接成'fd://' + file.fd格式的URL后,立即关闭了文件(fs.closeSync(file))。这导致当AVPlayer尝试通过这个文件描述符访问音频文件时,该描述符已经失效,从而引发IO错误。
解决方案:
不要过早关闭文件。文件描述符需要在AVPlayer的整个播放生命周期内保持有效。正确的做法是在确定不再需要播放该文件时(例如,在AVPlayer的stateChange监听器中收到STATE_IDLE或STATE_STOPPED状态,并准备释放资源时),再关闭文件描述符。
修改后的代码逻辑建议:
-
解码和写入文件部分保持不变,但不要立即关闭文件:
this.audioFilePath = context.tempDir + '/test.mp3'; let result = new util.Base64Helper().decodeSync(this.base64Str); const file = fs.openSync(this.audioFilePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); const writeLen = fs.writeSync(file.fd, result.buffer); // 关键:此处不要调用 fs.closeSync(file); this.url = 'fd://' + file.fd; this.audioFile = file; // 将file对象保存到成员变量中,以便后续关闭 console.info(`Base64解码写入成功,字节数:${writeLen}`); -
在适当的时机关闭文件: 例如,在AVPlayer的
stateChange监听器中,当播放结束或播放器被释放时。// 假设在avPlayer的stateChange回调中 avPlayer.on('stateChange', (state, reason) => { if (state === avPlayer.AVState.STOPPED || state === avPlayer.AVState.IDLE) { // 当播放停止或闲置时,关闭之前打开的文件 if (this.audioFile) { fs.closeSync(this.audioFile); this.audioFile = undefined; console.info('音频文件已关闭'); } } });或者,在你的业务逻辑中明确知道不再需要播放该音频时(例如,组件销毁或切换音频源前),手动调用关闭。
其他注意事项:
- 文件路径有效性: 确保
context.tempDir是有效的应用临时目录路径。 - Base64数据格式: 确认
this.base64Str是标准的、无换行符等杂质的Base64编码字符串,且解码后的二进制数据是有效的MP3格式。 - 权限: 确保应用已申请必要的文件读写权限(
ohos.permission.READ_MEDIA和ohos.permission.WRITE_MEDIA)。
通过延迟文件描述符的关闭时机,应该能解决5400102报错问题。


