Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript Native Language Text-To-Speech

I'm making a project for school where we'll teach children to calculate for the first time. Unfortunately these children can't read so the task will be spoken to them in there native language, which in this case is Dutch.

I've been looking around and most text-to-speech javascript libs provide great support for English, but not for any other language. Also the HTML5 speechSynthesis doesn't support Dutch:

Speech synthesis voices currently supported in Chrome 35

In further research I've come across an article where you can use Google Translate Voice to generate any text into speech.

You take this as a base URL: http://translate.google.com/translate_tts

Attach your language you want so in my case Dutch

http://translate.google.com/translate_tts?tl=nl

and attach your text:

"This is a test" translated to Dutch

You would expect this to work with longer text but it doesn't.

Text to speech which is not working

Are there any other solutions? The Google Voice speaks Dutch pretty well so I would like the link to somehow work.

like image 254
timr Avatar asked May 29 '14 12:05

timr


People also ask

What is SpeechSynthesisUtterance in JS?

The SpeechSynthesisUtterance interface of the Web Speech API represents a speech request. It contains the content the speech service should read and information about how to read it (e.g. language, pitch and volume.)

How do I turn off text to speech in JavaScript?

cancel() The cancel() method of the SpeechSynthesis interface removes all utterances from the utterance queue. If an utterance is currently being spoken, speaking will stop immediately.

How do I make text to speech in HTML?

On any web page, open up the developer tools console and enter the following code: speechSynthesis. speak(new SpeechSynthesisUtterance("Hello, this is your browser speaking.")); Your browser will speak the text "Hello, this is your browser speaking." in its default voice.


1 Answers

DISCLAIMER: This is probably not allowed by Google. Don't use this without permission from Google.

It's possible to use Google's text to speech with texts of any size. It requires a little tweaking though.

Here's the script:

function textToSpeech(text, language) {
    if(text === undefined || text === null || text.length === 0)
        return

    var vid = document.createElement("video")
    var textParts = []

    text.split(" ").forEach(function(word) {
        var textPartsIndex = textParts.length - 1
        var currentStr = textParts[textPartsIndex]
        if(currentStr !== undefined && currentStr.length + word.length < 100)
            textParts[textPartsIndex] += " " + word
        else
            textParts.push(word)
    })

    function play(txt) {
        vid.src = "http://translate.google.com/translate_tts?tl=" + language + "&q=" + txt
        vid.load()
        vid.play()
    }

    var partIndex = 0
    play(textParts[partIndex])

    vid.addEventListener("ended", function() {
        var part = textParts[++partIndex]
        if(part !== undefined)
            play(part)
        else
            vid.removeEventListener("ended")
    })
}

BEFORE using it you must close all Chrome browser instances and, on a windows machine, open "Run" (WIN+R) and type "chrome --no-referrers" without "

On your page, you can now write (I don't understand dutch, so it's just some sample text I found)

textToSpeech("Ik ga ervan uit dat de mens een groot vermogen bezit om externe informatie op te slorpen ,\" legt professor Georges uit . Hij kan zelfs 5 tot 6 maal méér informatie verwerken dan het debiet van het gesproken woord , 120 woorden per minuut . Teamgeest is voor mij geen ijdel woord . In de tweede plaats komen puur betekenisloze verhaspelingen niet in aanmerking , want die zijn niet ontstaan door verwarring met een ander woord .", "nl")

If your application is only run locally, ie not hosted, you don't have to run chrome with the --no-referrers command.

The reason for disabling referrers is that Google cancels your request if there's a referrer-header.

IFRAME VERSION WHICH DOESN'T REQUIRE --no-referrers

http://jsfiddle.net/9tTeg/

<body>
<script>
textToSpeech("Ik ga ervan uit dat de mens een groot vermogen bezit om externe informatie op te slorpen ,\" legt professor Georges uit . Hij kan zelfs 5 tot 6 maal méér informatie verwerken dan het debiet van het gesproken woord , 120 woorden per minuut . Teamgeest is voor mij geen ijdel woord . In de tweede plaats komen puur betekenisloze verhaspelingen niet in aanmerking , want die zijn niet ontstaan door verwarring met een ander woord .", "nl")

function textToSpeech(text, language) {
    if(text === undefined || text === null || text.length === 0)
        return

    var vid = document.createElement("iframe")
    document.body.appendChild(vid)
    var textParts = []

    text.split(" ").forEach(function(word) {
        var textPartsIndex = textParts.length - 1
        var currentStr = textParts[textPartsIndex]
        if(currentStr !== undefined && currentStr.length + word.length < 100)
            textParts[textPartsIndex] += " " + word
        else
            textParts.push(word)
    })

    function play(txt) {
        vid.src = "http://translate.google.com/translate_tts?tl=" + language + "&q=" + txt
    }

    var partIndex = 0
    play(textParts[partIndex])

    var intervalId = setInterval(function() {
        var part = textParts[++partIndex]
        if(part !== undefined)
            play(part)
        else
            clearInterval(intervalId)       
    }, 9000)
}
</script>
</body>

Improvements: Instead of separating the string by words, use dot and comma, so the pauses are more natural. Each part is currently being played with 9 seconds each, but if the words are grouped by dots and commas, you could instead calculate the amount of time each part has by looking at the length of the part, since 9 seconds might be too much then.

like image 95
Jan Sommer Avatar answered Sep 23 '22 00:09

Jan Sommer