Reputation: 3543
I want to create a function to combine natural human recorded voice with speech synthesis in a very simple way, here is the code:
function speak(text, type){
switch(type){
case 'answer':
// Initiate Speech Synthesis
speech('This is the Answer');
// After Speech Synthesis has finished
playVoice('voice_1.mp3');
break;
}
}
function speech(input){
// Fetch the available voices.
const voice = speechSynthesis.getVoices().filter(voice => voice.lang == 'en-US');
var msg = new SpeechSynthesisUtterance();
msg.voice = voice[0];
// Set the text.
msg.text = input;
// Queue this utterance.
window.speechSynthesis.speak(msg);
// Track if Speech Synthesis has finished
msg.onend = function(event) {
console.log('Speech has finished being spoken after ' + event.elapsedTime + ' milliseconds.');
}
}
So I want to run speech synthesis then after Speech Synthesis has finished in speech
function, I want to play audio that is in speak
function here:
// After Speech Synthesis has finished
playVoice('voice_1.mp3');
Guys, please tell me if there is any solution to do this that I'm missing?
What would you do if you were me?
Note: I want many different behaviors from speak
function and it makes it confusing how I want to deal with my issue:
function speak(text, type){
switch(type){
case 'answer':
// Initiate Speech Synthesis
speech('This is the Answer');
// After Speech Synthesis has finished
playVoice('voice_1.mp3');
break;
case 'question':
// Play an specific voice
playVoice('voice_2.mp3');
// Then Talk the text
speech('This is the Question');
// After Speech Synthesis has finished
playVoice('voice_3.mp3');
break;
}
}
Upvotes: 1
Views: 100
Reputation: 3543
This is what I wanted! After Start appears you have 2 seconds to click on anywhere on the page to play the speech synthesis...
console.log('Start')
setTimeout(function(){
let promise;
speak('this is a text', 'answer');
function speak(text, type){
switch(type){
case 'answer':
// Initiate Speech Synthesis
speech('This is the Answer');
// After Speech Synthesis has finished
onSpeechEnd()
break;
case 'question':
// Play an specific voice
playVoice('voice_2.mp3');
// Then Talk the text
speech('This is the Question');
}
async function onSpeechEnd() {
let result = await promise;
playVoice(result)
}
}
// Function
function speech(input){
// Fetch the available voices.
const voice = speechSynthesis.getVoices().filter(voice => voice.lang == 'en-US');
var msg = new SpeechSynthesisUtterance();
msg.voice = voice[0];
// Set the text.
msg.text = input;
// Queue this utterance.
window.speechSynthesis.speak(msg);
// Track if Speech Synthesis has finished
promise = new Promise((resolve, reject) => {
msg.onend = function(event) {
console.log('Speech has finished being spoken');
resolve('voice_1.mp3');
}
});
}
},2000)
function playVoice(voice){
console.log(voice)
}
Upvotes: 0
Reputation: 2452
Can you pass the mp3's filename to the "speech" function as a parameter, and call it on the "onend" function? Like this?
function speak(text, type){
switch(type){
case 'answer':
// Initiate Speech Synthesis & voice to play when done
speech('This is the Answer', 'voice_1.mp3');
break;
case 'question':
// Play an specific voice
playVoice('voice_2.mp3');
// Then Talk the text & voice to play when done
speech('This is the Question', 'voice_3.mp3');
break;
}
}
function speech(input,voiceToPlay){
// Fetch the available voices.
const voice = speechSynthesis.getVoices().filter(voice => voice.lang == 'en-US');
var msg = new SpeechSynthesisUtterance();
msg.voice = voice[0];
// Set the text.
msg.text = input;
// Queue this utterance.
window.speechSynthesis.speak(msg);
// After Speech Synthesis has finished
msg.onend = function(event) {
console.log('Speech has finished being spoken after ' + event.elapsedTime + ' milliseconds.');
if(voiceToPlay) {
console.log('Play voice.');
playVoice(voiceToPlay);
}
}
}
As for the question's case, where you have an mp3 file playing before and after your speech synthesis, I'd consider something along the lines of this to check what the duration of what the mp3 file is, and then use setTimeout for that length of time before executing the speech() function. I'm sure you can write a function that takes the audio file's path that you're passing to the "speech" function, do a look-up, and then return the duration in ms in a variable.
Here's a pen I forked from yours.
Upvotes: 1