NodeJS中如何转换MPEG音频为8kHz audio/x-mulaw并Base64编码适配Twilio
解决Twilio媒体流TTS音频转mu-law编码后杂音问题
你的核心问题是把压缩的audio/mpeg二进制直接当作未压缩的16位PCM数据处理,WaveFile的fromScratch方法需要的是原始PCM采样值,而非mpeg压缩数据,这导致后续编码完全错乱,产生杂音。
要正确完成转换,必须先把audio/mpeg解码为未压缩的PCM,再转成8000Hz单声道格式,最后编码为mu-law并Base64编码。推荐用ffmpeg处理,因为它能可靠处理音频解码和格式转换,以下是修正后的代码:
const ffmpeg = require('fluent-ffmpeg'); const { PassThrough } = require('stream'); async function convertToMuLaw(rawMpegData) { return new Promise((resolve, reject) => { const inputStream = new PassThrough(); inputStream.end(rawMpegData); const mulawChunks = []; // 第一步:将mpeg解码为8000Hz单声道16位PCM ffmpeg(inputStream) .inputFormat('mpeg') .audioChannels(1) .audioFrequency(8000) .audioCodec('pcm_s16le') .format('wav') // 第二步:将PCM编码为mu-law原始格式 .pipe(ffmpeg().inputFormat('wav') .audioCodec('pcm_mulaw') .format('raw') .on('data', chunk => mulawChunks.push(chunk)) .on('end', () => { const mulawBuffer = Buffer.concat(mulawChunks); // 最后转Base64 resolve(mulawBuffer.toString('base64')); }) .on('error', err => reject(err)) ) .on('error', err => reject(err)); }); }
补充说明
- 确保你的环境已经安装了ffmpeg,并且fluent-ffmpeg能找到它(可以通过设置
ffmpeg.setFfmpegPath()指定路径) - 如果不想用ffmpeg,也可以找纯JS的mpeg解码库先解码出PCM,再用WaveFile转mu-law,但ffmpeg的兼容性和稳定性更好
内容的提问来源于stack exchange,提问作者J.Gudal
相关产品推荐
相关产品推荐

