智能面试——录音及播放下载js-audio-recorder — post请求,formdata传参

本文主要是介绍智能面试——录音及播放下载js-audio-recorder — post请求,formdata传参,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

录音插件 js-audio-recorder

image.png

bug:本地调试调取不起来麦克风

  • 浏览器配置安全域名 chrome://flags/
  • Insecure origins treated as secure
  • 输入域名即可
  • 电脑需要连接上耳机
<template><div class="BaseRecorder"><div class="BaseRecorder-record"><el-button @click="startRecorder()">开始录音</el-button><el-button @click="pauseRecorder()">暂停录音</el-button><el-button @click="resumeRecorder()">继续录音</el-button><el-button @click="stopRecorder()">结束录音</el-button></div><div class="BaseRecorder-play"><el-button @click="playRecorder()">录音播放</el-button><el-button @click="pausePlayRecorder()">暂停录音播放</el-button><el-button @click="resumePlayRecorder()">恢复录音播放</el-button><el-button @click="stopPlayRecorder()">停止录音播放</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"><canvas ref="record"></canvas><canvas ref="play"></canvas></div></div>
</template><script>
import Recorder from "js-audio-recorder";export default {name: "home",data() {return {recorder: null,// 波浪图-录音drawRecordId: null,// 波浪图-播放drawPlayId: null,};},mounted() {this.init();},methods: {// 初始化init() {this.recorder = new Recorder({// 采样位数,支持 8 或 16,默认是16sampleBits: 16,// 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值sampleRate: 48000,// 声道,支持 1 或 2, 默认是1numChannels: 1,// 是否边录边转换,默认是falsecompiling: false,});},// 开始录音startRecorder() {this.recorder.start().then(() => {console.log("开始录音", this.recorder);this.drawRecord();this.recorder.onprogress = (params) => {console.log(params);// 此处控制数据的收集频率if (this.recorder.config.compiling) {console.log("音频总数据:", params.data);}};// 定时获取录音的数据并播放this.recorder.config.compiling &&(playTimer = setInterval(() => {let newData = this.recorder.getNextData();if (!newData.length) {return;}let byteLength = newData[0].byteLength;let buffer = new ArrayBuffer(newData.length * byteLength);let dataView = new DataView(buffer);// 数据合并for (let i = 0, iLen = newData.length; i < iLen; ++i) {for (let j = 0, jLen = newData[i].byteLength; j < jLen; ++j) {dataView.setInt8(i * byteLength + j, newData[i].getInt8(j));}}// 将录音数据转成WAV格式,并播放let a = encodeWAV(dataView,config.sampleRate,config.sampleRate,config.numChannels,config.sampleBits);let blob = new Blob([a], { type: "audio/wav" });blob.arrayBuffer().then((arraybuffer) => {console.log(arraybuffer);// Player.play(arraybuffer);});}, 3000));},(error) => {// 出错了console.log(`${error.name} : ${error.message}`);});},// 继续录音resumeRecorder() {this.recorder.resume();},// 暂停录音pauseRecorder() {this.recorder.pause();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 结束录音stopRecorder() {this.recorder.stop();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 录音播放playRecorder() {this.recorder.play();this.drawPlay(); // 绘制波浪图},// 暂停录音播放pausePlayRecorder() {this.recorder.pausePlay();},// 恢复录音播放resumePlayRecorder() {this.recorder.resumePlay();this.drawPlay(); // 绘制波浪图},// 停止录音播放stopPlayRecorder() {this.recorder.stopPlay();},// 销毁录音destroyRecorder() {this.recorder.destroy().then(() => {this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;this.drawPlayId && cancelAnimationFrame(this.drawPlayId);this.drawPlayId = null;this.recorder = null;});},/***  下载录音文件* */// 下载pcmdownPCM() {console.log("pcm: ", this.recorder.getPCMBlob());// 这里传参进去的时文件名this.recorder.downloadPCM("新文件");},// 下载wavdownWAV() {console.log("wav: ", this.recorder.getWAVBlob());// 这里传参进去的时文件名this.recorder.downloadWAV("新文件");},/*** 绘制波浪图-录音* */drawRecord() {this.drawRecordId = requestAnimationFrame(this.drawRecord);this.drawWave({canvas: this.$refs.record,dataArray: this.recorder.getRecordAnalyseData(),bgcolor: "rgb(255, 128, 200)",lineWidth: 1,lineColor: "rgb(0, 128, 255)",});},/*** 绘制波浪图-播放* */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;// 一个点占多少位置,共有bufferLength个点要绘制const sliceWidth = canvas.width / bufferLength;// 绘制点的x轴位置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 {& > div {margin: 20px 0;}&-wave {canvas {width: 100%;border: 1px solid #ccc;}}
}
</style>

智能面试页面

image.png

<template><div class="flex1 w100 h100 bg"><div style="width: 300px" class="bg-white h100 flex-column center"><div class="blue size-30 mb-60">Java面试专场</div><div class="size-26">张三</div><div class="gray-2 mt-20 mb-100">18378562388</div><el-button type="success" round @click="start()">开始面试</el-button></div><div class="flex-1 h100 over-hidden"><divclass="h100 w65 flex1 flex-column"style="margin: 0 auto; min-width: 800px"><div class="flex-1 scroll w100 pt-30"><divv-for="(item, index) in list.filter((item) => item.show)":key="index"class="mb-30"><div class="flex_l mb-30"><i class="el-icon-question size-28 blue mr-10"></i><div class="">{{ item.topic }}</div></div><div class="flex_l" v-if="item.file"><el-avatarclass="mr-10"size="small"src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"></el-avatar><el-card class="flex-1"> 语音已发送 </el-card></div><div class="flex_l" v-if="item.answer"><el-avatarclass="mr-10"size="small"src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"></el-avatar><el-card class="flex-1">{{ item.answer }}</el-card></div></div></div><div class="w100 flex1 pb-30"><el-inputtype="textarea"placeholder="请输入内容"v-model="textarea"maxlength="500"show-word-limit:autosize="{ minRows: 4 }"></el-input><div class="w10 text-center"><el-buttontype="success"icon="el-icon-microphone"circleclass="size-16 mb-10"@click="startRecorder":disabled="disabled"></el-button><el-button:disabled="disabled"type="primary"round@click="submit(1)">提交</el-button></div></div></div></div><!-- 结果 --><el-dialog:close-on-click-modal="false":close-on-press-escape="false"title="面试结果":visible.sync="centerDialogVisible"width="600px"center:show-close="false"style="top: 16vh"><el-result:icon="score >= 80 ? 'success' : score >= 60 ? 'warning' : 'error'":title="score >= 80 ? '优秀' : score >= 60 ? '良好' : '不合格'"subTitle="面试结果"><template slot="extra"><el-button type="primary" size="medium" @click="back">返回</el-button></template></el-result></el-dialog><!-- 录音 --><el-dialog:close-on-click-modal="false":close-on-press-escape="false"title="正在录音...":visible.sync="audioVisible"width="600px"center:show-close="false"style="top: 16vh"><div class="mb-20 size-18" v-if="list[index]">{{ list[index].topic }}</div><div class="BaseRecorder-wave"><canvas ref="record"></canvas><!-- <canvas ref="play"></canvas> --></div><div class="center mt-20"><el-button type="primary" size="medium" @click="submit(2)">提交</el-button></div></el-dialog></div><!-- <div class="BaseRecorder"><div class="BaseRecorder-record"><el-button @click="startRecorder()">开始录音</el-button><el-button @click="pauseRecorder()">暂停录音</el-button><el-button @click="resumeRecorder()">继续录音</el-button><el-button @click="stopRecorder()">结束录音</el-button></div><div class="BaseRecorder-play"><el-button @click="playRecorder()">录音播放</el-button><el-button @click="pausePlayRecorder()">暂停录音播放</el-button><el-button @click="resumePlayRecorder()">恢复录音播放</el-button><el-button @click="stopPlayRecorder()">停止录音播放</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"><canvas ref="record"></canvas><canvas ref="play"></canvas></div></div> -->
</template><script>
import Recorder from "js-audio-recorder";
// import { subText, subAudio } from "../api/test.js";
import axios from "axios";
export default {name: "home",data() {return {index: null,disabled: true,list: [{topic: "题目1:1+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目2:2+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目3:白日依山尽的下一句是什么?",show: false,answer: "",result: "",file: "",},],textarea: "",config: {headers: {"Content-Type": "multipart/form-data",},},centerDialogVisible: false, //结果弹窗score: "", //得分audioVisible: false, //录音弹窗recorder: null,// 波浪图-录音drawRecordId: null,// 波浪图-播放drawPlayId: null,};},mounted() {this.init();},beforeDestroy() {this.destroyRecorder();},methods: {start(i = 0) {this.index = i;this.list[this.index].show = true;this.disabled = false;},// type 1 文字  2 语音async submit(type) {if (type == 1) {if (!this.textarea.trim()) {this.$message({message: "请输入答案",type: "warning",});return;}this.list[this.index].answer = this.textarea;this.disabled = true;this.textarea = "";const formData = new FormData();formData.append("topic", this.list[this.index].topic);formData.append("answer", this.list[this.index].answer);const { data } = await axios.post("/ququ/recognize-text",formData,this.config);console.log(data.result, 99);this.list[this.index].result = data.result;this.index += 1;if (this.index == this.list.length) {this.centerDialogVisible = true;this.index = null;console.log(this.list, 88);this.score =(this.list.filter((item) => item.result == "对").length * 100) /this.list.length;} else {this.start(this.index);}} else {this.stopRecorder();this.audioVisible = false;this.list[this.index].file = this.recorder.getWAVBlob();this.disabled = true;const formData = new FormData();formData.append("topic", this.list[this.index].topic);formData.append("file", this.list[this.index].file);const { data } = await axios.post("/ququ/recognize-video",formData,this.config);console.log(data.result, 99);this.list[this.index].result = data.result;this.index += 1;if (this.index == this.list.length) {this.centerDialogVisible = true;this.index = null;console.log(this.list, 88);this.score =(this.list.filter((item) => item.result == "对").length * 100) /this.list.length;} else {this.start(this.index);}}},back() {this.centerDialogVisible = false;this.list = [{topic: "题目1:1+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目2:2+2等于几?",show: false,answer: "",result: "",file: "",},{topic: "题目3:白日依山尽的下一句是什么?",show: false,answer: "",result: "",file: "",},];},// 初始化init() {this.recorder = new Recorder({// 采样位数,支持 8 或 16,默认是16sampleBits: 16,// 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值sampleRate: 48000,// 声道,支持 1 或 2, 默认是1numChannels: 1,// 是否边录边转换,默认是falsecompiling: false,});},// 开始录音startRecorder() {this.recorder.start().then(() => {console.log("开始录音", this.recorder);this.audioVisible = true;this.drawRecord();this.recorder.onprogress = (params) => {console.log(params);// 此处控制数据的收集频率if (this.recorder.config.compiling) {console.log("音频总数据:", params.data);}};// 定时获取录音的数据并播放this.recorder.config.compiling &&(playTimer = setInterval(() => {let newData = this.recorder.getNextData();if (!newData.length) {return;}let byteLength = newData[0].byteLength;let buffer = new ArrayBuffer(newData.length * byteLength);let dataView = new DataView(buffer);// 数据合并for (let i = 0, iLen = newData.length; i < iLen; ++i) {for (let j = 0, jLen = newData[i].byteLength; j < jLen; ++j) {dataView.setInt8(i * byteLength + j, newData[i].getInt8(j));}}// 将录音数据转成WAV格式,并播放let a = encodeWAV(dataView,config.sampleRate,config.sampleRate,config.numChannels,config.sampleBits);let blob = new Blob([a], { type: "audio/wav" });blob.arrayBuffer().then((arraybuffer) => {console.log(arraybuffer);// Player.play(arraybuffer);});}, 3000));},(error) => {// 出错了console.log(`${error.name} : ${error.message}`);});},// 继续录音resumeRecorder() {this.recorder.resume();},// 暂停录音pauseRecorder() {this.recorder.pause();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 结束录音stopRecorder() {this.recorder.stop();this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;},// 录音播放playRecorder() {this.recorder.play();this.drawPlay(); // 绘制波浪图},// 暂停录音播放pausePlayRecorder() {this.recorder.pausePlay();},// 恢复录音播放resumePlayRecorder() {this.recorder.resumePlay();this.drawPlay(); // 绘制波浪图},// 停止录音播放stopPlayRecorder() {this.recorder.stopPlay();},// 销毁录音destroyRecorder() {this.recorder.destroy().then(() => {this.drawRecordId && cancelAnimationFrame(this.drawRecordId);this.drawRecordId = null;this.drawPlayId && cancelAnimationFrame(this.drawPlayId);this.drawPlayId = null;this.recorder = null;});},/***  下载录音文件* */// 下载pcmdownPCM() {console.log("pcm: ", this.recorder.getPCMBlob());// 这里传参进去的时文件名this.recorder.downloadPCM("新文件");},// 下载wavdownWAV() {console.log("wav: ", this.recorder.getWAVBlob());// 这里传参进去的时文件名this.recorder.downloadWAV("新文件");},/*** 绘制波浪图-录音* */drawRecord() {this.drawRecordId = requestAnimationFrame(this.drawRecord);this.drawWave({canvas: this.$refs.record,dataArray: this.recorder.getRecordAnalyseData(),bgcolor: "#a8e1fc",lineWidth: 1,lineColor: "rgb(255, 128, 200)",});},/*** 绘制波浪图-播放* */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;// 一个点占多少位置,共有bufferLength个点要绘制const sliceWidth = canvas.width / bufferLength;// 绘制点的x轴位置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 {& > div {margin: 20px 0;}&-wave {canvas {width: 100%;border: 1px solid #ccc;}}
}
</style>

post请求,formdata传参

const formData = new FormData();
formData.append("topic", this.list[this.index].topic);
formData.append("answer", this.list[this.index].answer);
const { data } = await axios.post("/ququ/recognize-text",formData,{headers: {"Content-Type": "multipart/form-data",},});
console.log(data.result, 99);

这篇关于智能面试——录音及播放下载js-audio-recorder — post请求,formdata传参的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/891967

相关文章

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

SpringBoot中Get请求和POST请求接收参数示例详解

《SpringBoot中Get请求和POST请求接收参数示例详解》文章详细介绍了SpringBoot中Get请求和POST请求的参数接收方式,包括方法形参接收参数、实体类接收参数、HttpServle... 目录1、Get请求1.1 方法形参接收参数 这种方式一般适用参数比较少的情况,并且前后端参数名称必须

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

流媒体平台/视频监控/安防视频汇聚EasyCVR播放暂停后视频画面黑屏是什么原因?

视频智能分析/视频监控/安防监控综合管理系统EasyCVR视频汇聚融合平台,是TSINGSEE青犀视频垂直深耕音视频流媒体技术、AI智能技术领域的杰出成果。该平台以其强大的视频处理、汇聚与融合能力,在构建全栈视频监控系统中展现出了独特的优势。视频监控管理系统EasyCVR平台内置了强大的视频解码、转码、压缩等技术,能够处理多种视频流格式,并以多种格式(RTMP、RTSP、HTTP-FLV、WebS

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/