HarmonyOS 鸿蒙Next中AVRecorder录制的wav文件为G711mu编码,如何将的G711mu编码的wav音频文件转换成PCM编码的wav音频文件

HarmonyOS 鸿蒙Next中AVRecorder录制的wav文件为G711mu编码,如何将的G711mu编码的wav音频文件转换成PCM编码的wav音频文件 AVRecorder录制的wav音频如下设置:

let avProfile: media.AVRecorderProfile = {
  audioBitrate: 64000, // set audioBitrate according to device ability.
  audioChannels: 1, // set audioChannels,valid value 1-8,CFT_WAV supports 1.
  audioCodec: media.CodecMimeType.AUDIO_G711MU, // set audioCodec,AUDIO_G711MU matching CFT_WAV.
  audioSampleRate: 8000, // set audioSampleRate according to device ability.
  fileFormat: media.ContainerFormatType.CFT_WAV // set fileFormat,CFT_WAV.
}

但是获取到的 wav 音频为封装后的 G711mu编码,我需要PCM编码的wav音频文件,请问如何将G711mu编码的wav音频文件转换成PCM编码的wav音频文件?


更多关于HarmonyOS 鸿蒙Next中AVRecorder录制的wav文件为G711mu编码,如何将的G711mu编码的wav音频文件转换成PCM编码的wav音频文件的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

PCM,音频数据的基础未压缩格式,是音频编解码器可直接处理的数字音频形式。

编码,将PCM原始音频数据按照特定算法压缩成对应的编码格式。

封装,就是将已经编码压缩好的音视频数据按照一定的格式放到一个文件中。

音频转码过程涉及到的步骤有音频编解码,媒体文件转封装。在HarmonyOS中提供AVCodec来对音频进行编解码,提供AVMuxer用于封装和AVDemuxer用于解封装。

模块 支持的格式
AVCodec所支持的音频解码格式 AAC、MPEG(MP3)、FLAC、Vorbis、AMR(amrnb、amrwb)、G711MU、APE、AudioViVid11+、OPUS。
AVCodec所支持的音频编码格式 AAC、FLAC、MP3、G711mu、AMR、OPUS。
AVDemuxer所支持的音频媒体解封装格式 m4a、aac、mp3、ogg、flac、wav、amr、ape。
AVMuxer所支持的音频媒体封装格式 mp4、m4a、mp3、amr、wav、aac。

媒体文件需对应的编码格式才能封装为指定媒体格式,详细参考媒体数据解析支持的格式。

解决方案

根据需要转换的目标音频格式不同,可以将转码需求分为两种场景:第一种场景是目标音频格式为封装格式;第二种场景是目标音频格式为编码格式。

图片

  • 场景一:需要转为特定的封装格式
    • 音频格式为封装格式,转换为其它封装格式,例如使用AVPlayer录制音频,拿到.m4a格式的音频文件,现需要将此文件转为.amr格式。查看.m4a格式解封装后对应的编码格式为AAC,见流程图中case1,先将封装格式解封装(Demuxer)得到AAC编码数据,再解码(Decode)拿到PCM音频数据,.amr文件的音频编码格式为AMR,将PCM数据编码(Encode)为AMR格式,再封装(Muxer)成.amr文件。 如果原封装格式解码后的编码格式和目标封装格式支持的编码格式一致,此时只需要转封装无需转码。
    • 音频格式为PCM原始数据,编码封装为.mp3格式的文件。 将PCM音频数据转为.mp3文件,此场景见case2,PCM音频数据编码(Encode)压缩成MP3格式,再封装(Muxer)成.mp3格式的文件。
  • 场景二:需要转为特定的编码格式
    • 在实时语音传输系统中,需要将设备采集的amr-nb编码格式转为OPUS编码格式。见流程图中case3中amr-nb编码格式到OPUS编码格式,需解码(Decode)成PCM格式再编码(Encode)到OPUS编码格式。
    • 流程图中case4,播放软件播放mp3音频时,需要将音频解封装(Demuxer)到MPEG(MP3)编码格式再解码(Decode),拿到PCM音频数据输送到硬件扬声器播放。 上述案例只是列举了几个较典型的场景,具体转换时请根据实际需要选择转封装或转码。

音视频编解码详细可参考音频编码/音频解码,封装解析可参考媒体文件的封装解析

更多关于HarmonyOS 鸿蒙Next中AVRecorder录制的wav文件为G711mu编码,如何将的G711mu编码的wav音频文件转换成PCM编码的wav音频文件的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


