Skip to content

Commit

Permalink
added speechtotext route
Browse files Browse the repository at this point in the history
  • Loading branch information
preston176 committed May 28, 2024
1 parent f59b836 commit d5c0992
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Footer from './Components/Footer/Footer';
import About from './Pages/About';
import { ThemeContext } from '@emotion/react';
import AiServices from './Pages/AiServices';
import SpeechToText from './Pages/SpeechToText';

const App = () => {
const [isDarkMode, setIsDarkMode] = useState(true);
Expand All @@ -26,6 +27,8 @@ const App = () => {
<Route path="/generate_image" element={<ImageGen />} />
<Route path="/about" element={<About isDarkMode={isDarkMode} />} />
<Route path="/services" element={<AiServices isDarkMode={isDarkMode} />} />
<Route path="/services/generate_image" element={<ImageGen isDarkMode={isDarkMode} />} />
<Route path="/services/speech_to_text" element={<SpeechToText isDarkMode={isDarkMode} />} />
<Route path="*" element={<h1>Not Found</h1>} />
</Routes>
<Footer />
Expand Down
1 change: 0 additions & 1 deletion src/Components/Header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const Header = () => {
const links = [
{ name: 'About', link: 'about' },
{ name: 'Services', link: 'services' },
{ name: 'Generate Image', link: 'generate_image' },
];

const [open, setOpen] = useState(false);
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Hero/Hero.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const Hero = ({ isDarkMode }) => {

<div className="">

<Link to="/generate_image"> <h3 className={`${isDarkMode ? ThemeStyles.darkBtn : ThemeStyles.lightBtn}' hover:scale-105 transition ease-in-out delay-50 hover:transition-all`}>Get Started</h3></Link>
<Link to="/services"> <h3 className={`${isDarkMode ? ThemeStyles.darkBtn : ThemeStyles.lightBtn}' hover:scale-105 transition ease-in-out delay-50 hover:transition-all`}>Get Started</h3></Link>

</div>
</div>
Expand Down
8 changes: 7 additions & 1 deletion src/Components/ImageGenerator/ImageGenerator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useRef, useState } from 'react';
import defaultImage from '../../assets/defaultImage.jpg';
import axios from 'axios';
import './ImageGenerator.css';
import Swal from 'sweetalert2';

const ImageGenerator = ({ isDarkMode }) => {
// ImageURL State
Expand Down Expand Up @@ -33,7 +34,12 @@ const ImageGenerator = ({ isDarkMode }) => {
setLoading(false)
} catch (error) {
console.error('Error generating image:', error.response.data);
alert('Failed to generate image. Please try again later.');
Swal.fire({
icon: 'error',
title: 'Oops...',
text: "Failed to generate image. Please try again later.",
});
// alert('Failed to generate image. Please try again later.');
}
};

Expand Down
96 changes: 93 additions & 3 deletions src/Pages/AiServices.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,99 @@
import React from 'react'
import BoltIcon from '@mui/icons-material/Bolt';
import ArticleIcon from '@mui/icons-material/Article';
import TranscribeIcon from '@mui/icons-material/Transcribe';
import { Link } from 'react-router-dom';

const AiServices = ({ isDarkMode }) => {



const ThemeStyles = {
dark: "bg-[#111] shadow-gray-700",
darkText: 'text-white',
lightText: 'text-black',
light: 'bg-[#858585] shadow-gray-700 bg-opacity-10'
}

const cards = [
{
icon: <BoltIcon fontSize='large' />,
title: "Generate Images",
description: "Describe and get images",
link: '/services/generate_image'
},
{
icon: <TranscribeIcon fontSize='large' />,
title: "Speech to Text",
description: "Convert your spoken words into text instantly with our advanced speech-to-text feature.",
link: '/services/speech_to_text'
},
{
icon: <ArticleIcon fontSize='large' />,
title: "Summarization",
description: "Summarize long documents, articles, or reports into concise overviews.",
},
]
//TODO: To be implemented
// const cards2 = [
// {
// icon: <BoltIcon fontSize='large' />,
// title: "Generate Images",
// description: "Describe and get images",
// },
// {
// icon: <TranscribeIcon fontSize='large' />,
// title: "Speech to Text",
// description: "Convert your spoken words into text instantly with our advanced speech-to-text feature.",
// },
// {
// icon: <ArticleIcon fontSize='large' />,
// title: "Summarization",
// description: "Summarize long documents, articles, or reports into concise overviews.",
// },
// ]

return (
<div>AiServices</div>
<>
<div className={`${isDarkMode ? ThemeStyles.dark : ThemeStyles.light} mb-0 mt-8 flex flex-col justify-evenly items-center h-[40vh] rounded-3xl`}>
<h2 className='bg-gradient-to-r from-red-500 to-blue-500 text-transparent bg-clip-text laptop:text-[60px] font-mono p-0 md:text-[76px] sm:text-[46px] mobile:text-[28px] small_mobile:text-[25px] text-center' >
Services</h2>
</div>
<div className='flex rounded-[3000px] items-center justify-between pt-8 py-4 sm:flex-row mobile:flex-col mobile:gap-5 '>
{
cards.map((card, index) => (
<Link to={card.link}>
<div key={index} className={`${isDarkMode ? ThemeStyles.dark : ThemeStyles.light} flex flex-col justify-around items-center h-60 rounded-xl mobile:w-screen md:w-[320px] lg:w-[400px] hover:scale-110 hover:cursor-pointer transition-all ease-in-out duration-150`}>
<h2 className="bg-gradient-to-r from-red-500 to-blue-500 text-transparent bg-clip-text laptop:text-[40px] font-mono p-4 md:text-[76px] sm:text-[46px] mobile:text-[28px] small_mobile:text-[25px] text-center">{card.title}</h2>
<div className={`${isDarkMode ? ThemeStyles.darkText : ThemeStyles.lightText} flex justify-center items-center scale-[2]`}>
{card.icon}
</div>
<div className="">
<h3 className={`${isDarkMode ? ThemeStyles.darkText : ThemeStyles.lightText} w-auto m-auto text-center`}>{card.description}</h3>
</div>
</div>
</Link>
))
}
</div>
{/* TODO: To be implemented */}
{/* <div className='flex rounded-[3000px] items-center justify-between pt-8 sm:flex-row mobile:flex-col mobile:gap-5 '>
{
cards2.map((card, index) => (
<div key={index} className={`${isDarkMode ? ThemeStyles.dark : ThemeStyles.light} flex flex-col justify-around items-center h-60 rounded-xl mobile:w-screen md:w-[320px] lg:w-[400px]`}>
<h2 className="bg-gradient-to-r from-red-500 to-blue-500 text-transparent bg-clip-text laptop:text-[40px] font-mono p-4 md:text-[76px] sm:text-[46px] mobile:text-[28px] small_mobile:text-[25px] text-center opacity-5">{card.title}</h2>
<div className={`${isDarkMode ? ThemeStyles.darkText : ThemeStyles2.lightText} flex justify-center items-center scale-[2] opacity-5`}>
{card.icon}
</div>
<div className="">
<h3 className={`${isDarkMode ? ThemeStyles.darkText : ThemeStyles.lightText} w-auto m-auto text-center opacity-100`}>{card.description}</h3>
</div>
</div>
))
}
</div> */}

</>
)
}

export default AiServices
export default AiServices
89 changes: 89 additions & 0 deletions src/Pages/SpeechToText.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React, { useState } from 'react';
import axios from 'axios';
import { ReactMic } from 'react-mic';
import Swal from 'sweetalert2';

const SpeechToText = ({ isDarkMode }) => {
const [recording, setRecording] = useState(false);
const [transcript, setTranscript] = useState('');
const [audioBlob, setAudioBlob] = useState(null);
const [recognizing, setRecognizing] = useState(false);

const startRecording = () => {
setRecording(true);
};

const stopRecording = () => {
setRecording(false);
};

const onData = (recordedBlob) => {
// You can use this function if you want to perform any operation with the blob data in real-time.
};

const onStop = (recordedBlob) => {
setAudioBlob(recordedBlob.blob);
transcribeAudio(recordedBlob.blob);
};

const transcribeAudio = async (audioBlob) => {
setRecognizing(true);
try {
const formData = new FormData();
formData.append('file', audioBlob, 'audio.wav');
formData.append('model', 'whisper-1');

const response = await axios.post('https://api.openai.com/v1/audio/transcriptions', formData, {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
});

setTranscript(response.data.text);
} catch (error) {
console.error('Error transcribing audio:', error.response ? error.response.data : error.message);
Swal.fire({
icon: 'error',
title: 'Oops...',
text: 'Failed to transcribe audio. Please try again later.',
});
} finally {
setRecognizing(false);
}
};

return (
<div className="flex flex-col items-center justify-center mt-8 mb-4 gap-4">
<div className={`${isDarkMode ? "text-white" : "text-black"} text-4xl font-medium pb-6`}>
AI Speech <span className="text-pink-500">Recognizer</span>
</div>
<div className={`${isDarkMode ? "bg-gray-700" : "bg-gray-900"} flex flex-col w-full max-w-screen-md items-center justify-center p-4 rounded-md`}>
<ReactMic
record={recording}
className="sound-wave"
onStop={onStop}
onData={onData}
strokeColor="#000000"
backgroundColor="#FF4081"
/>
<input
type="text"
placeholder="Transcription will appear here"
className="w-full h-12 bg-transparent border-none outline-none text-white placeholder-white text-lg px-4 mr-2 mt-4"
value={transcript}
readOnly
/>
<button
className="mt-4 bg-[#DE1B89] hover:bg-[#c448c8] text-white font-bold py-2 px-4 rounded"
onClick={recording ? stopRecording : startRecording}
disabled={recognizing}
>
{recording ? 'Stop Recording' : 'Start Recording'}
</button>
</div>
</div>
);
};

export default SpeechToText;

0 comments on commit d5c0992

Please sign in to comment.