226 lines
7.7 KiB
Vue
226 lines
7.7 KiB
Vue
|
<template>
|
||
|
<div>
|
||
|
<el-card style="width: 80%;margin: 30px auto;">
|
||
|
<div slot="header" style="text-align: center;">
|
||
|
<span style="font-size: 20px;color: #000;">语音识别训练</span>
|
||
|
<el-button style="float: right; padding: 3px 0" type="text">清空</el-button>
|
||
|
</div>
|
||
|
<div>
|
||
|
<div v-for="(chatContent,index) in messageList" :key="index" class="chatContentInClass">
|
||
|
<div class="leftUser">
|
||
|
<div class="userHeader">
|
||
|
<div class="userChatTime">{{ covertTime(chatContent.time) }}</div>
|
||
|
</div>
|
||
|
<div class="userBubble" @click="playAudio(baseUrl+chatContent.src, chatContent)">
|
||
|
<div class="userMessage">
|
||
|
<!-- 语音播放 -->
|
||
|
<div class="wifi-symbol">
|
||
|
<div class="wifi-circle first" />
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<audio id="audioPlay" style="display:none" />
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div style="position: relative;height: 50px;">
|
||
|
<el-button class="chat-box-footer-create chat-box-footer-send" :class="{'active': recordSending}" size="mini" type="primary" @click="startRecording()">
|
||
|
<el-progress id="record_progress_bar" type="circle" :show-text="false" :percentage="100/60*seconds" :width="40" :stroke-width="2" status="success" />
|
||
|
<i v-if="recordSending" class="el-icon-close close_icon" @click.stop="cancleRecording()" />
|
||
|
<span class="iconfont icon-yuyin"></span>
|
||
|
</el-button>
|
||
|
</div>
|
||
|
</el-card>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
import RecordRTC from 'recordrtc';
|
||
|
import { uploadAudioFiles } from '@/api/voice';
|
||
|
export default {
|
||
|
name: 'Index',
|
||
|
data() {
|
||
|
return {
|
||
|
seconds: 0,
|
||
|
recordSending: false,
|
||
|
recorders: null,
|
||
|
microphone:null,
|
||
|
messageList: [{ filePath: '/8888', result: '测试文字' }]
|
||
|
};
|
||
|
},
|
||
|
methods: {
|
||
|
startRecording() {
|
||
|
this.audioPlay = true;
|
||
|
const that = this;
|
||
|
if (!this.recordSending) {
|
||
|
if (!this.recordSending && !this.recorders && !this.microphone) {
|
||
|
const StereoAudioRecorder = RecordRTC.StereoAudioRecorder;
|
||
|
navigator.getUserMedia(
|
||
|
{ audio: true } // 只启用音频
|
||
|
, function (stream) {
|
||
|
that.microphone = stream;
|
||
|
that.recorders = new RecordRTC(that.microphone, {
|
||
|
type: 'audio',
|
||
|
recorderType: StereoAudioRecorder,
|
||
|
numberOfAudioChannels: 1,
|
||
|
bitsPerSecond:256000,
|
||
|
desiredSampRate: 16000
|
||
|
});
|
||
|
that.recorders.startRecording();
|
||
|
that.recordSending = true;
|
||
|
that.audioPlay = false;
|
||
|
that.inter = setInterval(() => {
|
||
|
if (that.seconds < 60) {
|
||
|
that.seconds++;
|
||
|
} else {
|
||
|
clearInterval(that.inter);
|
||
|
that.stopRecording();
|
||
|
}
|
||
|
}, 1000);
|
||
|
}, function (error) {
|
||
|
switch (error.code || error.name) {
|
||
|
case 'PERMISSION_DENIED':
|
||
|
case 'PermissionDeniedError':
|
||
|
that.$message({
|
||
|
showClose: true,
|
||
|
message: '用户拒绝提供信息',
|
||
|
type: 'error'
|
||
|
});
|
||
|
break;
|
||
|
case 'NOT_SUPPORTED_ERROR':
|
||
|
case 'NotSupportedError':
|
||
|
that.$message({
|
||
|
showClose: true,
|
||
|
message: '浏览器不支持硬件设备',
|
||
|
type: 'error'
|
||
|
});
|
||
|
break;
|
||
|
case 'MANDATORY_UNSATISFIED_ERROR':
|
||
|
case 'MandatoryUnsatisfiedError':
|
||
|
that.$message({
|
||
|
showClose: true,
|
||
|
message: '无法发现指定的硬件设备',
|
||
|
type: 'error'
|
||
|
});
|
||
|
break;
|
||
|
default:
|
||
|
that.$message({
|
||
|
showClose: true,
|
||
|
message: '无法打开麦克风',
|
||
|
type: 'error'
|
||
|
});
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
}
|
||
|
} else {
|
||
|
this.stopRecording(); // 发送语音
|
||
|
}
|
||
|
},
|
||
|
cancleRecording() {
|
||
|
if (this.microphone) {
|
||
|
clearInterval(this.inter);
|
||
|
this.seconds = 0;
|
||
|
this.microphone.stop();
|
||
|
this.microphone = null;
|
||
|
this.recordSending = false;
|
||
|
this.recorders = null;
|
||
|
}
|
||
|
},
|
||
|
// 停止录制 发送语音
|
||
|
stopRecording() {
|
||
|
this.audioPlay = true;
|
||
|
const that = this;
|
||
|
this.recorders.stopRecording(function(blobURL) {
|
||
|
clearInterval(that.inter);
|
||
|
that.seconds = 0;
|
||
|
const blob = that.recorders.getBlob();
|
||
|
const fd = new FormData();
|
||
|
fd.append('file', blob);
|
||
|
uploadAudioFiles(fd)
|
||
|
.then((data) => {
|
||
|
that.textContent = '';
|
||
|
that.audioPlay = false;
|
||
|
})
|
||
|
.catch(error => {
|
||
|
console.log(error);
|
||
|
that.$message.error('语音发送失败: ' + error.message);
|
||
|
that.audioPlay = false;
|
||
|
});
|
||
|
if (that.microphone) {
|
||
|
that.microphone.stop();
|
||
|
that.microphone = null;
|
||
|
that.recordSending = false;
|
||
|
that.recorders = null;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style lang="scss" scoped>
|
||
|
#record_progress_bar{
|
||
|
width: 40px;
|
||
|
height: 40px;
|
||
|
position: absolute;
|
||
|
left: 0;
|
||
|
top: 0;
|
||
|
border-radius: 50%;
|
||
|
}
|
||
|
.userHeader{margin-bottom: 2px;}
|
||
|
.userChatTime{font-size: 12px;display:inline-block;}
|
||
|
.chatContentInClass{
|
||
|
display: inline-block;
|
||
|
width: 100%;
|
||
|
}
|
||
|
.leftUser{
|
||
|
float: left;
|
||
|
margin-left: 10px;
|
||
|
margin-top: 10px;
|
||
|
display: inline-block;
|
||
|
}
|
||
|
.chat-box-footer-create{
|
||
|
font-size: 16px;
|
||
|
text-align: center;
|
||
|
color: #fff;
|
||
|
position: absolute;
|
||
|
right: 5px;
|
||
|
top: 6px;
|
||
|
line-height: 30px;
|
||
|
cursor: pointer;
|
||
|
width: 40px;
|
||
|
height: 40px;
|
||
|
border-radius: 50%;
|
||
|
background: green;
|
||
|
border: none;
|
||
|
display: flex;
|
||
|
justify-content: center;
|
||
|
align-items: center;
|
||
|
}
|
||
|
.chat-box-footer-send{
|
||
|
background: #F2F2F2;
|
||
|
right: 55px;
|
||
|
cursor: pointer;
|
||
|
.icon-yuyin{
|
||
|
color: #333;
|
||
|
font-size: 24px;
|
||
|
margin: 0;
|
||
|
}
|
||
|
&.active{
|
||
|
.icon-yuyin{
|
||
|
color: green;
|
||
|
}
|
||
|
}
|
||
|
.close_icon{
|
||
|
position: absolute;
|
||
|
top: -15px;
|
||
|
left: 11px;
|
||
|
font-size: 16px;
|
||
|
color: #333;
|
||
|
font-weight: 600;
|
||
|
}
|
||
|
}
|
||
|
</style>
|