使用lamejs导出AudioBuffer为MP3无声音问题求助
解决AudioBuffer转MP3无声问题
核心问题
你当前代码直接将AudioBuffer返回的32位浮点PCM数据传入lamejs编码器,但lamejs要求输入是16位有符号整数PCM数据。这会导致编码器无法正确解析音频样本,最终输出的MP3只有正确时长但没有声音。
修复方案
需要先将32位浮点样本(范围-1到1)转换为16位整数样本(范围-32767到32767),再传入编码器。以下是修改后的完整代码:
转换函数+编码函数
// 把32位浮点PCM转成16位整数PCM function floatTo16BitPCM(input) { const output = new Int16Array(input.length); for (let i = 0; i < input.length; i++) { const s = Math.max(-1, Math.min(1, input[i])); output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF; } return output; } // 2 channels async encodeAudioBufferLame(audioBuffer) { const mp3encoder = new Mp3Encoder(2, audioBuffer.sampleRate, 128); const mp3Data = []; // 获取浮点PCM并转换为16位整数 const leftFloat = audioBuffer.getChannelData(0); const rightFloat = audioBuffer.getChannelData(1); const left = floatTo16BitPCM(leftFloat); const right = floatTo16BitPCM(rightFloat); const sampleBlockSize = 1152; // MPEG-1 Layer 3标准每帧样本数 for (let i = 0; i < left.length; i += sampleBlockSize) { const leftChunk = left.subarray(i, i + sampleBlockSize); const rightChunk = right.subarray(i, i + sampleBlockSize); const mp3buf = mp3encoder.encodeBuffer(leftChunk, rightChunk); if (mp3buf.length > 0) { mp3Data.push(mp3buf); } } const mp3buf = mp3encoder.flush(); if (mp3buf.length > 0) { mp3Data.push(mp3buf); } return mp3Data; }
导出代码(保持不变)
const mp3Data = await encodeAudioBufferLame(audioBuffer); const blob = new Blob(mp3Data, {type: 'audio/mp3'}); const url = window.URL.createObjectURL(blob); const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.setAttribute('download', `myAudio.mp3`); downloadLink.click();
额外验证建议
- 可以先将转换后的16位整数PCM导出为WAV文件,确认音频正常播放,再进行MP3编码,排除PCM转换错误的可能。
- 确保编码器初始化时的采样率与AudioBuffer的
sampleRate一致(不要硬写44100,用audioBuffer.sampleRate适配不同输入)。
内容的提问来源于stack exchange,提问作者AppInHand-Dev
相关产品推荐
相关产品推荐

