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

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

1224 热度
408 浏览

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

bash 复制代码
npm i js-audio-recorder

还需要用到一个库 lamejs。这个 npm 下载的会有 bug,也可以在 node_modules 修改 bug,个人开发改改还行,多人开发还是算了。所以可以使用 CDN 来引入。

  • 注:可以把它下载到本地引入,这样就无关 CDN 的链接是否正常,都可使用
html 复制代码
<script src="https://cdn.jsdelivr.net/npm/lamejs@1.2.0/lame.all.js"></script>

一般需求都是长按录音。这里写一个开始触摸调用的方法。

下面有几个参数,比如 sampleRate(采样率)越低,录制的音频文件就越小。
numChannels(声道)1 就是单声道,2 就是立体声,当然 1 的文件会小很多。

js 复制代码
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);
    }
},

这里是手指松开,结束长摁的方法。

  • 首先要把录音给停止了。
  • 调用下个版块的函数 wavToMp3 来把生成的音频处理成 mp3。
  • 下面数据有 Blob、URL、base64,看你需要哪种数据格式。
js 复制代码
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) => { // 把 mp3 Blob 文件转为 base64 格式。
        console.log('base64=', base64)
    })
    this.recorder.stream.getTracks().forEach(track => track.stop()) // 这一步很关键,说完话,要把麦克风给释放掉。
},

wavToMp3 函数。

  • 注意:channels、sampleRate 要与上面的 new Recorder 的参数 numChannels、sampleRate 一致。
  • 要不然编译出来的音频听着很怪。
js 复制代码
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(); // 完成mp3音频编码的编写
    if (mp3buf.length > 0) {
        mp3Data.push(new Int8Array(mp3buf));
    }
    var blob = new Blob(mp3Data, { type: "audio/mp3" });
    return blob; // 返回这个 mp3 的 Blob 对象
},

把 Blob 转为 base64 格式。

js 复制代码
blobToDataURI(blob, callback) {
    var reader = new FileReader();
    reader.readAsDataURL(blob);
    reader.onload = function (e) {
        callback(e.target.result);
    };
},
实现一个 js 录制音频,并且转为mp3音频编码格式。

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

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

评论 (0)

0/50
暂无评论,快来抢沙发吧~