I have implemented text to speech in javascript it is a funtion which create speech back to back process for different message. sometime before it was working fine but after updating chrome (auto update of window) it doesn't work so i have used artyom library which was also working fine. but now after update of windows again it does support speech again..
now both of the library is not support text to speech.. please help me somebody.. was stuck in this from last 1 month many times it work and after update it doen't i am not getting any standard solution please help...
if ( 'speechSynthesis' in window )
{
window.speechSynthesis.cancel();
//$(".divRandom").hide();
let speech = new SpeechSynthesisUtterance(msg);
voices = window.speechSynthesis.getVoices();
if ('speechSynthesis' in window) {
speech_voices = window.speechSynthesis.getVoices();
window.speechSynthesis.onvoiceschanged = function() {
speech_voices = window.speechSynthesis.getVoices();
};
}
speech.voice = speech_voices[1];
//speech.lang = "en-US";
speech.volume = 2;
if (speed > 1)
speech.rate = 3;//slow speaking
else
speech.rate = 7;//faster
speech.pitch = 1;
window.speechSynthesis.speak(speech);
}
else
{
/*var Jarvis = new Artyom();
Jarvis.ArtyomVoicesIdentifiers["en-GB"] = ["Google UK English Female", "Google UK English Male", "en-GB", "en_GB"];
//Jarvis.say(msg);
//Jarvis.ArtyomProperties["speed"] = 3;
Jarvis.say(msg.toString(),{
onStart:function(){
setTimeout(function(){
// Most likely to be true
console.log("Speaking : "+ Jarvis.isSpeaking().toString());
},500);
},
onEnd: function(){
setTimeout(function(){
// Most likely to be false
console.log("Speaking : "+ Jarvis.isSpeaking().toString());
},500);
}
});*/
alert("your browser doesn't support audio..");
}
Related
Upong calling audioElement.duraion returns infinite in chromium based browsers but works find in firefox. The song is stored locally in the same directory.
console.log("Welcome to Spotify | clone");
let songIndex = 0;
const masterPlay = document.getElementById("masterPlay");
const progressBar = document.getElementById("progressBar");
const gif = document.getElementById("gif");
const audioElement=document.getElementById("song")
// let audioElement=new Audio('./1.mp3')
// Handeling play pause and click
masterPlay.addEventListener('click', () => {
if (audioElement.paused || audioElement.currentTime <= 0) {
audioElement.play();
masterPlay.classList.remove("fa-circle-play");
masterPlay.classList.add("fa-circle-pause");
gif.style.opacity = 1;
}
else {
audioElement.pause();
masterPlay.classList.remove("fa-circle-pause");
masterPlay.classList.add("fa-circle-play");
gif.style.opacity = 0;
}
});
//EventListeners
audioElement.addEventListener("timeupdate", () => {
progress = ((audioElement.currentTime / audioElement.duration) * 100);
progressBar.value = progress;
console.log(audioElement.currentTime)
});
Expectations:
It returns the duration of the autio track.
What I tried:
Different browsers. (Works fine on firefox based browsers.)
Different song. (I found that some songs don't work on chrome but on firefox everything works.)
Tried using HTML audio element. (The problem persists)
Tried using JS audio(). (The problem still exists)
At the end of the day I found out that it was a bug with VS code Live Preview extension from Microsoft
I made this little script where you can enter some message and it reads it out.
I solved it by using FireFox SpeechSynthesis API.
How can I get more voices and support for more languages?
Note: There is a "bug" in SO. If I edit my question and edit the script and test it from there, then 4 voices are
loading. If I run the code snippet normally, then no voices are
loading, but the default voice.
if ('speechSynthesis' in window) {
// Speech Synthesis supported
} else {
// Speech Synthesis Not Supported
alert("Sorry, your browser doesn't support text to speech!");
}
const voices = speechSynthesis.getVoices();
populateVoiceList();
if (typeof speechSynthesis !== 'undefined' && speechSynthesis.onvoiceschanged !== undefined) {
speechSynthesis.onvoiceschanged = populateVoiceList;
}
var selectedLang = $("#voiceSelect").find("option").attr("data-lang");
var selectedVoice = $("#voiceSelect").find("option").attr("data-pos");
$("#voiceSelect").change(function() {
selectedLang = $(this).find("option:selected").attr("data-lang");
selectedVoice = $(this).find("option:selected").attr("data-pos");
});
$("#start").click(function() {
var msg = new SpeechSynthesisUtterance();
msg.text = $("#message").val();
msg.lang = selectedLang;
msg.voice = voices[selectedVoice];
console.log(msg);
window.speechSynthesis.speak(msg);
});
// Hide Dropdown if there is only one voice
if ($("#voiceSelect option").length == 0) {
$("#voiceSelect").hide();
}
function populateVoiceList()
{
if (typeof speechSynthesis === 'undefined') {
return;
}
for (let i = 0; i < voices.length; i++) {
const option = document.createElement('option');
option.textContent = `${voices[i].name} (${voices[i].lang})`;
if (voices[i].default) {
option.textContent += ' — DEFAULT';
}
option.setAttribute('data-lang', voices[i].lang);
option.setAttribute('data-name', voices[i].name);
option.setAttribute('data-voice-uri', voices[i].voiceURI);
option.setAttribute('data-pos', i);
document.getElementById("voiceSelect").appendChild(option);
}
}
.flex-container {
display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="voiceSelect"></select>
<div class="flex-container">
<textarea id="message" value="test"></textarea>
<button id="start">Start</button>
</div>
JSFiddle
How can I get more voices and support for more languages?
Currently there isn't a browser vendor that supports loading custom/more voices. It doesn't appear to be part of the nascent specification yet either, as there is an open issue asking how to add more voices.
The list of voices is dependent upon the user agent/device because that is how it is specified. User agents are using either a native speech engine provided by the device OS or a network based speech engine, each of which work with a set of supported voices. Here is a comment from a chromium issue about not being able to support boundary events because of the missing capabilities in the native/network based speech engines, as an example of the platform the Web Speech API is dependent upon.
If you want to see what voices are available for various devices/browsers you can go to https://morganney.github.io/tts-react/?path=/story/tts-react--hook and click the "load" button to get an HTML <select> of the SpeechSynthesisVoice's supported.
You can also run the snippet below to see what voices are available:
let voices = []
const btn = document.getElementById('load')
const options = document.getElementById('voices')
const hasSynth = 'speechSynthesis' in window
if (hasSynth) {
voices = speechSynthesis.getVoices()
speechSynthesis.addEventListener('voiceschanged', () => {
voices = speechSynthesis.getVoices()
})
}
btn.addEventListener('click', () => {
const initOpt = document.createElement('option')
if (!voices.length && hasSynth) {
voices = speechSynthesis.getVoices()
}
initOpt.append(document.createTextNode('-- select voice --'))
options.append(initOpt)
voices.forEach(voice => {
const option = document.createElement('option')
option.value = voice.name
option.append(document.createTextNode(`${voice.lang} - ${voice.name}`))
options.append(option)
})
options.style.display = 'inline'
})
options.addEventListener('change', (evt) => {
if (hasSynth) {
const utterance = new SpeechSynthesisUtterance()
utterance.text = 'Testing the selected voice.'
utterance.voice = voices.find(voice => voice.name === evt.target.value)
speechSynthesis.speak(utterance)
}
})
#voices {
display: none;
}
<button id="load">click to load voices</button>
<select id="voices">
</select>
I have slightly altered your code and have a working version here: https://jsfiddle.net/lharby/j36nbhy1/
First we set synth variable and also a let to initialise voices as an empty array which we can push to later
const synth = window.speechSynthesis;
let voices = [];
Then we have to pass voices = synth.getVoices(); inside our populateVoiceList function as the call to it works asynchronously.
Then I changed the for loop, for a forEach function like so:
voices.forEach((item, index) => {
const option = document.createElement('option');
option.textContent = `${item.name} (${item.lang})`;
option.setAttribute('data-lang', item.lang);
option.setAttribute('data-name', item.name);
option.setAttribute('data-voice-uri', item.voiceURI);
option.setAttribute('data-pos', index);
document.getElementById("voiceSelect").appendChild(option);
});
I think the rest is pretty much the same, but let me know if you get issues. I did have to make a couple of edits in order to test.
So it switches the initial rain video file for a different one, but the new one doesn't even reach the length of the video before it gets stuck. Same thing with different files. The initial file works just fine, and it's 10x the size. Very confused. p2 is a text box and no, I don't know why I called it that. Works just fine in Chrome but not Firefox.
function phase2(){
rain.src = "BloodRain2.0.mp4"
rain.play()
rain.loop = true;
p2.style.display = "initial";
p2.value = "Oh no...";
phase2_tr = true; //trigger to reference phase 2 later on
phase_def = 1.3; //update stats for phase 2
phase_mdef = 1.2;
setTimeout(() =>{
p2.style.display = "none";
document.getElementById("boss_img").src = "AKUMU2.0.jpeg";
phase1_theme.pause();
const phase2_theme = new Audio('phase2OST.mp3')
phase2_theme.play();
phase2_theme.loop = true;
roar.play();
roar.loop = false;
document.getElementById("boss_name").innerHTML = "Akumu, Origin of the Nightmare";
ostbox.value = "Now playing: \n Bloodborne OST: The Hunter - Phase 2";
}, 4000);
setTimeout(()=>{
const xtraThunder = new Audio("xtrathunder.mp3")
xtraThunder.play();
xtraThunder.loop = true;
}, 5000);
}
The intial file is right up top like so:
var rain = document.getElementById("rainbg")
rain.loop = true;
What about removing the element like so
var rain = document.getElementById("rainbg");
document.removeChild(rain);
Then try your code again.
I enter to browser this link
https://google.com.vn;
Google redirect to https://www.google.com.vn;
I want alert full url redirect.
I used this code:
processNewURL: function(aURI) {
var tabIndex = gBrowser.tabContainer.selectedIndex;
var referredFromURI = gBrowser.tabContainer.childNodes[tabIndex].linkedBrowser.webNavigation.referringURI.spec;
alert(referredFromURI);
},
But it always alert https://www.google.com.vn,
and I tested with some short link example bit.ly/R9j52J . It isn't ok.
Please help me.
this works, i also show 2 methods to get to webNavigation. the second method is just longed winded way to teach other stuff, recommended way is method 1.
var processNewURL = function(e) {
console.log('e:', e);
var win = e.originalTarget.defaultView;
//start - method 1 to get to webNav:
var webNav = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation);
var referredFromURI = webNav.referringURI;
//end - method 1
//start - method 2 long winded way:
/*
var domWin = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var tab = domWin.gBrowser._getTabForContentWindow(win);
//console.log('tab:', tab);
var referredFromURI = tab.linkedBrowser.webNavigation.referringURI;
*/
//end - method 2
if (referredFromURI != null) {
win.alert('referred from:' + referredFromURI.spec);
} else {
win.alert('not redirected');
}
}
gBrowser.addEventListener('DOMContentLoaded', processNewURL, false);
I wrote a HTML5 webpage consisting only of:
<input type="text" style="font-size: 40px;" name="speech" size="50" x-webkit-speech/>
What I'm trying to do is to get the x-webkit-speech to start automatically as soon as I enter the page and continously put out the speech recognition results into the text. How would I do that ? I've seen various javascripts relating to that and I tested a lot of them but they don't work for me.
Thanks to anyone who answers ! ;)
You can try to use Web Speech API, for example:
if ('webkitSpeechRecognition' in window) {
var recognition = new webkitSpeechRecognition();
var final_transcript = '';
recognition.continuous = true;
recognition.interimResults = true;
recognition.onresult = function( event ) {
var final_transcript = '';
for (var i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
}
}
document.getElementById( 'speech' ).value = final_transcript;
};
recognition.start();
}
The only one thing is that you will need to allow page to use microphone at page load
jsFiddle demo