You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

138 lines
3.6 KiB

<template>
<el-dialog class="chat-record" title="语音录制" :visible.sync="visible" width="600px" :before-close="onClose">
<div v-show="mode == 'RECORD'">
<div class="tip">{{ stateTip }}</div>
<div>时长: {{ state == 'STOP' ? 0 : parseInt(rc.duration) }}s</div>
</div>
<audio v-show="mode == 'PLAY'" :src="url" controls ref="audio" @ended="onStopAudio()"></audio>
<el-divider content-position="center"></el-divider>
<el-row class="btn-group">
<el-button round type="primary" v-show="state == 'STOP'" @click="onStartRecord()">开始录音</el-button>
<el-button round type="warning" v-show="state == 'RUNNING'" @click="onPauseRecord()">暂停录音</el-button>
<el-button round type="primary" v-show="state == 'PAUSE'" @click="onResumeRecord()">继续录音</el-button>
<el-button round type="danger" v-show="state == 'RUNNING' || state == 'PAUSE'" @click="onCompleteRecord()">
结束录音</el-button>
<el-button round type="success" v-show="state == 'COMPLETE' && mode != 'PLAY'" @click="onPlayAudio()">播放录音
</el-button>
<el-button round type="warning" v-show="state == 'COMPLETE' && mode == 'PLAY'" @click="onStopAudio()">停止播放
</el-button>
<el-button round type="primary" v-show="state == 'COMPLETE'" @click="onRestartRecord()">重新录音</el-button>
<el-button round type="primary" v-show="state == 'COMPLETE'" @click="onSendRecord()">立即发送</el-button>
</el-row>
</el-dialog>
</template>
<script>
import Recorder from 'js-audio-recorder';
export default {
name: 'chatRecord',
props: {
visible: {
type: Boolean
}
},
data() {
return {
rc: new Recorder(),
audio: new Audio(),
state: 'STOP', // STOP、RUNNING、PAUSE、COMPLETE
stateTip: "未开始",
mode: 'RECORD', // RECORD 、PLAY
duration: 0,
url: ""
}
},
methods: {
onClose() {
// 关闭前清除数据
this.rc.destroy();
this.rc = new Recorder();
this.audio.pause();
this.mode = 'RECORD';
this.state = 'STOP';
this.stateTip = '未开始';
this.$emit("close");
},
onStartRecord() {
this.rc.start().then((stream) => {
this.state = 'RUNNING';
this.stateTip = "正在录音...";
}).catch(error => {
this.$message.error(error);
});
},
onPauseRecord() {
this.rc.pause();
this.state = 'PAUSE';
this.stateTip = "已暂停录音";
},
onResumeRecord() {
this.rc.resume();
this.state = 'RUNNING';
this.stateTip = "正在录音...";
},
onCompleteRecord() {
this.rc.pause();
this.state = 'COMPLETE';
this.stateTip = "已结束录音";
},
onPlayAudio() {
let wav = this.rc.getWAVBlob();
let url = URL.createObjectURL(wav);
this.$refs.audio.src = url;
this.$refs.audio.play();
this.mode = 'PLAY';
},
onStopAudio() {
this.$refs.audio.pause();
this.mode = 'RECORD';
},
onRestartRecord() {
this.rc.destroy();
this.rc = new Recorder()
this.rc.start();
this.state = 'RUNNING';
this.mode = 'RECORD';
this.stateTip = "正在录音...";
},
onSendRecord() {
let wav = this.rc.getWAVBlob();
let name = new Date().getDate() + '.wav';
var formData = new window.FormData()
formData.append('file', wav, name);
this.$http({
url: '/file/upload',
data: formData,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data'
}
}).then((url) => {
let data = {
duration: parseInt(this.rc.duration),
url: url
}
this.$emit("send", data);
this.onClose();
})
}
}
}
</script>
<style lang="scss">
.chat-record {
.tip {
font-size: 18px;
}
.btn-group {
margin-bottom: 20px;
}
}
</style>