Chandima Maduwantha
Chandima Maduwantha

Reputation: 3

Error while using "pyttsx3" with "react-speech-recognition"

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

Answers (0)

Related Questions