使用鸿蒙媒体编解码库的AVCodec组件进行转码。创建AVCodec实例,配置G.711 mu-law解码器,将WAV文件中的G.711数据解码为PCM原始数据。然后,使用AVMuxer或直接写入文件的方式,为PCM数据添加标准的WAV文件头,生成新的PCM编码的WAV文件。整个过程在鸿蒙应用层通过ArkTS调用原生媒体API完成。

在HarmonyOS Next中,将AVRecorder录制的G.711 mu-law编码的WAV文件转换为PCM编码的WAV文件,核心是进行音频解码和重新封装。由于当前系统API更侧重于媒体录制与播放,直接的转码工具类可能不完整,因此通常需要手动处理数据。

以下是基于@ohos.multimedia.media@ohos.file.fs等系统能力实现转换的关键步骤:

1. 读取原始WAV文件并解析头部 首先,使用fs模块读取文件。G.711 mu-law的WAV文件头部格式是标准的,但audioFormat字段值为7(代表G.711 mu-law)。你需要解析这个头部以获取采样率、声道数等关键信息,并找到音频数据块的起始位置。

2. 解码G.711 mu-law数据 这是转换的核心步骤。HarmonyOS Next的media库目前主要提供编码器(如AVRecorder所用),对于G.711解码,可能需要:

  • 查找专用的音频解码接口:关注media中是否有AudioDecoder相关类,并检查其支持的CodecMimeType是否包含AUDIO_G711MU
  • 若无直接解码器,需手动实现或集成解码库:G.711 mu-law解码算法是标准且相对简单的。你可以将解码算法(例如将8位mu-law样本转换为16位PCM样本的查找表或计算函数)集成到应用中。注意,这需要你处理原始字节数据。

3. 编码为PCM并封装为WAV

  • 解码后得到的已经是原始的PCM样本数据(通常是16位)。
  • 你需要构建一个新的标准WAV文件头部,其中audioFormat应设置为1(表示PCM格式),并更新数据块大小等字段。
  • 最后,将新的WAV头部和解码后的PCM数据写入一个新文件。

代码结构示意(概念性)

import fs from '@ohos.file.fs';
// 假设有解码能力或已实现decodeG711Mu函数

async function convertG711MuWavToPcmWav(inputPath: string, outputPath: string): Promise<void> {
  // 1. 读取并解析输入WAV文件头部
  let file = fs.openSync(inputPath, fs.OpenMode.READ_ONLY);
  let headerBuffer = new ArrayBuffer(44); // 标准WAV头部长度
  fs.readSync(file.fd, headerBuffer); // 读取头部
  // ... 解析headerBuffer,获取音频参数,验证格式为G.711 mu-law (audioFormat === 7)

  // 2. 读取音频数据块(G.711 mu-law编码数据)
  let dataSize = ...; // 从头部解析出的数据块大小
  let g711DataBuffer = new ArrayBuffer(dataSize);
  fs.readSync(file.fd, g711DataBuffer, { offset: 44 }); // 从头部后开始读取
  fs.closeSync(file);

  // 3. 解码G.711 mu-law数据到PCM
  // 假设decodeG711Mu函数已实现,接收ArrayBuffer,返回Int16Array或包含PCM数据的ArrayBuffer
  let pcmData: Int16Array = decodeG711Mu(g711DataBuffer); // 此处需自行实现或调用系统解码接口

  // 4. 构建新的PCM WAV头部
  let pcmHeaderBuffer = buildWavHeader(/* 参数:音频格式=1 (PCM), 声道数, 采样率, 比特深度=16, pcmData长度等 */); // 需实现此函数

  // 5. 写入新文件
  let outFile = fs.openSync(outputPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
  fs.writeSync(outFile.fd, pcmHeaderBuffer);
  // 将pcmData转换为ArrayBuffer或Uint8Array后写入
  fs.writeSync(outFile.fd, pcmData.buffer);
  fs.closeSync(outFile);
}

关键点与注意事项

  • 系统解码器支持:优先查询media库是否有现成的AudioDecoder可用于AUDIO_G711MU。如果存在,使用系统解码器是最可靠的方式。
  • 手动解码:若需手动实现,请确保准确理解G.711 mu-law的8位压缩格式到16位线性PCM的转换规则。
  • WAV头部构造:确保新生成的WAV头部字段(如文件大小、数据块大小)计算正确,以便其他播放器能正常识别。
  • 性能与内存:处理大文件时,建议流式读取、解码和写入,避免一次性加载全部数据导致内存压力。

总之,转换过程涉及文件I/O、音频格式解析、编解码数据处理。在HarmonyOS Next上,重点在于利用系统提供的媒体数据处理能力或集成轻量级解码逻辑来实现格式转换。

回到顶部