Skip to content

Instantly share code, notes, and snippets.

@chrobione
Created April 26, 2023 07:55
Show Gist options
  • Save chrobione/e168a71ac23c7ec49297c0566a7c7d2f to your computer and use it in GitHub Desktop.
Save chrobione/e168a71ac23c7ec49297c0566a7c7d2f to your computer and use it in GitHub Desktop.
html file for brower tts. Best experience is with edge atm.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Text-to-Speech Example</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 2rem;
}
textarea {
width: 80%;
resize: none;
overflow: hidden;
}
</style>
</head>
<body>
<h1>Text-to-Speech Example</h1>
<p>Type some text in the input field below, select a voice, adjust the speech rate, and click the "Read Text" button to hear it read aloud.</p>
<textarea id="text-to-read" rows="1" placeholder="Enter text here..."></textarea>
<br>
<label for="voice-select">Select Voice:</label>
<select id="voice-select" style="margin: 1rem;"></select>
<br>
<label for="speech-rate">Speech Rate: <span id="speech-rate-value">1</span></label>
<input type="range" id="speech-rate" min="0.1" max="2" step="0.1" value="1">
<br>
<button id="read-text" style="margin-top: 1rem;">Read Text</button>
<br>
<a id="settings-link" href="#" style="display: block; margin-top: 1rem;">Save Settings</a>
<script>
let currentUtterance = null;
function populateVoiceList() {
const voiceSelect = document.getElementById('voice-select');
const voices = speechSynthesis.getVoices();
voices.forEach(voice => {
const option = document.createElement('option');
option.textContent = voice.name;
option.value = voice.name;
voiceSelect.appendChild(option);
});
}
function getQueryParams() {
const queryString = window.location.search.slice(1);
const queryParams = new URLSearchParams(queryString);
return queryParams;
}
function loadSettings() {
const queryParams = getQueryParams();
if (queryParams.has('speed')) {
const speed = parseFloat(queryParams.get('speed'));
document.getElementById('speech-rate').value = speed;
document.getElementById('speech-rate-value').textContent = speed;
}
if (queryParams.has('voice')) {
const voice = queryParams.get('voice');
document.getElementById('voice-select').value = voice;
}
}
function updateSettingsLink() {
const speed = document.getElementById('speech-rate').value;
const voice = encodeURIComponent(document.getElementById('voice-select').value);
const baseUrl = window.location.href.split('?')[0];
const settingsUrl = `${baseUrl}?speed=${speed}&voice=${voice}`;
const settingsLink = document.getElementById('settings-link');
settingsLink.href = settingsUrl;
settingsLink.textContent = 'Save Settings: ' + settingsUrl;
}
if ('speechSynthesis' in window) {
populateVoiceList();
if (speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = () => {
populateVoiceList();
loadSettings();
};
}
}
loadSettings();
document.getElementById('read-text').addEventListener('click', readText);
document.getElementById('speech-rate').addEventListener('input', updateSpeechRate);
document.getElementById('voice-select').addEventListener('change', updateSettingsLink);
document.getElementById('settings-link').addEventListener('click', (event) => {
event.preventDefault();
updateSettingsLink();
});
// Auto-resize textarea
document.getElementById('text-to-read').addEventListener('input', (event) => {
const target = event.target;
target.style.height = 'auto';
target.style.height = target.scrollHeight + 'px';
});
function readText() {
const textToRead = document.getElementById('text-to-read').value;
const selectedVoice = document.getElementById('voice-select').value;
const speechRate = document.getElementById('speech-rate').value;
if ('speechSynthesis' in window) {
currentUtterance = new SpeechSynthesisUtterance(textToRead);
const voices = speechSynthesis.getVoices();
const voice = voices.find(voice => voice.name === selectedVoice);
currentUtterance.voice = voice;
currentUtterance.rate = speechRate;
window.speechSynthesis.speak(currentUtterance);
} else {
alert('Your browser does not support the Web Speech API.');
}
}
function updateSpeechRate(event) {
document.getElementById('speech-rate-value').textContent = event.target.value;
if (currentUtterance && !currentUtterance.paused) {
speechSynthesis.cancel();
readText();
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment