实现一个 js 录制音频,并且转为mp3音频编码格式。


电脑浏览器录制出来的是webm音频编码格式、手机浏览器录制出来的是mp4音频编码格式。如后端指定格式需要把它们的音频编码格式转一下。以下,以转mp3音频编码格式为例。

首先我们先使用 npm 安装一下 js-audio-recorder 库。
npm i js-audio-recorder


还需要用到一个库 lamejs 这个npm下载的会有bug,也可以在node_modules修改bug,个人开发改改还行,多人开发还是算了。所以可以使用cdn来引入。注:可以把它下载到本地引入,这样就无关cdn的链接是否正常,都可使用。
<script src="https://cdn.jsdelivr.net/npm/lamejs@1.2.0/lame.all.js"></script>


一般需求都是长按录音。这里写一个开始触摸调用的方法。
下面有几个参数,比如 sampleRate (采样率)越低,录制的音频文件就越小。numChannels (声道) 1 就是单声道,2就是立体声,当然 1 的文件会小很多。
        async startRecording() {
            try {
                if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                    throw new Error("当前浏览器不支持音频录制");
                }
                this.recorder = new Recorder({
                    sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
                    sampleRate: 8000, // 采样率,支持 11025、16000、22050、24000、44100、48000。
                    numChannels: 1, // 声道,支持 1 或 2, 默认是1
                });
                this.recorder.start();
            } catch (error) {
                       // 如果拒绝 getUserMedia 会在这里返回错误
                console.log("error", error);
            }
        },


这里是手指松开,结束长摁的方法。1、首先要把录音给停止了。2、调用下个版块的函数 wavToMp3 来把生成的音频处理成 mp3。3、下面数据有 Blob、URL、base64,看你需要哪种数据格式。
        sendEndAudio() {
            this.recorder.stop(); // 录音停止
            let mp3Blob = this.wavToMp3( // blob 文件格式。
                this.recorder.getWAV(),
                this.recorder.getChannelData()
            );
            this.audioData = URL.createObjectURL(mp3Blob); // 转为链接,可以把它赋值给audio元素听一下效果。
            this.blobToDataURI(mp3Blob, (base64) => { // 把 map3 Blob 文件转为 base64 格式。
                console.log('base64=', base64)
            })
            this.recorder.stream.getTracks().forEach(track => track.stop())  // 这一步很关键,说完话,要把麦克风给释放掉。
        },


wavToMp3 函数。注意:channels、sampleRate 要与上面的 new Recorder 的参数 numChannels、sampleRate 一致。要不然编译出来的音频听着很怪。
        wavToMp3(recorderData) {
            const channels = 1; // 1 单声道 2 立体声
            const sampleRate = 8000; // 采样率
            const kbps = 128; // 128kbps mp3
            var mp3encoder = new lamejs.Mp3Encoder(channels, sampleRate, kbps); // 初始化 MP3 编码器
            var mp3Data = [];
            var samples = new Int16Array(recorderData.buffer); // 从源中获取数据
            const sampleBlockSize = 1152; // 576的倍数
            for (var i = 0; i < samples.length; i += sampleBlockSize) {
                var sampleChunk = samples.subarray(i, i + sampleBlockSize);
                const mp3buf = mp3encoder.encodeBuffer(sampleChunk);
                if (mp3buf.length > 0) {
                    mp3Data.push(mp3buf);
                }
            }
            var mp3buf = mp3encoder.flush(); // 完成map3音频编码的编写
            if (mp3buf.length > 0) {
                mp3Data.push(new Int8Array(mp3buf));
            }
            var blob = new Blob(mp3Data, { type: "audio/mp3" });
            return blob; // 返回这个 map3 的 Blob 对象
        },


把 Blob 转为 base64 格式。
        blobToDataURI(blob, callback) {
            var reader = new FileReader();
            reader.readAsDataURL(blob);
            reader.onload = function (e) {
                callback(e.target.result);
            };
        },

221

声明:Web前端小站 - 前端博客 - 王搏的个人博客|版权所有,违者必究|如未注明,均为原创

转载:转载请注明原文链接 - 实现一个 js 录制音频,并且转为mp3音频编码格式。

孙瑞杰生日