vue实现发送语音功能
实现语音录制功能
使用浏览器提供的MediaRecorder API进行语音录制。在Vue组件的data中定义相关变量:
data() {
return {
mediaRecorder: null,
audioChunks: [],
isRecording: false,
audioBlob: null
}
}
创建开始录制方法:
startRecording() {
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
this.mediaRecorder = new MediaRecorder(stream)
this.mediaRecorder.start()
this.isRecording = true
this.mediaRecorder.ondataavailable = event => {
this.audioChunks.push(event.data)
}
})
}
实现语音停止与保存
添加停止录制方法:

stopRecording() {
this.mediaRecorder.stop()
this.isRecording = false
this.mediaRecorder.onstop = () => {
this.audioBlob = new Blob(this.audioChunks, { type: 'audio/wav' })
this.audioChunks = []
}
}
实现语音播放功能
创建播放录音的方法:
playRecording() {
const audioURL = URL.createObjectURL(this.audioBlob)
const audio = new Audio(audioURL)
audio.play()
}
实现语音上传
添加上传到服务器的方法:

uploadRecording() {
const formData = new FormData()
formData.append('audio', this.audioBlob, 'recording.wav')
axios.post('/api/upload-audio', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
}).then(response => {
console.log('上传成功', response)
})
}
组件模板示例
<template>
<div>
<button @click="startRecording" :disabled="isRecording">开始录音</button>
<button @click="stopRecording" :disabled="!isRecording">停止录音</button>
<button @click="playRecording" :disabled="!audioBlob">播放</button>
<button @click="uploadRecording" :disabled="!audioBlob">上传</button>
</div>
</template>
添加录音可视化
使用AudioContext实现简单的波形可视化:
setupVisualizer() {
const audioContext = new AudioContext()
const analyser = audioContext.createAnalyser()
const canvas = this.$refs.visualizer
const canvasCtx = canvas.getContext('2d')
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
const source = audioContext.createMediaStreamSource(stream)
source.connect(analyser)
this.visualize(analyser, canvas, canvasCtx)
})
}
visualize(analyser, canvas, canvasCtx) {
const WIDTH = canvas.width
const HEIGHT = canvas.height
analyser.fftSize = 2048
const draw = () => {
requestAnimationFrame(draw)
const bufferLength = analyser.frequencyBinCount
const dataArray = new Uint8Array(bufferLength)
analyser.getByteTimeDomainData(dataArray)
canvasCtx.fillStyle = 'rgb(200, 200, 200)'
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT)
canvasCtx.lineWidth = 2
canvasCtx.strokeStyle = 'rgb(0, 0, 0)'
canvasCtx.beginPath()
const sliceWidth = WIDTH * 1.0 / bufferLength
let x = 0
for(let i = 0; i < bufferLength; i++) {
const v = dataArray[i] / 128.0
const y = v * HEIGHT/2
if(i === 0) {
canvasCtx.moveTo(x, y)
} else {
canvasCtx.lineTo(x, y)
}
x += sliceWidth
}
canvasCtx.lineTo(canvas.width, canvas.height/2)
canvasCtx.stroke()
}
draw()
}
添加录音时长限制
在开始录音时设置自动停止:
startRecording() {
// ...之前的代码...
// 设置60秒后自动停止
this.recordingTimer = setTimeout(() => {
this.stopRecording()
}, 60000)
}
stopRecording() {
clearTimeout(this.recordingTimer)
// ...之前的代码...
}






