API-ul Web Speech pentru Sinteza Vocală
Web Speech API permite dezvoltatorilor web să genereze și să recunoască vocea pe o pagină web în mod programatic. Acesta definește două interfețe: SpeechRecognition (pentru recunoașterea vocii) și SpeechSynthesis (pentru sinteza vocii). Acest API (la momentul scrierii acestui articol) încă nu este un standard oficial W3C, iar suportul său în diferite browsere poate varia. Să examinăm mai întâi sinteza vocii.
La nivelul browserului, sinteza vocii este accesibilă prin proprietatea speechSynthesis a obiectului window, care reprezintă SpeechSynthesis și prin care se poate verifica suportul browserului pentru sinteza vocii:
if(window.speechSynthesis) {
console.log("Sinteza vocii este suportată");
}
else {
console.log("Sinteza vocii NU este suportată");
}
// O metodă alternativă de verificare
if("speechSynthesis" in window) {
console.log("Sinteza vocii este suportată");
}
else {
console.log("Sinteza vocii NU este suportată");
}
Pentru sinteza vocii se utilizează obiectul de tip SpeechSynthesisUtterance, care reprezintă o expresie vocală distinctă și permite configurarea sintezei prin intermediul mai multor proprietăți:
- lang: obține și setează limba expresiei
- pitch: obține și setează înălțimea tonului cu care va fi rostită expresia
- rate: obține și setează viteza de rostire a expresiei
- text: obține și setează textul care va fi sintetizat și rostit
- voice: obține și setează vocea care va fi folosită pentru rostirea expresiei
- volume: obține și setează volumul rostirii expresiei
În general, este suficient să setăm proprietatea text:
const utterance = new SpeechSynthesisUtterance();
utterance.text = "Hello World";
Pentru sinteza vocii și gestionarea acesteia se apelează una dintre metodele de tip SpeechSynthesis:
- cancel(): elimină toate expresiile din coada de așteptare
- getVoices(): returnează o listă de obiecte SpeechSynthesisVoice, reprezentând toate vocile disponibile pe dispozitivul curent
- pause(): suspendă sinteza vocii
- resume(): reia sinteza vocii (dacă anterior a fost suspendată)
- speak(): adaugă o expresie în coada de așteptare pentru a fi rostită
De exemplu, să sintetizăm vocea pentru un text simplu:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>FDC.COM</title>
</head>
<body>
<input id="text" value="Hello World" />
<button id="btn">Speak</button>
<script>
document.getElementById("btn").addEventListener("click", speak);
function speak(){
if(window.speechSynthesis) {
const utterance = new SpeechSynthesisUtterance();
utterance.text = document.getElementById("text").value;
window.speechSynthesis.speak(utterance);
}
else{
console.log("Funcția nu este suportată");
}
}
</script>
</body>
</html>
În acest caz, apăsând pe buton se va sintetiza vocea pentru textul introdus în câmpul text. Este de menționat că browserele pot impune restricții asupra inițierii sintezei, de exemplu, în Google Chrome este necesar ca utilizatorul să activeze acțiunea. De aceea, aici sinteza este executată la apăsarea butonului, nu imediat la încărcarea paginii.
Se pot configura și alte setări ale vocii:
document.getElementById("btn").addEventListener("click", speak);
function speak(){
if(window.speechSynthesis) {
const utterance = new SpeechSynthesisUtterance();
utterance.text = "Salut";
utterance.lang = "ro"; // abrevierea limbii
utterance.volume = 0.5; // volumul
utterance.rate = 0.5; // viteza
utterance.pitch = 0.5; // înălțimea tonului
window.speechSynthesis.speak(utterance);
}
}
Alegerea vocii
Dacă browserul suportă mai multe voci, acestea pot fi selectate cu ajutorul metodei getVoices() a obiectului SpeechSynthesis. Fiecare voce are diferite proprietăți, inclusiv numele și abrevierea asociată țării sau limbii. Și le putem parcurge pe toate într-un ciclu:
const voices = window.speechSynthesis.getVoices();
voices.forEach(function(voice) {
console.log(voice.lang);
console.log(voice.name);
});
Alegând vocea dorită, aceasta poate fi setată folosind proprietatea voices a obiectului SpeechSynthesisUtterance
document.getElementById("btn").addEventListener("click", speak);
function speak(){
if(window.speechSynthesis) {
const utterance = new SpeechSynthesisUtterance();
utterance.text = "Salut";
const voices = window.speechSynthesis.getVoices();
const selectedVoice = voices[0]; // selectăm prima voce
window.speechSynthesis.speak(utterance);
}
}
Este de menționat că, în cazul meu, deși lista oferea trei voci în limba română, toate erau identice cu prima.
Evenimente de sinteză a vocii
În procesul de sinteză a vocii pot apărea diferite evenimente (pe obiectul SpeechSynthesisUtterance):
- boundary: apare la atingerea graniței unui cuvânt sau fraze. Handlerul este setat prin proprietatea onboundary
- end: apare la finalizarea vocii. Handlerul este setat prin proprietatea onend
- error: apare în caz de eroare. Handlerul este setat prin proprietatea onerror
- mark: apare când vocea atinge un tag numit "marca" SSML. Handlerul este setat prin proprietatea onmark
- pause: apare când vocea este suspendată. Handlerul este setat prin proprietatea onpause
- resume: apare când vocea este reluată. Handlerul este setat prin proprietatea onresume
- start: apare la începutul vocii. Handlerul este setat prin proprietatea onstart
Pentru demonstrație, să procesăm câteva evenimente:
document.getElementById("btn").addEventListener("click", speak);
function speak(){
if(window.speechSynthesis) {
const utterance = new SpeechSynthesisUtterance();
utterance.onstart = () => console.log("Începutul vocii");
utterance.onend = () => console.log("Sfârșitul vocii");
utterance.text = "Salut";
window.speechSynthesis.speak(utterance);
}
}