Reputation: 3
Error in text-to-speech: run loop already started
Backend Code
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
import os
import google.generativeai as genai
from dotenv import load_dotenv
import pyttsx3
from langchain_google_genai import GoogleGenerativeAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain.prompts import PromptTemplate
from langchain.chains.question_answering import load_qa_chain
# Load environment variables
load_dotenv()
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))
# Initialize TTS Engine
engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[0].id)
class VoiceBotView(APIView):
def post(self, request):
user_message = request.data.get('query')
VoiceBotFunction.speak("Searching")
try:
response_text = VoiceBotFunction.get_voice_response(user_message)
VoiceBotFunction.speak(response_text)
print(response_text)
return Response({'query': user_message, 'response': response_text})
except Exception as e:
print(f"Exception occurred: {e}")
return Response({'error': 'Internal server error'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class VoiceBotFunction:
def speak(text, rate=120):
try:
engine.setProperty('rate', rate)
engine.say(text)
engine.runAndWait() # run and wait method, it processes the voice commands.
engine.stop()
if engine._inLoop:
engine.endLoop()
except Exception as e:
print(f"Error in text-to-speech: {e}")
def get_conversational_chain():
prompt_template = """
Answer the question as detailed as possible from the provided context, make sure to provide all the details, if the answer is not in
provided context just say, "Answer is not available in the Database", don't provide the wrong answer\n\n
Context:\n {context}?\n
Question: \n{question}\n
Answer:
"""
model = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0.3)
prompt = PromptTemplate(template=prompt_template, input_variables=["context", "question"])
chain = load_qa_chain(model, chain_type="stuff", prompt=prompt)
return chain
def get_voice_response(user_message):
try:
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
new_db = FAISS.load_local("vector_db", embeddings, allow_dangerous_deserialization=True)
docs = new_db.similarity_search(user_message)
chain = VoiceBotFunction.get_conversational_chain()
reply_response = chain.invoke({"input_documents": docs, "question": user_message}, return_only_outputs=True)
print(f"Reply response: {reply_response}")
return reply_response.get('output_text', 'No response available.')
except Exception as e:
print(f"Error in get_voice_response: {e}")
raise
Frontend Code
import React, { useState } from 'react';
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';
import 'regenerator-runtime/runtime';
const VoiceBot = () => {
const [userQuestion,setUserQuestion] = useState('')
const [response, setResponse] = useState('');
const { transcript, listening, resetTranscript } = useSpeechRecognition();
if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
return <div>Your browser does not support speech recognition.</div>;
}
const startListening = () => SpeechRecognition.startListening({ continuous: true });
const stopListening = () => {
SpeechRecognition.stopListening();
sendTranscript(transcript);
resetTranscript();
};
const sendTranscript = async (text) => {
try {
const response = await fetch('http://localhost:8000/api/voice/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: text }),
});
const data = await response.json();
setUserQuestion(data.query);
setResponse(data.response);
} catch (error) {
console.error('Error:', error);
}
};
return (
<div className="container mx-auto p-4">
<h2 className="text-2xl font-bold mb-4">Voice Bot</h2>
<p className="mb-4">Press the buttons to start and stop recording, and send the transcript to the backend.</p>
<div className="mb-4">
<button
className="bg-green-500 text-white px-4 py-2 rounded mr-2"
onClick={startListening}
disabled={listening}
>
Start Recording
</button>
<button
className="bg-red-500 text-white px-4 py-2 rounded"
onClick={stopListening}
disabled={!listening}
>
Stop Recording
</button>
</div>
<div className="transcript p-4 border border-gray-300 rounded mb-4">
<h3 className="text-xl font-bold">Transcript</h3>
<p>{transcript}</p>
</div>
<div className="response p-4 border border-gray-300 rounded">
<h3 className="text-xl font-bold">User: </h3>
<p>{userQuestion}</p>
<h3 className="text-xl font-bold">Server:</h3>
<p>{response}</p>
</div>
</div>
);
};
export default VoiceBot;
I am trying to develop a custom voice assistant with React & DJango. FAISS is used as the vector DB. Both frontend & backend work perfectly. frontend When I click the "stop Recording" button the voice output send to the backend. When I input correct query then correct result is generated but voice part is not worked as I expected.
Upvotes: 0
Views: 27