-
-
Save wesbos/cd16b8b1815825f111a2 to your computer and use it in GitHub Desktop.
// paste in your console | |
speechSynthesis.onvoiceschanged = function() { | |
var msg = new SpeechSynthesisUtterance(); | |
msg.voice = this.getVoices().filter(v => v.name == 'Cellos')[0]; | |
msg.text = Object.keys(window).join(' '); | |
this.speak(msg); | |
}; |
Love it!
LOL awesome!
Bad News is pretty great, too.
this is amazing
:D
AWESOME! :D
Nice one Wes! Made some minor tweaks to find unique globals by comparing current globals to an iframe's globals.
( function() {
"use strict";
const getGlobals = callback => {
var iframe = document.createElement( "iframe" );
iframe.addEventListener( "load", () => {
const windowKeys = Object.keys( window );
const iframeKeys = Object.keys( iframe.contentWindow );
const uniqueKeys = windowKeys.reduce( ( memo, key ) => {
if ( !~iframeKeys.indexOf( key ) ) {
memo.push( key );
}
return memo;
}, [] );
callback ( uniqueKeys );
} );
iframe.src = "about:blank";
document.body.appendChild( iframe );
}
const msg = new SpeechSynthesisUtterance();
msg.voice = speechSynthesis.getVoices().filter( v => v.name == "Cellos" )[ 0 ];
getGlobals( keys => {
console.log( keys );
msg.text = keys.join( " " );
speechSynthesis.speak( msg );
} );
} () );
In case you're wondering, use speechSynthesis.cancel()
to shut it up.
Took @elijahmanor's code and added a iframe.remove()
after callback is made, to cleanup resulting iframes. I threw this into a bookmarklet maker. Baby, you got yourself a stew going!
"use strict";
(function () {
(function () {
"use strict";
var getGlobals = function getGlobals(callback) {
var iframe = document.createElement("iframe");
iframe.addEventListener("load", function () {
var windowKeys = Object.keys(window);
var iframeKeys = Object.keys(iframe.contentWindow);
var uniqueKeys = windowKeys.reduce(function (memo, key) {
if (! ~iframeKeys.indexOf(key)) {
memo.push(key);
}
return memo;
}, []);
callback(uniqueKeys);
iframe.remove();
});
iframe.src = "about:blank";
document.body.appendChild(iframe);
};
var msg = new SpeechSynthesisUtterance();
msg.voice = speechSynthesis.getVoices().filter(function (v) {
return v.name == "Cellos";
})[0];
getGlobals(function (keys) {
console.log(keys);
msg.text = keys.join(" ");
speechSynthesis.speak(msg);
});
})();
Ahahah this is amazing. Only a bunch of developers would take a joke and build it out even more 😭
console.log(window.speechSynthesis.getVoices());
in google chrome give all the name voice with many languages
@groteworld nice addition to remove the iframe & a bookmarklet is a good idea.
@wesbos it's hard to not be a geek ;)
Damn you! Just redundified my js1k entry!
"Good News" 👍
👍
I was able to get all the voices to work on OS X with Chrome 49, but on Windows with Chrome 50 I'm not getting any of the named voices, just the boring Google ones. 😦
Awesome! You can also invoke speech synthesis from outside the onvoiceschanged
method:
var msg = new SpeechSynthesisUtterance();
msg.voice = speechSynthesis.getVoices().filter(v => v.name == 'Alex')[0];
msg.text = 'hi there from the dev tools console';
speechSynthesis.speak(msg);
In case you'd like to know what they all sound like (there's a bunch of funny ones)
var msgs = speechSynthesis.getVoices().map( (v, i) => { return { voice: v, text: `hi there from the voice named ${v.name}` }; }),
speaker = new SpeechSynthesisUtterance(),
halt = false;
function speakOne(i) {
if (halt) { halt = false; return; }
speaker.voice = msgs[i].voice;
speaker.text = msgs[i].text;
speechSynthesis.speak(speaker);
console.log(`Saying "${speaker.voice.name}"`);
}
function speakAll() {
var cursor = 0;
speaker.onend = () => (++cursor) >= msgs.length? true : speakOne(cursor); // chain each end
speakOne(cursor); // start the series
}
To bail, set halt
to true in the console. speechSynthesis.cancel()
will only cancel the currently speaking voice.
I like Bad News, Bells, Cellos, Hysterical, and the way the language-specific Google voices butcher the words "hi there from."
Call speakOne(i)
to listen to any specific voice by index, or speakAll()
to listen to them all.
I also gist
ed this here.
I've got Japanese too. Is this standard in all Chrome installs?
var msg = new SpeechSynthesisUtterance();
msg.voice = speechSynthesis.getVoices().filter(v => v.name == 'Google 日本語')[0];
msg.text = 'こんにちは皆さん!';
speechSynthesis.speak(msg);
@akenn The reason it's wrapped in the voiceschanged
eventlistener, is that the voices are loaded asynchronously and this way you can make sure that they actually exist before you start using them.
It's no problem when you just run the snippet in the dev console, but if it's embedded on a page and set to run immediately, you'll get an error.
Here's a pretty cool Pen to play around with the different voices.
@ToreJuloe oh good to know - thanks!
Why not use Array#find
? .filter(v => v.name == 'Cellos')[0]
→ .find(v => v.name == 'Cellos')
@msikma Not in my Opera/Chrome.
Its not working in Linux window.speechSynthesis.getVoices()
returns empty array no "voices" :(
Wow 👍
Love it!
Awesome!!
I really hope I wasn't the last one to find out this! Amazing 🎉
For an extra treat, change Cellos to Hysterical
sorry.