使用vue3实现语音交互的前端页面

ops/2025/1/16 22:40:22/

代码地址:https://github.com/ZZD3627/my-third-vue.git

需求
1.前端实现录音并将音频传到通过http请求将音频传递到后端
2.基于后端识别的语音及后端返回的内容进行语音沟通
实现
1.使用MediaRecorder在前端使用录音功能
2.使用SpeechSynthesis实现将后端传来的文字进行播放

其中一个页面的代码:

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import SpeechSynthesis from '../components/SpeechSynthesis.vue'; // 导入语音合成组件let mediaRecorder: MediaRecorder | null = null;
let audioChunks: Blob[] = [];
const pureColor = ref('#FF66B2');  // 默认纯色const recording = ref(false);  // 录音状态
const isSending = ref(false);   // 发送音频状态
const transcript = ref('');     // 显示的识别结果
const robotReply = ref('');     // 显示机器人的回复
const userId = ref(''); // 用户ID
const responseText = ref(''); // 接口返回的文本内容// 语音播报函数
const playSpeech = (text: string) => {const utterance = new SpeechSynthesisUtterance(text);utterance.pitch = 1;utterance.rate = 1;window.speechSynthesis.speak(utterance);
};// 页面加载时播报欢迎语
onMounted(() => {const timestamp = new Date().getTime();  // 获取当前时间戳playSpeech("可爱的我,你不喜欢吗");userId.value = `default_user_${timestamp}`;
});// 启动或停止录音
const toggleRecording = () => {if (recording.value) {mediaRecorder?.stop();  // 停止录音} else {startRecording();  // 开始录音}
};// 开始录音
const startRecording = () => {navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {mediaRecorder = new MediaRecorder(stream);mediaRecorder.start();audioChunks = [];  // 清空音频数据mediaRecorder.ondataavailable = (event) => {audioChunks.push(event.data);  // 收集音频数据};mediaRecorder.onstop = () => {recording.value = false;isSending.value = true;sendAudio();  // 自动调用后台接口};recording.value = true;}).catch((error) => {console.error('获取麦克风权限失败', error);});
};// 发送音频数据到后端
const sendAudio = () => {const formData = new FormData();const audioBlob = new Blob(audioChunks, { type: 'audio/wav' });formData.append('user_id', userId.value); // 添加用户 IDformData.append('audio', audioBlob, 'recording.wav'); // 添加音频文件formData.append('scene', 'sweet_girl')fetch('http://127.0.0.1:5000/dialogue', {method: 'POST',body: formData,}).then(response => {if (!response.ok) {throw new Error('上传失败');}return response.json();}).then(data => {// 解析后端返回的数据transcript.value = `识别结果: ${data.transcript}`;robotReply.value = `机器人回复: ${data.reply}`;responseText.value = data.reply;  // 设置返回的机器人回复文本// 播放机器人回复的语音playSpeech(data.reply);}).catch((error) => {console.error('请求失败:', error);transcript.value = '请求失败,请检查后端服务!';});
};
</script><template><div><h1 :style="{ color: pureColor }"><Chrome v-model="pureColor" />我们的聊天会有点甜哦</h1><!-- 用户输入ID --><input :style="{ color: pureColor }" v-model="userId" type="text" placeholder="请输入用户 ID" /><!-- 录音按钮 --><button :style="{ color: pureColor }" @click="toggleRecording">{{ recording ? '停止录音' : '开始录音' }}</button><!-- 显示识别结果 --><div v-if="transcript"><p>{{ transcript }}</p></div><!-- 显示机器人的回复 --><div v-if="robotReply"><p>{{ robotReply }}</p></div><!-- 语音合成播放 --><SpeechSynthesis :text="responseText" :rate="1" :pitch="1" :selectedVoice="null" /></div>
</template><style scoped>
/* 添加页面样式 */
button {padding: 10px 15px;margin: 10px;font-size: 16px;cursor: pointer;
}input {padding: 8px;font-size: 16px;margin: 10px;width: 100%;max-width: 300px;
}
</style>

页面截图:
在这里插入图片描述


http://www.ppmy.cn/ops/150654.html

相关文章

深度解析 React 中 setState 的原理:同步与异步的交织

在 React 框架的核心机制里&#xff0c;setState是实现动态交互与数据驱动视图更新的关键枢纽。深入理解setState的工作原理&#xff0c;尤其是其同步与异步的特性&#xff0c;对于编写高效、稳定且可预测的 React 应用至关重要。 一、setState 的基础认知 在 React 组件中&a…

Vue.js devtools插件点击Root失效或不显示数据甚至没有Root的解决方法

文章目录 一、问题描述二、原因分析三、解决方法 一、问题描述 在vue开发者工具devTools插件中&#xff0c;有时候会遇到没有Root或点击Root失效等问题。 正常情况如下图&#xff1a; Vue工具devtools没有root 二、原因分析 源码如下&#xff1a; 上图中的示例是name字…

C51交通控制系统的设计与实现

实验要求&#xff1a; 本题目拟设计一个工作在十字路口的交通信号灯控制系统&#xff0c;设东西方向为主干道A&#xff0c;南北方向为辅助干道B。要求&#xff1a;&#xff08;1&#xff09;用发光二极管模拟交通灯信号&#xff1b;&#xff08;2&#xff09;灵活控制主、辅干…

插入排序与霍纳规则

参考书&#xff1a;机械工业出版社《算法导论》第二版 插入排序 插入排序来自扑克牌的灵感&#xff0c;每次抽牌都要从洗好的牌堆里抽一张&#xff0c;然后与自己现有的牌比较&#xff0c;插入到合适的位置 算法步骤 由此可以看到&#xff0c;插入排序时对元素进行这样一种操…

【蓝桥杯】Python算法——快速幂

零、前言 距离25年蓝桥杯还有大概三个月时间&#xff0c;接下来重点应该会放在蓝桥杯备考方向&#xff0c;一起努力&#xff0c;一起加油 一、快速幂 如何快速求 a b p a^bp abp&#xff1f;如果直接循环aaa…毫无疑问时间复杂度是很大的&#xff0c;那么怎么降低计算量呢&…

docker访问权限问题

docker ps -a时看到错误信息中包含permission denied时&#xff0c;多半时权限问题 解决办法 首先查看当前存在的用户组 cat /etc/group 若存在docker用户组,则可在输出中找到docker字段 ... docker:x:999: ...若不存在docker用户组,则需要使用以下命令添加docker用户组 …

docker mysql5.7如何设置不区分大小写

环境 docker部署&#xff0c;镜像是5.7&#xff0c;操作系统是centos 操作方式 mysql 配置文件是放在 /etc/mysql/mysql.conf.d/mysqld.cnf&#xff0c; vim /etc/mysql/mysql.conf.d/mysqld.cnf lower_case_table_names1 重启mysql容器 验证 SHOW VARIABLES LIKE low…

分类统计字符个数(PTA)C语言

本题要求实现一个函数&#xff0c;统计给定字符串中英文字母、空格或回车、数字字符和其他字符的个数。 函数接口定义&#xff1a; void StringCount( char s[] ); 其中 char s[] 是用户传入的字符串。函数StringCount须在一行内按照 letter 英文字母个数, blank 空格或回…