1

Good Morning everybody,

I am still working on a questionnaire for illiterate people. For that I am using a Text to Speech application (thanks to @JO3-W3B-D3V)

The Problem is that the questionnaire will be developped in several languages, which means, that the text to speech application has to support several languages as well.

SpeechSynthesis.getVoices()

If I understood it correctly, the function above returns a list of all objects representing all the available voices on the current device. Now to my questions:

  1. Is there a way to return a selection of these languages? For example, the listshould not return all 15 languages which are available on the device, but only 4 chosen ones?

  2. Is there a way to add more languages to the device? I am using Chrome. If I understood it correctly Chromes gets the languages from Microsoft and Google. Therefore Chrome should display new language-option if I add a new language to my operation system (Windows 10). Is that assupmtion correct? I am asking because I did that already and nothing changed, so I might be missing something.

Hope my questions make sense :)

Have a great day!

InPanic
  • 155
  • 1
  • 14

1 Answers1

1

Explained

Okay, so I'll answer this in two parts, considering the fact that you've kinda asked two questions, both are relatively simple & straightforward thankfully.

Question One

You've asked how to get _ chosen languages that you'd like to support, well that's simple, it's as easy as manipulating an array, within my example I've used the reduce function, fairly straightforward stuff.

P.S. For the sake of some form of consistence, I've written this snippet in a very similar fashion to the one that I wrote in the other question that you asked regarding speechSynthesis.

Assumptions

As stated within the code comments, I've written this snippet in such a way that there's no duplicated entries, i.e. within the snippet below, you will end up with a list that only contains one entity that supports the English language. In other words, you won't have both en-GB & en-US, of course you can change this, I just assumed that you'd want this type of feature, of course this is down to you & your requirements entirely.

// IIFE for the sake of it. 
(function() {
  "use strict";

  // This is a simple list of languages that you wish to support. 
  var supportedLanguages = ['en', 'de', 'es', 'fr'];
  var languages = [];

  // This is essentially similar to jQuery's $.ready.
  var ready = function(callback) {
    var d = document,
      s = d.readyState;

    // DOMContentLoaded was fired
    if (s == "complete" || s == "loaded" || s == "interactive") {
      callback();
    } else {
      if (d.addEventListener) {
        d.addEventListener("DOMContentLoaded", callback, false);
      } else {
        d.attachEvent("onDOMContentLoaded", callback);
      }
    }
  };

  // This is just a simple function to process whether or not you'd like to
  // push a voice onto the array or not.
  var shouldPush = function(array, object) {
    var language = object.lang || '';
    var snipped = language.substring(0, 2);

    // Generate a list of all of the known languages. 
    var languageList = array.map(function(object) {
      return object.lang;
    });

    // Create a list of short hand language names.
    var snippedList = languageList.map(function(language) {
      return language.substring(0, 2);
    });

    // Save having a bloated if statement, personally I find this 
    // more readable. 
    //
    // Only push relevant ones, saves having any duplicated entities, i.e. 
    // this will not allow for both en-US & en-GB to be among the list,
    // this can be altered, this is merely based on an assumption that you 
    // wouldn't want both en-US & en-GB, etc. 
    var isToPush = !snippedList.includes(snipped) &&
      !languageList.includes(language) &&
      supportedLanguages.includes(snipped);

    // If true, push to array.
    if (isToPush) {
      array.push(object);
    }

    // Then of course return the array object. 
    return array;
  };

  // This is essentially the list of voices that you've picked to support.
  var getSelectedLanguages = function() {
    languages = speechSynthesis.getVoices().reduce(shouldPush, []);
  };

  // A starting point for this snippet.
  var start = function() {
    speechSynthesis.onvoiceschanged = function() {
      getSelectedLanguages();
      console.log(languages);
    };
  };

  // Run the code when ready.
  ready(start);
})();

Question Two

I'm not entirely sure if there's a "clean & easy" way to do this, having conducted my own research on the matter I've found that it looks like this would require some form of tinkering. One of the better sources of information that I've found is this question.

Having further looked into this question, it looks like Artyom also suggests that there's no simple way to achieve this, it looks like you can only add a language by installing the language into the operating system, so I'm lead to believe.

Conclusion

One possible idea is that you could, and I emphasise the word could possibly do this via implementing an API of your own, however I can't imagine this would be a solid or reliable implementation, as my conclusion is based on research suggests in order for an additional language to be included, the user is somewhat responsible for that, as it looks like it needs the user to have _ language installed on their OS in order for speechSynthesis to make use of _ language.

I actually find it a little odd that it appears that there's little/no formal documentation on this subject, rather I've just found mostly informal documentation, suggestions and assumptions. This could however be down to my lack of investigation, bear in mind that I've spent ~15 minutes at most looking into this issue.

Sources

  1. A link to flaviocopes.com regarding speechSynthesis.
  2. A link to Artyom.js, a library for speech related APIs.
  3. A link to a previous stack overflow question similar to the second part of this question.
  4. A link to a medium article.
  5. MDN documentation.
  6. A treehouse blog post.

While I may not have the answer that you desire for your second question, I hope that this entire answer has helped in some form or another! :)

JO3-W3B-D3V
  • 2,124
  • 11
  • 30
  • Thank you first of all. You confirmed als my thought, that there is a lack of information regarding my second question. I am still struggling abit regarding the code. Do I have to use it additionally to the one you provided in my first question? I also tried merging both codes but once again my lack of skill in not helping. – InPanic Feb 07 '19 at 13:26
  • @InPanic Could you show me what you've done or what you're trying to do and I'll just made a JSFiddle or something? – JO3-W3B-D3V Feb 07 '19 at 16:39