I've been experimenting with responsive voice for my html5 application. Apart from responsive voice, my app works stand-alone, with no need for the Internet, because the schools where I work have unreliable Internet connections.
I previously had a problem waiting for RV's javascript to load on a slow connection, which I solved using the preloader yepnope:
yepnope({
load: 'https://code.responsivevoice.org/responsivevoice.js',
callback: function (url, result, key) {
if (typeof responsiveVoice!="undefined"){
//code to activate RV functionality here
}
}
});
While testing this out, I realised the potential for something much better: yepnope automatically times out after 10 seconds if the script doesn't load and triggers the callback function anyway. That timeout can be changed, but what I'd like is, effectively, no timeout at all!
For example, if the students start using my app at 07:30 a.m. when the school's satellite dish barely works, then at 3 p.m. the clouds clear to make RV viable, it would be nice if the script finally loaded, triggered the callback and RV sprang into life.
So I have 3 questions:
In principle, is there any reason why I should not change the yepnope timeout from 10 seconds, to 12 hours? e.g.
yepnope.errorTimeout = 43200000;
I notice that yepnope has been deprecated. Can anyone recommend a similarly easy-to-use preloader with a no timeout option?
Would it be lighter on system resources to use setInterval? e.g.
var net_check = window.setInterval(yepnope, 18000); // try loading the script every 5 minutes
then if RV loads, cancel the setInterval:
yepnope({
load: 'https://code.responsivevoice.org/responsivevoice.js',
callback: function (url, result, key) {
if (typeof responsiveVoice!="undefined"){
clearInterval(net_check);
//code to activate RV functionality here
}
}
});
Thanks as always for any advice.
Edit: @Steyn van Esveld raised a really good point: "Is there any reason you can't download the responsivevoice.js and load it locally?"
In fact the RV script doesn't provide the text-to-speech voices itself - it's more of a facilitator. If your browser has native t-t-s support, it will use it, if not, they generate audio files (presumably from their website) and send them to your browser. Also, even Chrome's native t-t-s support evaporates if you are off-line. e.g. if you run:
voices = window.speechSynthesis.getVoices();
voices.length
from the console when offline, it returns "0".
This means I need a fallback if the Internet goes down after my app loads. The most reliable way I've found to do this is:
var rvStarted=false;
responsiveVoice.speak(vocEx, {onstart:function(){rvStarted=true;}});
setTimeout(function(){
if (rvStarted==false){
responsiveVoice.cancel();
audVoc.play(); //plays a backup off-line recording
}
},1000);
There is an onerror callback in the RV api, but it's vaguely documented, and I certainly cannot control the timeout myself as I can with this script.
After more research and experimenting, I've got a solution that works. If anyone can come up with something more efficient, I'd be delighted. First the code (explanation follows):
function loadRV() {
console.log("Trying to load RV");
inject.js('https://code.responsivevoice.org/responsivevoice.js',
function() {
if (typeof responsiveVoice!="undefined"){
clearInterval(net_check);
console.log("RV loaded");
// code here to turn on RV functionality
}
else {
console.log("RV load failed");
}
});
}
var net_check=setInterval(function(){
loadRV();
},60000);
loadRV();
Now the explanation:
Although this seems unwieldy, it's working very well so far. I've tested it with the three situations that I commonly face:
The setInterval has no appreciable effect on program execution, and the added functionality is quite transparent. If I connect the computer to the network and start a listening activity, about 1 minute later the RV voices will be added to my off-line recordings.
I doubt that many others face similar problems (I certainly would not wish them on anyone), but if so, I do hope this helps.