1. 为什么选择 js-audio-recorder 和 lamejs?
在 Vue 项目中实现录音功能,听起来好像挺复杂,是不是得自己处理一大堆 Web Audio API?其实完全不用。我刚开始做这个需求的时候也头疼过,但后来发现了 js-audio-recorder 这个宝藏库,它把浏览器录音的复杂逻辑都封装好了,我们只需要调用几个简单的方法就行。它最大的好处是开箱即用,支持 PCM、WAV 和 MP3 格式的录音数据获取,而且自带播放、暂停、下载这些基础功能,省去了我们大量造轮子的时间。
但是,js-audio-recorder 本身不直接输出 MP3 格式。MP3 作为最通用的音频格式,体积小、兼容性好,无论是上传到服务器还是本地保存,都是首选。这时候就需要 lamejs 这个库出场了。它是一个纯 JavaScript 的 MP3 编码器,可以把原始的 PCM 或 WAV 数据高效地转换成 MP3。实测下来,这个组合非常稳定,在主流浏览器上都能跑得很顺畅。
所以,我们的技术栈就确定了:Vue 3(或 2) + js-audio-recorder + lamejs。这个方案既能快速实现功能,又能保证最终产出的音频文件是兼容性最好的 MP3 格式。接下来,我就带你一步步从零开始,把整个流程跑通,包括安装、基础录音、波形图绘制,以及最关键的 WAV 转 MP3。
2. 项目环境搭建与依赖安装
万事开头先建项目。如果你还没有 Vue 项目,可以用 Vue CLI 或者 Vite 快速创建一个。这里我假设你已经有了一个现成的 Vue 项目,我们直接进入安装环节。
打开你的终端,进入项目根目录,执行以下命令来安装两个核心库:
npm install js-audio-recorder lamejs
# 或者使用 yarn
yarn add js-audio-recorder lamejs
# 或者使用 pnpm
pnpm add js-audio-recorder lamejs
这里有个小坑我踩过:lamejs 这个包在某些网络环境下可能安装比较慢,因为它包含了一些编译好的二进制模块。如果安装失败,可以尝试切换 npm 镜像源,或者多试几次。安装成功后,你可以在 package.json 的 dependencies 里看到它们。
安装完库,我们得在 Vue 组件里引入它们。通常我会创建一个单独的 Vue 组件,比如叫 AudioRecorder.vue,来管理所有录音相关的逻辑。这样代码比较清晰,也方便复用。在组件的 <script> 部分,我们这样引入:
import Recorder from 'js-audio-recorder';
import lamejs from 'lamejs';
注意,lamejs 的引入方式,在有些构建工具里可能需要用 require 语法,但现代 Vue 项目通常用 ES6 的 import 就行。如果遇到问题,可以检查一下你的构建配置。
3. 初始化录音器与基础功能实现
库装好了,接下来就是初始化录音器实例。这是整个功能的核心。js-audio-recorder 的初始化配置很简单,主要关注三个参数:采样位数 (sampleBits)、采样率 (sampleRate) 和声道数 (numChannels)。
// 在组件的 data 或 setup 中初始化
const recorder = new Recorder({
sampleBits: 16, // 采样位数,8 或 16,16 位音质更好
sampleRate: 48000, // 采样率,常见的有 16000, 44100, 48000
numChannels: 1, // 声道数,1 是单声道,2 是立体声
});
我一般会把采样率设为 48000,这是目前很多浏览器麦克风的默认采样率,音质不错。如果你做语音识别,可能需要用 16000,因为很多语音识别引擎要求这个采样率。单声道对于语音录制完全够用,还能减小文件体积。
初始化之后,就可以实现基础的开始、暂停、继续、停止录音了。这些功能对应着 recorder 实例的几个方法,都是返回 Promise 的,所以用 async/await 或者 .then/.catch 来处理很方便。我习惯在 Vue 的 methods 或 setup 里把这些方法封装一下:
methods: {
async startRecording() {
try {
await this.recorder.start();
console.log('录音开始');
// 这里可以开始绘制波形图
this.startWaveform();
} catch (error) {
console.error('录音启动失败:', error);
// 处理错误,比如用户拒绝了麦克风权限
this.$message.error('无法访问麦克风,请检查权限设置');
}
},
pauseRecording() {
this.recorder.pa

427

被折叠的 条评论
为什么被折叠?



