HarmonyOS鸿蒙Next中AudioCapturer录制的音频使用AVPlayer播放,报类型不支持错误怎么解决

HarmonyOS鸿蒙Next中AudioCapturer录制的音频使用AVPlayer播放,报类型不支持错误怎么解决

【问题现象】

通过AudioCapturer录制音频,并将音频存储在wav格式的文件中。将wav格式文件通过base64编码后发送给服务端,服务端拿到base64编码后的文件作语音识别并播放。服务端使用AVPlayer播放时,发生报错,错误信息为"BusinessError: Unsupport Format: unsupport interface@5056652b"。

点击放大

【背景知识】

  • 音频录制开发概述:系统提供了多样化的API,来帮助开发者完成音频录制的开发,不同的API适用于不同录音输出格式、音频使用场景或不同开发语言。

    • AudioCapturer:音频输入的ArkTS/JS API,仅支持PCM格式,需要应用持续读取音频数据进行工作。
    • OpenSL ES:Native API,同样提供音频输入原子能力,仅支持PCM格式,适用于从其他嵌入式平台移植,或依赖在Native层实现音频输入功能的录音应用使用。
    • OHAudio:音频输入的Native API,支持普通音频通路和低时延通路。仅支持PCM格式,适用于依赖Native层实现音频输入功能的场景。
    • AVRecorder:音频录制的ArkTS/JS API,集成了音频输入录制、音频编码和媒体封装的功能。开发者可以直接调用设备硬件如麦克风录音,并生成m4a音频文件。
  • AVPlayer:将Audio/Video媒体资源(比如mp4/mp3/mkv/mpeg-ts等)转码为可供渲染的图像和可听见的音频模拟信号,并通过输出设备进行播放。

【定位思路】

  • 确认pcm格式转wav格式是否正确。wav文件(PCM数据)分为三个部分,RIFF块描述、fmt块以及data块。如果需要把pcm码流保存成wav格式需要添加所对应的文件头(RIFF块和fmt块)。

点击放大

  • 确认base64编解码是否正确。

【解决方案】

  • pcm格式转wav格式分两个步骤:先构造wav格式的文件头,再将pcm数据写入到wav文件中。
    • wav格式的文件头构造:
// 写入wav文件头函数
private writeWaveFileHeader(
   out: fs.File,
   audioDataSize: number,
   totalDataLen: number,
   byteRate: number
) {
   const header = new ArrayBuffer(44);
   const dv = new DataView(header);
   const bitsPerSample = 16; // 当前位深是16

   // 写入RIFF块
   this.writeString(dv, 0, 'RIFF');
   dv.setUint32(4, totalDataLen, true);
   this.writeString(dv, 8, 'WAVE');

   // 写入fmt块
   this.writeString(dv, 12, 'fmt ');
   dv.setUint32(16, 16, true); // fmt块大小
   dv.setUint16(20, 1, true); // 格式类别 (PCM)
   dv.setUint16(22, this.mChannel, true); // 通道数
   dv.setUint32(24, this.mSampleRate, true); // 采样率
   dv.setUint32(28, byteRate, true); // ByteRate 码率
   dv.setUint16(32, this.mChannel * bitsPerSample / 8, true); // BlockAlign
   dv.setUint16(34, bitsPerSample, true); // 位深

   // 写入data块
   this.writeString(dv, 36, 'data');
   dv.setUint32(40, audioDataSize, true); // 数据块大小
   fs.writeSync(out.fd, new Uint8Array(header).buffer, {
   length: 44
   })
}
  • pcm数据写入到wav文件中:
private writePcmData(inFile: fs.File, outFile: fs.File, audioDataSize: number) {
   // 写入 pcm 数据
   let readSize = 0
   let data = new ArrayBuffer(audioDataSize);
   let readOptions: ReadOptions = {
     offset: readSize,
     length: audioDataSize
   };
   let readLen = fs.readSync(inFile.fd, data, readOptions);
   while (readLen > 0) {
     readSize += readLen;
     fs.writeSync(outFile.fd, data, { length: readLen});
     readOptions.offset = readSize;
     readLen = fs.readSync(inFile.fd, data, readOptions);
   }
   fs.closeSync(inFile.fd)
   fs.closeSync(outFile.fd)
}
  • 音频文件使用base64编码参考:
let file = await fileIo.open(this.selectedUri, fileIo.OpenMode.READ_ONLY);
let fileSize = fileIo.statSync(f.fd).size;
console.info('file Size: ' + fileSize);
let buffer = new ArrayBuffer(fileSize);
fileIo.readSync(f.fd, buffer);
fileIo.closeSync(f);
// Base64Helper的构造函数
let base64 = new util.Base64Helper();
// 通过输入参数编码后输出Uint8Array对象
let unit8data = base64.encodeSync(new Uint8Array(buffer.slice(0, buffer.byteLength)))
// 将字节数组解码为字符串,格式为utf-8
let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true })
let retStr = textDecoder.decodeWithStream( unit8data , {stream: false});

【总结】

  1. AudioCapturer录制的音频格式为pcm格式,如果需要直接播放pcm音频文件,可以考虑使用AudioRenderer播放音频。

  2. 如果需要使用AVPlayer播放音频AudioCapturer录制的音频,必须将pcm格式音频文件转为AVPlayer播放器支持的文件格式。在进行格式转换时需要比较格式之间的差异(比如文件头差异),防止在格式转换时引入未知的错误。


更多关于HarmonyOS鸿蒙Next中AudioCapturer录制的音频使用AVPlayer播放,报类型不支持错误怎么解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中AudioCapturer录制的音频使用AVPlayer播放,报类型不支持错误怎么解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用AudioCapturer录制的音频通过AVPlayer播放时,报类型不支持错误

在HarmonyOS鸿蒙Next中,使用AudioCapturer录制的音频通过AVPlayer播放时,报类型不支持错误,通常是由于音频格式或编码方式与AVPlayer支持的类型不匹配。AVPlayer支持的音频格式有限,可能无法直接播放AudioCapturer录制的原始PCM数据。可以通过以下步骤解决:

  1. 确认音频格式:检查AudioCapturer录制的音频格式,确保其为AVPlayer支持的格式,如AAC、MP3等。如果录制的是PCM数据,需先进行编码转换。

  2. 音频编码转换:如果录制的是PCM数据,使用鸿蒙的音频编码接口(如AudioEncoder)将其转换为AVPlayer支持的格式,如AAC或MP3。

  3. 设置AVPlayer的源:确保转换后的音频文件路径或数据流正确设置给AVPlayer。

  4. 检查权限:确认应用已获取必要的音频录制和播放权限。

  5. 日志分析:通过日志进一步分析错误信息,确认具体不支持的格式或编码。

通过这些步骤,可以解决AVPlayer播放AudioCapturer录制音频时的类型不支持错误。

回到顶部