一、理论参考
常用配置项 options
options
{
sampleBits: 16,
sampleRate: 48000,
numChannels: 1,
compiling: false
}
new Recorder(options)
复制代码
常用属性 attrs
duration
recorder.duration
复制代码
fileSize
recorder.fileSize
复制代码
常用方法 getWAVBlob
获取数据方法
recorder.getRecordAnalyseData()
recorder.getPlayAnalyseData()
复制代码
录音方法
recorder.start()
recorder.pause()
recorder.resume()
recorder.stop()
复制代码
播放方法
recorder.play()
recorder.pausePlay()
recorder.resumePlay()
recorder.stopPlay()
复制代码
下载方法
recorder.downloadPCM()
recorder.downloadWAV()
复制代码
销毁方法
recorder.destroy()
二、使用
安装
npm i js-audio-recorder
具体组件代码
<template>
<div class="BaseRecorder">
<div class="BaseRecorder-record">
<el-button @click="startRecorder()" :disabled="recorder_state !== '无'">开始录音</el-button>
<el-button @click="pauseRecorder()">暂停录音</el-button>
<el-button @click="resumeRecorder()">继续录音</el-button>
<el-button @click="stopRecorder()" :disabled="recorder_state === '无'">结束录音</el-button>
</div>
<div class="BaseRecorder-play">
<el-button @click="playRecorder()" :disabled="play_state !== '无'">录音播放</el-button>
<el-button @click="pausePlayRecorder()">暂停录音播放</el-button>
<el-button @click="resumePlayRecorder()">恢复录音播放</el-button>
<el-button @click="stopPlayRecorder()" :disabled="play_state === '无'"
>停止录音播放</el-button
>
</div>
<div class="BaseRecorder-download">
<el-button @click="downPCM()">下载PCM格式录音</el-button>
<el-button @click="downWAV()">下载WAV格式录音</el-button>
</div>
<div class="BaseRecorder-destroy">
<el-button type="error" @click="destroyRecorder()">销毁录音</el-button>
</div>
<div class="BaseRecorder-wave">
<p class="recorder_state">{{ recorder_state }}</p>
<canvas ref="record"></canvas>
<p class="recorder_state">{{ play_state }}</p>
<canvas ref="play"></canvas>
</div>
</div>
</template>
<script>
import Recorder from 'js-audio-recorder';
export default {
data() {
return {
recorder: null,
drawRecordId: null,
drawPlayId: null,
recorder_state: '无',
play_state: '无',
};
},
mounted() {
this.init();
},
methods: {
init() {
this.recorder = new Recorder({
sampleBits: 16,
sampleRate: 48000,
numChannels: 1,
compiling: false,
});
},
startRecorder() {
this.recorder.start().then(
() => {
this.drawRecord();
this.recorder_state = '录音中...';
},
error => {
console.log(`${error.name} : ${error.message}`);
},
);
},
resumeRecorder() {
this.recorder.resume();
this.drawRecord();
this.recorder_state = '录音中...';
},
pauseRecorder() {
this.recorder.pause();
this.recorder_state = '暂停录音';
this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
this.drawRecordId = null;
},
stopRecorder() {
this.recorder.stop();
this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
this.drawRecordId = null;
this.recorder_state = '无';
},
playRecorder() {
this.recorder.play();
this.drawPlay();
this.play_state = '录音播放中';
},
pausePlayRecorder() {
this.recorder.pausePlay();
this.play_state = '录音暂停播放';
},
resumePlayRecorder() {
this.recorder.resumePlay();
this.drawPlay();
this.play_state = '录音播放中';
},
stopPlayRecorder() {
this.recorder.stopPlay();
this.play_state = '无';
},
destroyRecorder() {
this.recorder.destroy().then(() => {
console.log(this.drawRecordId, this.drawPlayId);
this.drawRecordId && cancelAnimationFrame(this.drawRecordId);
this.drawRecordId = null;
this.drawPlayId && cancelAnimationFrame(this.drawPlayId);
this.drawPlayId = null;
this.init();
});
},
downPCM() {
this.recorder.downloadPCM('新文件');
},
downWAV() {
this.recorder.downloadWAV('新文件');
},
drawRecord() {
this.drawRecordId = requestAnimationFrame(this.drawRecord);
this.drawWave({
canvas: this.$refs.record,
dataArray: this.recorder.getRecordAnalyseData(),
bgcolor: 'white',
lineWidth: 1,
lineColor: 'red',
});
},
drawPlay() {
this.drawPlayId = requestAnimationFrame(this.drawPlay);
this.drawWave({
canvas: this.$refs.play,
dataArray: this.recorder.getPlayAnalyseData(),
});
},
drawWave({
canvas,
dataArray,
bgcolor = 'rgb(200, 200, 200)',
lineWidth = 2,
lineColor = 'rgb(0, 0, 0)',
}) {
if (!canvas) return;
const ctx = canvas.getContext('2d');
const bufferLength = dataArray.length;
const sliceWidth = canvas.width / bufferLength;
let x = 0;
ctx.fillStyle = bgcolor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.lineWidth = lineWidth;
ctx.strokeStyle = lineColor;
ctx.beginPath();
for (let i = 0; i < bufferLength; i++) {
const v = dataArray[i] / 128;
const y = (v * canvas.height) / 2;
if (i === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
x += sliceWidth;
}
ctx.lineTo(canvas.width, canvas.height / 2);
ctx.stroke();
},
},
};
</script>
<style lang="scss" scoped>
.BaseRecorder {
text-align: center;
& > div {
margin: 20px 0;
}
&-wave {
canvas {
width: 400px;
height: 100px;
border: 1px solid #ccc;
}
}
}
.recorder_state {
font-size: 30px;
color: red;
}
</style>