uniapp android 如何播放pcm音频文件

在uniapp开发安卓应用时,如何播放PCM格式的音频文件?尝试过使用uni.createInnerAudioContext()但无法直接播放PCM数据,是否需要特定解码或转换?求有效的解决方案或示例代码。

2 回复

使用uniapp的plus.audio.createPlayer创建音频播放器,设置src为pcm文件路径,format设为"pcm"。注意pcm需指定采样率等参数,建议先转成wav格式再播放。


在 UniApp 中,Android 平台播放 PCM 音频文件可以通过以下方法实现:

方法一:使用原生音频 API(推荐)

由于 UniApp 的 uni.playVoice 或 HTML5 的 Audio 对象不支持直接播放 PCM 数据,需将 PCM 转换为 WAV 格式(添加 WAV 文件头),然后通过音频 API 播放。

步骤:

  1. 转换 PCM 为 WAV
    在播放前,为 PCM 数据添加 WAV 文件头(包含采样率、位深度等信息)。
  2. 播放 WAV 文件
    使用 uni.playVoiceinnerAudioContext 播放转换后的 WAV 数据。

示例代码(转换 PCM 为 WAV 并播放):

// 将 PCM 数据转换为 WAV 格式(假设 PCM 为 16 位、单声道、44100Hz 采样率)
function pcmToWav(pcmData) {
  const sampleRate = 44100;
  const numChannels = 1;
  const bitsPerSample = 16;
  const byteRate = sampleRate * numChannels * bitsPerSample / 8;
  const blockAlign = numChannels * bitsPerSample / 8;
  const dataSize = pcmData.length;

  // WAV 文件头(44 字节)
  const wavHeader = new ArrayBuffer(44);
  const view = new DataView(wavHeader);
  
  // 写入 RIFF 标识
  function writeString(view, offset, string) {
    for (let i = 0; i < string.length; i++) {
      view.setUint8(offset + i, string.charCodeAt(i));
    }
  }
  
  writeString(view, 0, 'RIFF');
  view.setUint32(4, 36 + dataSize, true); // 文件总长度
  writeString(view, 8, 'WAVE');
  writeString(view, 12, 'fmt ');
  view.setUint32(16, 16, true); // PCM 格式块大小
  view.setUint16(20, 1, true);  // 音频格式(PCM=1)
  view.setUint16(22, numChannels, true);
  view.setUint32(24, sampleRate, true);
  view.setUint32(28, byteRate, true);
  view.setUint16(32, blockAlign, true);
  view.setUint16(34, bitsPerSample, true);
  writeString(view, 36, 'data');
  view.setUint32(40, dataSize, true);
  
  // 合并 WAV 头和 PCM 数据
  const wavData = new Uint8Array(wavHeader.byteLength + pcmData.length);
  wavData.set(new Uint8Array(wavHeader), 0);
  wavData.set(new Uint8Array(pcmData), 44);
  
  return wavData.buffer;
}

// 播放 PCM 文件(假设 pcmData 为 ArrayBuffer 类型)
function playPCM(pcmData) {
  const wavData = pcmToWav(pcmData);
  
  // 将 WAV 数据转换为临时 URL
  const blob = new Blob([wavData], { type: 'audio/wav' });
  const url = URL.createObjectURL(blob);
  
  // 使用 UniApp 音频 API 播放
  const audio = uni.createInnerAudioContext();
  audio.src = url;
  audio.play();
  
  // 播放完成后释放 URL
  audio.onEnded(() => {
    URL.revokeObjectURL(url);
  });
}

// 调用示例:从文件读取 PCM 数据并播放
uni.getFileSystemManager().readFile({
  filePath: 'path/to/your.pcm',
  success: (res) => {
    playPCM(res.data); // res.data 为 ArrayBuffer
  }
});

方法二:使用原生插件

如果性能要求高或需直接处理 PCM,可开发原生插件(Android 使用 AudioTrack):

  • 在 Android 原生代码中实现 PCM 播放逻辑。
  • 通过 UniApp 插件机制调用原生功能。

注意事项:

  • PCM 参数:确保转换 WAV 时指定正确的采样率、位深度和声道数。
  • 文件路径:如果 PCM 文件在本地,使用 uni.getFileSystemManager().readFile 读取;若为网络资源,需先下载。
  • 兼容性innerAudioContext 在 Android 和 iOS 均支持,但 PCM 需转换为兼容格式(如 WAV)。

以上方法可实现在 UniApp Android 环境中播放 PCM 音频。根据需求选择合适方案,推荐优先使用方法一。

回到顶部