当前位置: 首页 > wzjs >正文

网页设计技术培训教程宁波seo网络推广

网页设计技术培训教程,宁波seo网络推广,携程做网站的流程,典型网站建设实例精讲语音交互大模型的功能越来越受到重视。讯飞语音听写(流式版)为开发者提供了一种高效、准确的语音识别解决方案。本文将基于 Home.vue、iat_xfyun.js 和 sparkChat.js 这三个文档,详细阐述讯飞语音听写(流式版)的开发逻…

语音交互大模型的功能越来越受到重视。讯飞语音听写(流式版)为开发者提供了一种高效、准确的语音识别解决方案。本文将基于 Home.vueiat_xfyun.jssparkChat.js 这三个文档,详细阐述讯飞语音听写(流式版)的开发逻辑、涉及的代码,并提供开发说明、文件结构和分析。

开发说明

页面示例

在这里插入图片描述

功能概述

讯飞语音听写(流式版)允许用户通过麦克风输入语音,实时将语音转换为文字。在本项目中,该功能主要应用于聊天界面,用户可以通过语音输入问题,系统将语音转换为文字后发送给后端进行处理。

环境配置

  • 开发环境:Vue.js 3.x、Vite
  • 依赖库@muguilin/xf-voice-dictation 用于实现讯飞语音听写功能

配置步骤

  1. 安装依赖:在项目根目录下执行以下命令安装 @muguilin/xf-voice-dictation
npm install @muguilin/xf-voice-dictation
  1. 配置讯飞 API 信息:在 iat_xfyun.js 文件中,配置讯飞语音听写的 API 信息,包括 APPIDAPIKeyAPISecret
// 讯飞语音识别配置
const xfConfig = {APPID: '6acb09d5',APIKey: '36fb21a7095db0bb***',APISecret: 'MmNhN2VkY2JkMj****',host: 'iat-api.xfyun.cn',path: '/v2/iat'
}

文件结构

主要文件

  • Home.vue:聊天界面组件,包含语音输入按钮和语音识别结果显示区域。
  • iat_xfyun.js:封装讯飞语音听写功能的工具文件,提供创建语音识别实例的工厂函数。
  • sparkChat.js:与后端进行 WebSocket 通信的工具文件,负责将语音识别结果发送给后端。

文件关系

Home.vue 组件引入 iat_xfyun.js 中创建的语音识别实例,当用户点击语音输入按钮时,调用语音识别实例的 start 方法开始录音。识别结果通过 onTextChange 回调函数返回,将结果显示在界面上,并通过 sparkChat.js 发送给后端。

开发逻辑

1. 创建语音识别实例

iat_xfyun.js 文件中,创建一个工厂函数 createVoiceInstance,用于创建语音识别实例。该函数接受一个回调对象作为参数,包含 onStatusChangeonTextChangeonError 三个回调函数。

文件 iat_xfyun.js
import { XfVoiceDictation } from '@muguilin/xf-voice-dictation'// 讯飞语音识别配置
const xfConfig = {APPID: '6acb09d5',APIKey: '36fb21a7095db0bb***',APISecret: 'MmNhN2VkY2JkMj****',host: 'iat-api.xfyun.cn',path: '/v2/iat'
}// 创建语音识别实例的工厂函数
export const createVoiceInstance = (callbacks) => {let instance = new XfVoiceDictation({...xfConfig,    onWillStatusChange: (oldStatus, newStatus) => {console.log('语音识别状态变更:', { oldStatus, newStatus })          },onTextChange: (text) => {    console.log('语音识别结果:', {text: text,textLength: text ? text.length : 0 })callbacks.onTextChange?.(text)},onError: (error) => {console.error('语音识别错误:', error)callbacks.onError?.(error)}})return instance
}

2. 在 Home.vue 中使用语音识别实例

