如何在Javascript中将音频缓冲区转换为MP3? [英] How to convert Audio buffer to MP3 in Javascript?

查看:201
本文介绍了如何在Javascript中将音频缓冲区转换为MP3?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ReactJS中使用MediaRecorder来记录来自麦克风的音频,并以MIME类型"audio/mp3"将其存储到blob中.我想将此Blob转换为MP3,然后将其上传到S3存储桶中.

I am using MediaRecorder in ReactJS to record audio from the microphone and storing into the blob with MIME type "audio/mp3". I want to convert this blob to MP3 and upload it in S3 bucket.

我可以通过使用audioContext,decodeAudioData和audioBufferToWav函数将其转换为WAV,但是WAV的大小非常大.由于MP3文件的大小相对较小,因此我希望它将我的Blob转换为MP3.有帮助吗?

I am able to convert it into WAV by using audioContext, decodeAudioData and audioBufferToWav functions, but the size of the WAV is very large. Since the MP3 file has relatively very small in size so I want it to convert my blob to MP3. Any help?

我用于记录并转换为wav的代码:

My code for recording and converting to wav:

getUserMedia({ audio: true })
      .then(stream => {
        this.stream = stream;
        const mimeType = 'audio/mp3';
        this.mediaRecorder = new MediaRecorder(stream);
        this.mediaRecorder.start();
        const audioChunks = [];
        this.mediaRecorder.addEventListener('dataavailable', event => {
          audioChunks.push(event.data);
        });

        this.mediaRecorder.addEventListener('stop', () => {
          const audioBlob = new Blob(audioChunks, {
            type: mimeType});

        });
      }).catch(error => { });

将上面创建的Blob转换为WAV:

Converting above created blob to WAV:

const reader = new window.FileReader();
    reader.readAsDataURL(audioBlob);
    reader.onloadend = () => {
      let base64 = reader.result + '';
      base64 = base64.split(',')[1];
      const ab = new ArrayBuffer(base64.length);
      const buff = new Buffer.from(base64, 'base64');
      const view = new Uint8Array(ab);
      for (let i = 0; i < buff.length; ++i) {
        view[i] = buff[i];
      }
      const context = new AudioContext();
      context.decodeAudioData(ab, (buffer) => {
      const wavFile = toWav(buffer);
}

我正在将 wavFile 存储到S3中.我想要MP3,请帮忙吗?

I am storing wavFile into the S3. I want MP3, please help?

推荐答案

我没有使用ReactJS MediaRecorder,也没有完全按照您的特定示例中的情况进行操作,但是我有一个将AudioBuffer转换为mp3的解决方案,波的方式.

I'm not using the ReactJS MediaRecorder nor do I exactly follow what's going on in your specific example, but I have a solution for converting an AudioBuffer to an mp3, way of wave.

第一个功能基于 russellgood.com/如何将音频缓冲区转换为音频文件.第二个基于 lamejs .

The first function is based on russellgood.com/how-to-convert-audiobuffer-to-audio-file. The second is based on lamejs.

function audioBufferToWav(aBuffer) {
    let numOfChan = aBuffer.numberOfChannels,
        btwLength = aBuffer.length * numOfChan * 2 + 44,
        btwArrBuff = new ArrayBuffer(btwLength),
        btwView = new DataView(btwArrBuff),
        btwChnls = [],
        btwIndex,
        btwSample,
        btwOffset = 0,
        btwPos = 0;
    setUint32(0x46464952); // "RIFF"
    setUint32(btwLength - 8); // file length - 8
    setUint32(0x45564157); // "WAVE"
    setUint32(0x20746d66); // "fmt " chunk
    setUint32(16); // length = 16
    setUint16(1); // PCM (uncompressed)
    setUint16(numOfChan);
    setUint32(aBuffer.sampleRate);
    setUint32(aBuffer.sampleRate * 2 * numOfChan); // avg. bytes/sec
    setUint16(numOfChan * 2); // block-align
    setUint16(16); // 16-bit
    setUint32(0x61746164); // "data" - chunk
    setUint32(btwLength - btwPos - 4); // chunk length

    for (btwIndex = 0; btwIndex < aBuffer.numberOfChannels; btwIndex++)
        btwChnls.push(aBuffer.getChannelData(btwIndex));

    while (btwPos < btwLength) {
        for (btwIndex = 0; btwIndex < numOfChan; btwIndex++) {
            // interleave btwChnls
            btwSample = Math.max(-1, Math.min(1, btwChnls[btwIndex][btwOffset])); // clamp
            btwSample = (0.5 + btwSample < 0 ? btwSample * 32768 : btwSample * 32767) | 0; // scale to 16-bit signed int
            btwView.setInt16(btwPos, btwSample, true); // write 16-bit sample
            btwPos += 2;
        }
        btwOffset++; // next source sample
    }

    let wavHdr = lamejs.WavHeader.readHeader(new DataView(btwArrBuff));
    let wavSamples = new Int16Array(btwArrBuff, wavHdr.dataOffset, wavHdr.dataLen / 2);

    wavToMp3(wavHdr.channels, wavHdr.sampleRate, wavSamples);

    function setUint16(data) {
        btwView.setUint16(btwPos, data, true);
        btwPos += 2;
    }

    function setUint32(data) {
        btwView.setUint32(btwPos, data, true);
        btwPos += 4;
    }
}

第二,将波形转换为mp3

function wavToMp3(channels, sampleRate, samples) {
    var buffer = [];
    var mp3enc = new lamejs.Mp3Encoder(channels, sampleRate, 128);
    var remaining = samples.length;
    var samplesPerFrame = 1152;
    for (var i = 0; remaining >= samplesPerFrame; i += samplesPerFrame) {
        var mono = samples.subarray(i, i + samplesPerFrame);
        var mp3buf = mp3enc.encodeBuffer(mono);
        if (mp3buf.length > 0) {
            buffer.push(new Int8Array(mp3buf));
        }
        remaining -= samplesPerFrame;
    }
    var d = mp3enc.flush();
    if(d.length > 0){
        buffer.push(new Int8Array(d));
    }

    var mp3Blob = new Blob(buffer, {type: 'audio/mp3'});
    var bUrl = window.URL.createObjectURL(mp3Blob);

    // send the download link to the console
    console.log('mp3 download:', bUrl);

}

希望这会有所帮助!

这篇关于如何在Javascript中将音频缓冲区转换为MP3?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