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

页面截图:

相关推荐
qq_2518364573 分钟前
基于java Web网络订餐系统设计与实现 源码文档
java·开发语言·前端
飞天狗11132 分钟前
零基础JavaWeb入门——第2课:让网页“活”起来 —— JSP是什么?
java·开发语言·前端·后端·web
回忆2012初秋1 小时前
【Nginx】优雅地走进高性能 Web 服务器世界(1)
服务器·前端·nginx
kyriewen1 小时前
Claude Code Token 烧太快?实测 5 招,把月费从 250 美金砍到 50 美金
前端·ai编程·claude
weixin_394758032 小时前
CRMEB Pro 商品字段二开:为什么加一个字段会牵动 SKU、缓存和前端展示?
前端·缓存
IT_陈寒2 小时前
Python的pickle让我半夜加班,这破玩意儿太坑了
前端·人工智能·后端
qq_422152573 小时前
图片格式转换工具怎么选?JPEG、PNG、WebP、AVIF 格式对比与在线转换方案实测
前端
xiaofeichaichai3 小时前
ES 新特性九年速览:从 ES2016 到 ES2024
前端·javascript·es6
2401_834636993 小时前
Keepalived + LVS (DR) + Nginx + NFS 高可用 Web 集群部署实战手册
前端·nginx·lvs