Skip to content

Commit

Permalink
text to speech added
Browse files Browse the repository at this point in the history
  • Loading branch information
aman-maharshi committed Jan 21, 2025
1 parent 0ed2642 commit baf9390
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 0 deletions.
3 changes: 3 additions & 0 deletions text-to-speech/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"liveServer.settings.port": 5501
}
63 changes: 63 additions & 0 deletions text-to-speech/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="styles.css" />
<title>VoiceOver - TTS & Translation</title>
</head>

<body class="gradient-bg flex items-center justify-center h-screen">
<div class="bg-[#212121] text-white shadow-md rounded-xl p-7 main-container">
<h1 class="text-2xl font-semibold text-center mb-4 flex gap-4 items-center justify-center">
<img src="waveIcon.svg" class="h-10 w-10" alt="wave">
VoiceOver
</h1>
<p class="text-center my-4 text-sm text-stone-400">
This app allows you to convert text to speech and translate it into different languages.
Simply type your text, select a language and voice, and click play to hear the translation.
</p>

<textarea
class="w-full h-32 p-3 border border-stone-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none bg-[#373737] placeholder:text-stone-300"
placeholder="Type your text here..."></textarea>

<!-- <div class="mt-4">
<label for="languageSelect" class="block text-sm font-medium mb-2">
Select Language
</label>
<select id="languageSelect"
class="w-full p-3 border border-stone-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer bg-[#373737]">
</select>
</div> -->

<div class="mt-4">
<label for="voiceSelect" class="block text-sm font-medium mb-2">Select Voice</label>
<select id="voiceSelect"
class="w-full p-3 border border-stone-500 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer bg-[#373737]">
<option value="default">Default Voice</option>
</select>
</div>

<button
class="mt-6 w-full flex items-center gap-2 justify-center cta-bg text-white font-medium py-3 rounded-xl focus:outline-none hover:ring-2 hover:ring-blue-500"
id="playButton">
<img src="speakerIcon.svg" class="h-5 w-5" alt="speaker">
Play Text
</button>

<p id="error" class="text-red-400 h-4 mt-2 text-sm"></p>
</div>

<footer class="hidden md:block fixed bottom-2 left-0 right-0 text-center p-2">
<p>Designed and Coded by
<a href="http://amanmaharshi.com" target="_blank" class="text-[#36556d] hover:underline">Aman Maharshi</a>
</p>
</footer>

<script src="script.js"></script>
</body>

</html>
69 changes: 69 additions & 0 deletions text-to-speech/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const voiceSelect = document.querySelector('#voiceSelect')
const playButton = document.querySelector('#playButton')
const textInput = document.querySelector('textarea')
const error = document.querySelector('#error')

let activeVoice = ''

/*
FUNCTIONS
--------------*/

const populateVoiceList = () => {
let voices = speechSynthesis.getVoices()
// voices = voices.filter(item => item.lang === "en-GB")
// console.log(voices)
voices.forEach(voice => {
const option = document.createElement('option')
option.textContent = `${voice.name} (${voice.lang})`
option.setAttribute('data-lang', voice.lang)
option.setAttribute('data-name', voice.name)
voiceSelect.appendChild(option)
})
}

const playText = () => {
const text = textInput.value
if (text) {
const utterance = new SpeechSynthesisUtterance(text)
if (activeVoice) {
utterance.voice = activeVoice
}
speechSynthesis.speak(utterance)
} else {
error.textContent = 'Please enter text to read'
setTimeout(() => {
error.textContent = ''
}, 3000)
}
}

const handleVoiceChange = () => {
const selectedVoice = voiceSelect.selectedOptions[0].getAttribute('data-name')
const voices = speechSynthesis.getVoices()
const voice = voices.find(voice => voice.name === selectedVoice)
activeVoice = voice
// const utterance = new SpeechSynthesisUtterance(textInput.value)
// utterance.voice = voice
// speechSynthesis.speak(utterance)
}

/*
EVENT LISTENERS
-------------------*/
document.addEventListener('DOMContentLoaded', () => {
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoiceList
}
populateVoiceList()
})

playButton.addEventListener('click', playText)

voiceSelect.addEventListener('change', handleVoiceChange)






1 change: 1 addition & 0 deletions text-to-speech/speakerIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions text-to-speech/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200..1000&display=swap');

* {
box-sizing: border-box;
font-family: "Nunito", serif;
}

.main-container {
width: 500px;
}

@media (max-width: 600px) {
.main-container {
width: 90vw;
height: 95vh;
}
}

.gradient-bg {
background-image: linear-gradient(to top, #a8edea 0%, #fed6e3 100%);
}

.cta-bg {
background-image: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
1 change: 1 addition & 0 deletions text-to-speech/waveIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit baf9390

Please sign in to comment.