我正在构建一个网络应用程序,它可以接收语音并将其转换为文本。然后将文本转换为文本并发送到 openai(chatgpt),以便它返回答案。 aws polly 是我在 chatgpt 返回答案时用于语音输出的工具。
我的问题是我在生产中的 vue 应用程序中遇到以下错误:
/voice/66154949.mp3:1 GET https://jarvis-ruby-rho.vercel.app/voice/66154949.mp3 net::ERR_ABORTED 404 (Not Found)
Uncaught (in promise) DOMException: Failed to load because no supported source was found.
代码在本地运行良好,但我在生产中遇到该错误(vercel 和 netlify)
这是我的节点(express)代码:
const express = require("express");
const app = express();
const cors = require("cors");
const bodyParser = require("body-parser");
const fs = require("fs");
const dotenv = require("dotenv")
dotenv.config()
const PORT = process.env.PORT || 3001;
const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({ apiKey: process.env.OPEN_AI_KEY});
const openai = new OpenAIApi(configuration);
app.use(bodyParser.json());
app.use(cors());
const AWS = require("aws-sdk");
AWS.config.loadFromPath("AWS_Credentials.json");
app.post('/api/TTS', async (req, res) => {
const completion = await openai.createCompletion({
model: "text-davinci-003",
prompt: req.body.text,
max_tokens: 100,
temperature: 0.5
})
console.log(completion)
let num = (Math.random() * 100000000).toFixed(0);
const awsPolly = new AWS.Polly({ region: "us-east-1" })
const params = {
OutputFormat: "mp3",
Text: completion.data.choices[0].text,
VoiceId: "Matthew"
}
awsPolly.synthesizeSpeech(params, (err, data) => {
if (err) {
console.error(err);
return;
}
let filePath = "../public/voice/";
let fileName = num + ".mp3";
if (num) fs.writeFileSync(filePath + fileName, data.AudioStream)
})
setTimeout(() => { res.status(200).json(num) }, 4500)
})
app.listen(PORT, () => {
console.log(`Listening at ${PORT}`);
});
我的vue代码:
<script setup>
import { ref } from 'vue';
import { useAVLine } from 'vue-audio-visual';
const player = ref(null);
const canvas = ref(null);
let mySource = ref(null);
let action = ref('');
let output = ref('');
useAVLine(player, canvas, { src: mySource, canvHeight: 300, canvWidth: 1000, lineColor: 'orange' });
const runSpeechRecognition = () => {
var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition;
var recognition = new SpeechRecognition();
recognition.onstart = () => {
action.value = "I'm Listening";
};
recognition.onspeechend = () => {
action.value = 'Done';
recognition.stop();
};
recognition.onresult = async (event) => {
var transcript = event.results[0][0].transcript;
output.value = transcript;
try {
const baseURL = import.meta.env.VITE_BASE_SERVER_URL || 'http://localhost:3001'
const response = await fetch(`${baseURL}/api/TTS`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: event.results[0][0].transcript,
}),
});
if (response.ok) {
const data = await response.json();
console.log(data)
if (data) {
mySource.value = `${import.meta.env.BASE_URL}voice/${data}.mp3`;
setTimeout(() => {
player.value.play();
}, 500);
}
} else {
console.log('Request failed with status:', response.status);
}
} catch (err) {
console.log(err);
}
};
recognition.start();
};
</script>
<template>
<div class="show">
<div class="action" v-if="action">{{ action }}</div>
<div class="synthesizedSpeech" v-if="output"><b>Question</b>: {{ output }}</div>
</div>
<div class="audio-wrapper">
<audio id="player" ref="player" :src="mySource" type="audio/mp3" controls hidden></audio>
<canvas ref="canvas" />
<div class="button-section">
<button type="button" @click="runSpeechRecognition()">Ask Me Anything</button>
</div>
</div>
</template>
<style>
body {
background-color: rgb(23, 23, 23);
}
.audio-wrapper{
height: 80vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
canvas {
display: block;
width: 800px;
}
.button-section {
display: flex;
justify-content: center;
margin-top: 30px;
}
button {
padding: 8px 13px;
border-radius: 5px;
background-color: orange;
color: white;
font-weight: 700;
font-size: 18px;
border: none;
cursor: pointer;
}
.show {
width: 100%;
text-align: center;
color: white;
}
.action {
margin-top: 10px;
margin-bottom: 10px;
}
.synthesizedSpeech {
max-width: 500px;
padding: 20px;
border-radius: 10px;
display: inline-block;
background: #313131;
font-weight: bold;
}
</style>
P.S:我的根 vue 代码中有我的后端文件夹(代码)(我的后端文件夹嵌套在前端内部的位置)
您没有正确使用音频标签
<audio ... >
<source :src="mySource" type="audio/mp3" />
</audio>
使用'source'标签而不是使用'src'属性,它应该是URL类型。