Home.vue 组件中,引入 createVoiceInstance 函数,创建语音识别实例,并绑定到语音输入按钮的点击事件上。

 
<template><!-- ... 其他代码 ... --><div class="input-bar"><input v-model="inputMessage" type="text" class="apple-input" placeholder="输入咨询内容(如:居住证续签)"@keypress.enter="sendInputMessage(false)" autocapitalize="none" autocomplete="off" spellcheck="false"><svg class="input-icon" :class="{ 'recording': isRecording }" viewBox="0 0 24 24" aria-label="语音麦图标"@mousedown="checkLoginBeforeAction(startRecording)" @mouseup="checkLoginBeforeAction(stopBtnRecording)"><pathd="M12 15c1.65 0 3-1.35 3-3V6c0-1.65-1.35-3-3-3S9 4.35 9 6v6c0 1.65 1.35 3 3 3zm5.91-4.56c.08.33.13.67.13 1.01 0 2.49-2.01 4.5-4.5 4.5H13v2.5h2c.55 0 1 .45 1 1s-.45 1-1 1H8c-.55 0-1-.45-1-1s.45-1 1-1h2V16H9.59c-2.49 0-4.5-2.01-4.5-4.5 0-.34.05-.68.13-1.01A2.999 2.999 0 0 1 3 9c0-1.66 1.34-3 3-3h3V4c0-.55.45-1 1-1s1 .45 1 1v2h3c1.66 0 3 1.34 3 3 0 1.28-.81 2.36-1.9 2.73l.01-.17z" /></svg><div v-show="isRecording" class="recording-tip">正在录音...<span class="recording-dots"></span></div><svg class="input-icon sendTxtMsg" viewBox="0 0 24 24" aria-label="发送图标"   @click="sendInputMessage(true)"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" /></svg></div><!-- ... 其他代码 ... -->
</template><script setup>
import { ref, onBeforeUnmount } from 'vue'
import { createVoiceInstance } from '../utils/voice/iat_xfyun'
import { ElMessage } from 'element-plus'const isRecording = ref(false)
const recognizedText = ref('')
let times = null// 创建语音识别实例
const xfVoice = createVoiceInstance({onTextChange: (text) => {if (text && text.length > 0) {const currentTime = Date.now();// 防止操作过于频繁if (currentTime - lastCallTime.value < 3000) {//只要无这段代码message.value.push()会加入一条除了本身语言以外只多了问号或一个点的消息//如:你好 //message数组内会有两条消息://1.你好//2.你好?//如果有这段代码,message数组内只会有一条消息:console.log('操作过于频繁,请等待10秒后再试');                 return;}lastCallTime.value = currentTime;clearTimeout(times);             xfVoice.stop();// 发送识别结果到服务器inputMessage.value = text;user_message.value = text;  tmpMsgArr.value = [];sendInputMessage(true);}},onError: (error) => {if (error.includes('WebSocket')) {ElMessage.error('语音识别连接失败,请检查网络');} else if (error.includes('authorization')) {ElMessage.error('语音识别授权失败,请检查配置');} else {ElMessage.error('语音识别发生错误:' + error);}isRecording.value = false;}
});const startRecording = () => {if (!isRecording.value) {recognizedText.value = '';xfVoice.start();isRecording.value = true;}
}const stopBtnRecording = () => {isRecording.value = false;xfVoice.stop();
}onBeforeUnmount(() => {clearTimeout(times);if (isRecording.value) {xfVoice.stop();}
});
</script>

3. 处理语音识别结果

onTextChange 回调函数中,处理语音识别结果。当识别到有效文本时,停止录音,并将识别结果发送给后端。

4. 错误处理

onError 回调函数中,处理语音识别过程中可能出现的错误,如网络连接失败、授权失败等,并通过 ElMessage 提示用户。

代码分析

iat_xfyun.js

  • 优点:将讯飞语音听写功能封装在一个独立的文件中,提高了代码的可维护性和可复用性。
  • 缺点:配置信息硬编码在文件中,不利于配置的修改和管理。可以考虑将配置信息提取到环境变量中。

Home.vue

  • 优点:在组件中使用语音识别实例,实现了语音输入功能的集成。通过回调函数处理识别结果和错误,代码结构清晰。
  • 缺点:语音输入按钮的样式和交互逻辑可以进一步优化,提高用户体验。

sparkChat.js

// 讯飞星火大模型WebSocket通信模块
import axios from 'axios'
import getSparkConfig from '../sparkConfig'class SparkChatService {constructor(callbacks) {this.websocket = nullthis.isReconnecting = falsethis.reconnectAttempts = 0this.MAX_RECONNECT_ATTEMPTS = 3this.RECONNECT_INTERVAL = 2000// 获取配置const sparkConfig = getSparkConfig()this.APPID = sparkConfig.APPIDthis.APISecret = sparkConfig.APISecretthis.APIKey = sparkConfig.APIKeythis.host = sparkConfig.hostthis.path = sparkConfig.paththis.sparkBaseUrl = sparkConfig.getWebSocketUrl()// 回调函数this.callbacks = callbacks || {}}// 生成鉴权URL所需的日期getAuthorizationDate() {return new Date().toUTCString()}// 生成鉴权URLasync getAuthUrl() {const date = this.getAuthorizationDate()const tmp = `host: ${this.host}\ndate: ${date}\nGET ${this.path} HTTP/1.1`const encoder = new TextEncoder()const key = await window.crypto.subtle.importKey('raw',encoder.encode(this.APISecret),{ name: 'HMAC', hash: 'SHA-256' },false,['sign'])const signature = await window.crypto.subtle.sign('HMAC',key,encoder.encode(tmp))const signatureBase64 = btoa(String.fromCharCode(...new Uint8Array(signature)))const authorization_origin = `api_key="${this.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="${signatureBase64}"`const authorization = btoa(authorization_origin)return `${this.sparkBaseUrl}?authorization=${encodeURIComponent(authorization)}&date=${encodeURIComponent(date)}&host=${encodeURIComponent(this.host)}`}// 检查WebSocket连接状态checkWebSocketConnection() {return this.websocket && this.websocket.readyState === WebSocket.OPEN}// 重连WebSocketasync reconnectWebSocket() {if (this.isReconnecting || this.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) returnthis.isReconnecting = truethis.reconnectAttempts++console.log(`尝试重新连接WebSocket (第${this.reconnectAttempts}次)...`)try {await this.connect()this.isReconnecting = falsethis.reconnectAttempts = 0console.log('WebSocket重连成功')} catch (error) {console.error('WebSocket重连失败:', error)this.isReconnecting = falseif (this.reconnectAttempts < this.MAX_RECONNECT_ATTEMPTS) {setTimeout(() => this.reconnectWebSocket(), this.RECONNECT_INTERVAL)} else {console.error('WebSocket重连次数达到上限')this.callbacks.onError?.('网络连接异常,请刷新页面重试')}}}// 建立WebSocket连接async connect() {try {const url = await this.getAuthUrl()this.websocket = new WebSocket(url)this.websocket.onopen = () => {console.log('WebSocket连接已建立')this.isReconnecting = falsethis.reconnectAttempts = 0this.callbacks.onOpen?.()}this.websocket.onmessage = (event) => {const response = JSON.parse(event.data)if (response.header.code === 0) {if (response.payload.choices.text[0].content) {const content = response.payload.choices.text[0].content.replace(/\r?\n/g, '')this.callbacks.onMessage?.(content)}if (response.header.status === 2) {this.callbacks.onComplete?.()}} else {this.callbacks.onError?.(`抱歉,发生错误:${response.header.message}`)}}this.websocket.onerror = (error) => {console.error('WebSocket错误:', error)if (!this.isReconnecting) {this.reconnectWebSocket()}this.callbacks.onError?.(error)}this.websocket.onclose = () => {console.log('WebSocket连接已关闭')if (!this.isReconnecting) {this.reconnectWebSocket()}this.callbacks.onClose?.()}} catch (error) {console.error('连接WebSocket失败:', error)throw error}}// 发送消息async sendMessage(message) {if (!this.checkWebSocketConnection()) {try {await this.reconnectWebSocket()} catch (error) {console.error('重连失败,无法发送消息')throw new Error('网络连接异常,请稍后重试')}}const requestData = {header: {app_id: this.APPID,uid: 'user1'},parameter: {chat: {domain: 'generalv3',temperature: 0.5,max_tokens: 4096}},payload: {message: {text: [{ role: 'user', content: message }]}}}try {this.websocket.send(JSON.stringify(requestData))} catch (error) {console.error('发送消息失败:', error)throw new Error('发送消息失败,请重试')}}// 关闭连接close() {if (this.websocket) {this.websocket.close()}}
}export default SparkChatService

虽然该文件主要负责与后端进行 WebSocket 通信,但在语音听写功能中起到了将识别结果发送给后端的重要作用。可以考虑对该文件进行进一步的封装,提高代码的可维护性。

AIChat

语音听写(流式版)WebAPI 文档帮助文档:

https://www.xfyun.cn/doc/asr/voicedictation/API.html#%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E
缺点:

语音听写流式接口,用于1分钟内的即时语音转文字技术,支持实时返回识别结果,达到一边上传音频一边获得识别文本的效果。
整个会话时长最多持续60s,或者超过10s未发送数据,服务端会主动断开连接

http://www.dtcms.com/wzjs/235488.html

相关文章:

  • 徐州网站中国搜索引擎份额排行
  • 淘宝网站小视频怎么做百度账号登录中心
  • 课堂网站开发网站快速被百度收录
  • 关于英文网站建设的请示seo搜索引擎优化心得体会
  • 推广型的网站怎么做常德网站建设公司
  • 手机网站跟pc网站有什么不同上海百度推广公司
  • 网页制作相关网站软件开发流程
  • 开一个二手车销售网站怎么做西安百度首页优化
  • 网站建设需要几个部门网站推广公司电话
  • 成都网站建设哪家公司好百度人工投诉电话是多少
  • 花乡做网站公司网络平台推广运营有哪些平台
  • 网站名查找seo关键词排名优化技巧
  • 锦州北京网站建设建立网站需要什么技术
  • 做毕设网站多少钱网站点击快速排名
  • 微商可以做网站推广吗广州seo公司排名
  • 余姚网站建设有哪些免费网站可以发布广告
  • 武汉地区网站建设成都网站快速排名
  • 浙江华洋建设有限公司网站seo外包服务公司
  • 自己怎么做单页网站杭州seo 云优化科技
  • 做兼职去什么网站网络营销的背景和意义
  • 中牟网站建设seo网站查询工具
  • com域名需要备案吗淘宝seo排名优化软件
  • flask做大型网站开发网址信息查询
  • 上海网站建设定制公司360收录提交入口
  • 网站开发主要语言软件开发交易平台
  • 有限责任公司设立条件seo描述是什么意思
  • 网站建设与管理实验报告百度官方网址
  • wordpress站点演示怎样自己做网站
  • 触屏手机网站万能浏览器
  • wordpress 更改目录seo搜索引擎优化方案