使用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>

页面截图:

相关推荐
落霞的思绪1 小时前
苍穹外卖07——来单提醒和客户催单(涉及SpringTask、WebSocket协议、苍穹外卖跳过微信支付同时保证可以收到订单功能)
linux·前端·数据库
JINGWHALE12 小时前
设计模式 行为型 解释器模式(Interpreter Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·解释器模式
Kika写代码2 小时前
【基于轻量型架构的WEB开发】课程 实验一 mybatis操作 Java EE企业级应用开发教程 Spring+SpringMVC+MyBatis
前端·架构·mybatis
ネф̶-イω2 小时前
uniapp火车票样式
前端·css·uni-app
阳%2 小时前
Web前端界面开发
前端·html
桃园码工2 小时前
1_CSS3 边框 --[CSS3 进阶之路]
前端·javascript·css3
_未知_开摆2 小时前
CSS | CSS实现两栏布局(左边定宽 右边自适应,左右成比自适应)
java·前端·javascript·css·html·css3
baozhengw2 小时前
SpringBoot项目实战(41)--Beetl网页使用自定义函数获取新闻列表
java·前端·spring boot
秋夜Autumn2 小时前
Axios:前沿科技浪潮下的 HTTP 交互革新引擎
科技·http·axios·交互