ocr / src /components /TextToSpeech.jsx
ariansyahdedy's picture
test with yaml
7f37689
import { useState } from 'react';
import { textToSpeech } from '../services/api';
import languageVoices from '../data/languageVoices'; // Adjust the path as needed
function TextToSpeech() {
const [text, setText] = useState('');
const [languageCode, setLanguageCode] = useState('en-US');
const [ssmlGender, setSsmlGender] = useState('NEUTRAL');
const [name, setName] = useState('en-US-Standard-C');
const [pitch, setPitch] = useState(0.0);
const [speakingRate, setSpeakingRate] = useState(1.0);
const [volumeGainDb, setVolumeGainDb] = useState(0.0);
const [audioUrl, setAudioUrl] = useState(null);
// Ensure you have VITE_API_URL set in your .env file
const API_URL = import.meta.env.VITE_API_URL;
const handleTextToSpeech = async () => {
// Call text-to-speech service
try {
const response = await textToSpeech(text, languageCode, ssmlGender, name, pitch, speakingRate, volumeGainDb);
const baseUrl = new URL(API_URL);
const audioUrl = `${baseUrl.origin}/static/storage/exported/${response}`;
console.log(audioUrl)
setAudioUrl(audioUrl);
} catch (error) {
console.error('Text-to-Speech failed:', error);
}
};
const handleDeleteAudio = () => {
setAudioUrl(null);
};
return (
<div className="flex justify-center items-center min-h-screen bg-gray-100 p-4">
<div className="w-full max-w-3xl p-6 bg-white rounded-lg shadow-md">
<h2 className="text-3xl font-bold mb-6 text-center text-blue-500">Text-to-Speech AI</h2>
<div className="mb-6">
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
className="w-full h-32 p-3 border rounded"
placeholder="Enter some text here..."
/>
</div>
<div className="mb-4">
<label className="block text-gray-700 font-bold mb-2">Volume</label>
<input
type="range"
min="-96.0"
max="16.0"
step="0.1"
value={volumeGainDb}
onChange={(e) => setVolumeGainDb(parseFloat(e.target.value))}
className="w-full"
/>
<span className="block text-right text-gray-600">{volumeGainDb.toFixed(1)}</span>
</div>
<div className="mb-4">
<label className="block text-gray-700 font-bold mb-2">Rate</label>
<input
type="range"
min="0.25"
max="4.0"
step="0.01"
value={speakingRate}
onChange={(e) => setSpeakingRate(parseFloat(e.target.value))}
className="w-full"
/>
<span className="block text-right text-gray-600">{speakingRate.toFixed(2)}</span>
</div>
<div className="mb-4">
<label className="block text-gray-700 font-bold mb-2">Pitch</label>
<input
type="range"
min="-20.0"
max="20.0"
step="0.1"
value={pitch}
onChange={(e) => setPitch(parseFloat(e.target.value))}
className="w-full"
/>
<span className="block text-right text-gray-600">{pitch.toFixed(1)}</span>
</div>
<div className="mb-4">
<label className="block text-gray-700 font-bold mb-2">Language</label>
<select
value={languageCode}
onChange={(e) => {
setLanguageCode(e.target.value);
setName(languageVoices[e.target.value][0].name); // Set default voice for selected language
}}
className="w-full p-2 border rounded"
>
{Object.keys(languageVoices).map((lang) => (
<option key={lang} value={lang}>
{lang}
</option>
))}
</select>
</div>
<div className="mb-4">
<label className="block text-gray-700 font-bold mb-2">Voice</label>
<select
value={name}
onChange={(e) => setName(e.target.value)}
className="w-full p-2 border rounded"
>
{languageVoices[languageCode].map((voice) => (
<option key={voice.name} value={voice.name}>
{voice.label}
</option>
))}
</select>
</div>
<div className="flex justify-between mt-6">
<button
onClick={handleTextToSpeech} // Stop button handler
className="w-fit px-4 py-2 bg-blue-500 text-white rounded hover:shadow-lg hover:bg-blue-700 transition duration-200"
>
Generate
</button>
</div>
{audioUrl && (
<div className="mt-6">
<div className="flex items-center">
<audio controls src={audioUrl} className="w-full">
Your browser does not support the audio element.
</audio>
<button
onClick={handleDeleteAudio}
className="ml-4 px-4 py-2 bg-red-500 text-white rounded hover:bg-red-700 transition duration-200"
>
Delete
</button>
</div>
</div>
)}
</div>
</div>
);
}
export default TextToSpeech;