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

代码地址: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); // 添加用户 ID
  formData.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>

页面截图:

相关推荐
会豪3 分钟前
工业仿真(simulation)--前端(五)--标尺,刻度尺
前端
会豪4 分钟前
工业仿真(simulation)--前端(四)--画布编辑(2)
前端
an__ya__6 分钟前
Vue数据响应式reactive
前端·javascript·vue.js
苦逼的搬砖工9 分钟前
Flutter UI Components:闲来无事,设计整理了这几年来使用的UI组件库
前端·flutter
想买Rolex和Supra的凯美瑞车主11 分钟前
Taro + Vite 开发中 fs.allow 配置问题分析与解决
前端
ruanCat12 分钟前
使用 vite 的 base 命令行参数来解决项目部署在 github page 的路径问题
前端·github
Codebee17 分钟前
使用Qoder 改造前端UI/UE升级改造实践:从传统界面到现代化体验的华丽蜕变
前端·人工智能
叫我詹躲躲21 分钟前
开发提速?Vue3模板隐藏技巧来了
前端·vue.js·ai编程
华仔啊21 分钟前
面试都被问懵了?CSS 的 flex:1 和 flex:auto 真不是一回事!90%的人都搞错了
前端·javascript
前端康师傅23 分钟前
JavaScript 函数详解
前端·javascript