如何在wavesurfer.js与Web Audio API处理音频后导出下载mp3文件
浏览器端Wavesurfer编辑后直接导出MP3方案
你的思路完全正确,无需先生成WAV格式文件,可以直接基于wavesurfer提供的AudioBuffer类型原始音频数据编码生成MP3,所有处理均在本地浏览器完成,无需上传服务器。
方案1:使用lamejs编码(兼容性最好,适合生产环境)
lamejs是LAME MP3编码器的JavaScript移植版本,支持所有现代浏览器,编码稳定。你之前调用lamejs报错大概率是没有正确将AudioBuffer返回的[-1,1]区间浮点PCM数据转换为编码器要求的16位整型格式,以下是可直接运行的实现代码:
转换函数
// 输入为AudioBuffer类型,bitRate单位为kbps,默认320符合你要求的CBR 320规格 function audioBufferToMp3(audioBuffer, bitRate = 320) { const channels = audioBuffer.numberOfChannels; const sampleRate = audioBuffer.sampleRate; // 初始化MP3编码器 const encoder = new lamejs.Mp3Encoder(channels, sampleRate, bitRate); const mp3Data = []; // 预处理PCM数据:浮点转16位整型 const channelData = []; for (let i = 0; i < channels; i++) { const float32 = audioBuffer.getChannelData(i); const int16 = new Int16Array(float32.length); for (let j = 0; j < float32.length; j++) { const sample = Math.max(-1, Math.min(1, float32[j])); int16[j] = sample < 0 ? sample * 32768 : sample * 32767; } channelData.push(int16); } // 分块编码避免长音频卡顿 const blockSize = 1152; let length = channelData[0].length; let offset = 0; while (offset < length) { const end = Math.min(offset + blockSize, length); const leftChunk = channelData[0].subarray(offset, end); const rightChunk = channels === 2 ? channelData[1].subarray(offset, end) : null; const encoded = encoder.encodeBuffer(leftChunk, rightChunk); if (encoded.length > 0) mp3Data.push(encoded); offset = end; } // 取出剩余编码数据 const remaining = encoder.flush(); if (remaining.length > 0) mp3Data.push(remaining); return new Blob(mp3Data, { type: 'audio/mp3' }); }
调用示例
// 复用你原有逻辑获取编辑后的音频片段 const cutSelection = this.handleCopyRegion( this.wavesurfer.regions.list.cut, this.wavesurfer ); // 生成MP3 Blob const mp3Blob = audioBufferToMp3(cutSelection, 320); // 触发下载 const downloadLink = document.createElement('a'); downloadLink.href = URL.createObjectURL(mp3Blob); downloadLink.download = 'edited_audio.mp3'; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); URL.revokeObjectURL(downloadLink.href);
方案2:使用WebCodecs API实现(无需第三方依赖)
如果不需要兼容旧版本浏览器,可以使用原生WebCodecs API实现MP3编码,无需引入第三方库,性能更优。仅支持Chrome 94+、Edge 94+、Safari 15.4及以上版本浏览器:
async function audioBufferToMp3WebCodecs(audioBuffer, bitRate = 320000) { const mp3Data = []; const encoder = new AudioEncoder({ output: (chunk) => mp3Data.push(new Uint8Array(chunk.data)), error: (err) => console.error('编码失败:', err) }); encoder.configure({ codec: 'mp3', sampleRate: audioBuffer.sampleRate, numberOfChannels: audioBuffer.numberOfChannels, bitrate: bitRate }); const audioData = new AudioData({ format: audioBuffer.numberOfChannels === 1 ? 'f32-planar' : 'f32-planar-stereo', sampleRate: audioBuffer.sampleRate, numberOfFrames: audioBuffer.length, numberOfChannels: audioBuffer.numberOfChannels, timestamp: 0, data: audioBuffer.getChannelData(0) }); encoder.encode(audioData); await encoder.flush(); encoder.close(); return new Blob(mp3Data, { type: 'audio/mp3' }); }
内容的提问来源于stack exchange,提问作者Mevia
相关产品推荐
相关产品推荐

