实现录音功能/语音录入案例
![在这里插入图片描述](https://img-blog.csdnimg.cn/2c967a3f13a2442897fdb7ce12a97bde.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5bCP5pa55pa55ZCW,size_13,color_FFFFFF,t_70,g_se,x_16)
本案例是弹框录音录入 可以直接作为录音组件使用
使用插件js-audio-recorder可以得到三种录音数据,pcm,wav,mp3 三种数据流
官网api入口.
tip:使用js-audio-recorder报浏览器不支持getUserMedia
因为浏览器安全限制只支持file:,https:,http://localhost,
不能使用http:ip
修改方法在最底下
安装js-audio-recorder
cnpm i js-audio-recorder --s
引入到所需页面
import Recorder from "js-audio-recorder";
<style scoped>
.pop {
padding: 0px;
}
.pop .popper__arrow {
display: none;
}
.tittle {
/* display: inline-block; */
color: #ffffff;
font-weight: bold;
font-family: "微软雅黑";
margin-left: 14px;
font-size: 20px;
/* height: 40px; */
/* line-height: 40px; */
}
.content {
border: none;
/* text-indent: 2em; */
margin: 14px auto;
width: 90%;
font-family: "微软雅黑";
color: rgb(112, 112, 112);
min-height: 340px !important;
font-size: 18px;
overflow-x: hidden;
overflow-y: scroll;
}
.content::-webkit-scrollbar {
display: none;
}
.top {
height: 60px;
line-height: 60px;
background-color: #2e4e8f;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px 5px 0 0;
}
.top .main {
height: 40px;
width: 90%;
display: flex;
align-items: center;
}
.top .img_c {
display: inline-block;
height: 40px;
width: 40px;
text-align: center;
background-color: #ffffff;
border-radius: 50%;
}
.top .img_c img {
height: 30px;
}
.imgs {
/* display: inline-block; */
height: 40px;
width: 40px;
text-align: center;
background-color: #2e4e8f;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
cursor: pointer;
}
.imgs img {
height: 30px;
}
.bottom .el-col-8 {
height: 40px;
text-align: center;
display: flex;
justify-content: center;
align-content: center;
line-height: 40px;
}
.bottom {
margin: 10px 0;
}
.trans {
height: 150px;
background-color: rgb(224, 224, 224);
border-radius: 4px;
margin: 20px 0;
position: relative;
}
.transvalue{
width: 100%;
height: 90%;
overflow-x: hidden;
overflow-y: scroll;
}
.transvalue::-webkit-scrollbar {
display: none;
}
.el-textarea {
height: 100%;
}
.el-textarea__inner {
height: 100%;
background-color: rgb(224, 224, 224);
}
.txtimg {
width: 18px;
}
.el-col-12 {
height: 40px;
line-height: 40px;
}
.tansimg {
height: 40px;
text-align: center;
line-height: 40px;
display: flex;
align-items: center;
justify-content: center;
}
.tansimg img {
height: 20px;
}
.cleartext {
display: inline-block;
width: 25px;
height: 25px;
position: absolute;
bottom: 5px;
right: 25px;
}
.cleartext img {
width: 25px;
}
.close {
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
margin-left: 100px;
cursor: pointer;
}
.close img {
width: 20px;
}
.bottom_text {
font-size: 16px;
font-weight: 500;
cursor: pointer;
}
.circle-border {
width: 40px;
height: 40px;
padding: 3px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
background: rgb(63,249,220);
background: linear-gradient(0deg, rgba(63,249,220,0.1) 33%, rgba(63,249,220,1) 100%);
animation: spin .8s linear 0s infinite;
cursor: pointer;
}
.circle-core {
width: 40px;
height: 40px;
background-color: #2e4e8f;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
animation: spins .8s linear 0s infinite;
}
@keyframes spin {
from {
transform: rotate(0);
}
to{
transform: rotate(359deg);
}
}
@keyframes spins {
from {
transform: rotate(359deg);
}
to{
transform: rotate(0);
}
}
.warn{
font-size:12px;
color: red;
cursor: pointer;
}
</style>
<template>
<div class="home">
<el-popover
placement="bottom"
popper-class="pop"
width="300"
trigger="manual"
v-model="transvoice"
>
<el-button slot="reference" @click="transvoice = !transvoice"
>语音识别</el-button
>
<div>
<div class="top">
<div class="main">
<div class="img_c"><img src="./img/recorder.png" alt="" /> </div>
<span class="tittle">语音输入</span>
<span class="close" @click="closevoice()"
><img src="./img/close.png" alt=""
/></span>
</div>
</div>
<div class="content" id="content">
<p v-for="(item, index) in textarea" :key="index">{{ item }}</p>
</div>
<div class="bottom">
<el-row>
<el-col :span="8">
<span @click="cleartext" class="bottom_text" v-if="isShow"
>清空</span
>
</el-col>
<el-col :span="8">
<div class="imgs" @click="handleStart" v-if="isRecorder">
<img src="./img/recorder1.png" alt="" />
</div>
<div class="circle-border" @click="handleStart" v-else>
<div class="circle-core"><img style="width: 80%;height: 80%;" src="./img/01.png" alt=""></div>
</div>
<!-- </el-popover> -->
</el-col>
<el-col :span="8" v-clipboard:copy="textarea">
<span class="bottom_text" v-if="isShow">复制</span>
</el-col>
</el-row>
</div>
</div>
</el-popover>
</div>
</template>
<script>
import Recorder from "js-audio-recorder";
import $ from "jquery";
import { post, upload } from "@/request/gAjax";
import ClipboardJS from "clipboard";
import md5 from "js-md5";
export default {
name: "home",
data() {
return {
textarea: [],
isStart: false,
visible: false,
transvisible: false,
options: [],
formData: "",
filename: "",
textvalue: "",
isShow: false,
totaldata: "",
transvoice: false,
index: 0,
isRecorder:true,
isShowto:false,
};
},
created() {
},
methods: {
closevoice() {
console.log("123");
this.transvoice = false;
},
closetext() {
this.transvisible = false;
},
cleartextarea() {
this.lantextarea = "";
this.textvalue = "";
},
onCopy() {
console.log("复制成功");
},
cleartext() {
this.textarea=[]
// this.textarea.push("请录入");
},
handleStart() {
if (this.isStart == false) {
this.recorder = new Recorder();
Recorder.getPermission().then(
() => {
console.log("开始录音");
this.recorder.start();
// 开始录音
this.isStart = !this.isStart;
this.visible = !this.visible;
this.isRecorder=!this.isRecorder
},
(error) => {
alert(error.message);
console.log(`${error.name} : ${error.message}`);
}
);
} else {
this.isStart = !this.isStart;
this.visible = !this.visible;
this.isRecorder=!this.isRecorder
this.uploadRecord();
}
},
handlePause() {
console.log("暂停录音");
this.recorder.pause(); // 暂停录音
},
handleResume() {
console.log("恢复录音");
this.recorder.resume(); // 恢复录音
},
handleStop() {
console.log("停止录音");
this.recorder.stop(); // 停止录音
},
handlePlay() {
console.log("播放录音");
this.recorder.play(); // 播放录音
// 播放时长
this.timer = setInterval(() => {
try {
this.playTime = this.recorder.getPlayTime();
} catch (error) {
this.timer = null;
}
}, 100);
},
handlePausePlay() {
console.log("暂停播放");
this.recorder.pausePlay(); // 暂停播放
// 播放时长
this.playTime = this.recorder.getPlayTime();
this.time = null;
},
handleResumePlay() {
console.log("恢复播放");
this.recorder.resumePlay(); // 恢复播放
// 播放时长
this.timer = setInterval(() => {
try {
this.playTime = this.recorder.getPlayTime();
} catch (error) {
this.timer = null;
}
}, 100);
},
handleStopPlay() {
console.log("停止播放");
this.recorder.stopPlay(); // 停止播放
// 播放时长
this.playTime = this.recorder.getPlayTime();
this.timer = null;
},
handleDestroy() {
console.log("销毁实例");
this.recorder.destroy(); // 毁实例
this.timer = null;
},
uploadRecord() {
if (this.recorder == null || this.recorder.duration === 0) {
this.$Message.error("请先录音");
return false;
}
this.recorder.pause(); // 暂停录音
this.timer = null;
console.log("上传录音"); // 上传录音
this.formData = new FormData();
var blob = this.recorder.getWAVBlob(); //获取wav格式音频数据
console.log(blob);
//此处获取到blob对象后需要设置fileName满足当前项目上传需求,其它项目可直接传把blob作为file塞入formData
var newbolb = new Blob([blob], { type: "audio/wav" });
this.formData.append("file", blob);
var _this = this;
//此处调用语音转文字接口(这里是自己封装的接口 根据自己所需修改)
upload("*********", this.formData).then((res) => {
_this.textarea.push(res.data);
//将返回文字 显示到页面
_this.isShow = true;
$("#content").scrollTop($("#content").scrollHeight);
//滚动到最底部
});
},
},
};
</script>
修改方法
1.可以手动修改浏览器
地址栏输入:chrome://flags/#unsafely-treat-insecure-origin-as-secure
2.如果上线项目有域名的话可以不用修改,如果没有域名让后端或者运维同学将项目和接口部署为https即可