September 2, 2015 10:19 am

Useful HTML5 Features, Part 6

In this article, we will be presenting a very simple audio game and in the meantime teach you about the newly implemented text-to-speech browser capabilities. The game or novel is just a series of audio messages, followed by a question to the user. Each user response plays him a different audio message but there is only one correct response that will move him to the next level. If he gets the question wrong, he will return to the first level (question).Useful HTML5 Features

[wpdm_file id=148]DEMO

TTS browser-support

The Speech Synthesis API has 53.95% support globally according to Can I use.

It is supported in:
1. Chrome 36+,
2. Safari 7+,
3. Opera 30+,
4. Chrome for Android 42+,
5. iOS Safari 7.1+

Currently, Firefox and IE do not provide any support for the TTS or Speech Synthesis API.

TTS in practice

UI

Our UI would consist only of radio inputs which will be used to get the user response to the question. We give them the following styles:

<style>
        input[type='radio'] {
            visibility: hidden;
        }
        input[type='radio'] + label {
            background-color: crimson;
            border: 1px solid #eee;
            padding: 10px;
            color: #fff;
            text-shadow: 0.1px 0.1px 0.2px #000;
            cursor: pointer;
        }

    </style>

In our markup, we only add one div in the body tag:

<div class="question">

</div>

The TTS audio game

We declare three global variables (the names are pretty self-explaining)

var currentQuestion = 1;
var replies = [];
var totalQuestions = 3;

Then, we check if the browser supports the TTS API and if it does – we initialize and declare the functions that the simple game will be using:

if (window.speechSynthesis) {
       askQuestion();
       //game logic here
       }
else {
       alert("To play, please use a better browser : )");
        }

We add a function that will add all replies for a particular question to our global variable:

function addReplies(newReplies) {
         replies[currentQuestion] = newReplies;
     }

Then, we declare a function that will return all replies for a particular question:

function showReplies(id) {
            var index = id.replace(/[^0-9]/g, "");
            speak(replies[currentQuestion][index]);
        }

Now, we actually define the function that works with the TTS API:

function speak(msg, callback) {
        var msg = new SpeechSynthesisUtterance(msg);
        msg.rate = 0.8;
        msg.onend = callback;
        window.speechSynthesis.speak(msg);
    }

You can see that first you have to create an instance of SpeechSynthesisUtterance and pass it the message you want converted to speech as an argument. We then define the rate or pace at which the message will be spoken (how fast or slow) which varies from 0.1 to 10. Then, we execute callback which is a function that will get called when the message has been pronounced (msg.onend) and which adds the options that the users would be able to select from, the event handlers for their replies and the particular audio that will be displayed to the users as a reply to their selection.

Our addOptions function adds all radio inputs for the question to the DOM and adds event handlers that will be executed when the user clicks on an input:

If the user has guessed the right answer, we increment the global variable currentQuestion and ask a new question. Otherwise, we start from scratch.

function addOptions(options, correctIndex) {
       var html = "";
        for (var i = 0; i < options.length;i++) {

           html += "<input type='radio' name='q' id='q" + i + "'>"
            html += "<label for='q" + i + "'>" + options[i] +"</label>";

        }

        $(".question").html(html);
        if (currentQuestion <= totalQuestions) {
            $("body").on("click", "input[type='radio']",function() {
               $("body").unbind("click");
                if ($(this).attr("id") === "q" + correctIndex ) {

                    showReplies($(this).attr("id"));
                    if (currentQuestion === totalQuestions) {
                         speak("You completed the game. Congratulations!", function() {
                            $(".question").html("<p class='xl-big'><span>GAME</span> COMPLETED!</p>");
                        });
                        return;
                    }
                    currentQuestion++;
                    askQuestion();



                }
                else {

                    showReplies($(this).attr("id"))
                    speak("Game over. Restarting.");
                    currentQuestion = 1;
                    askQuestion();

                }
            })
        }
    }

Our final function askQuestion just contains all questions, options and replies that the game has and displays the question corresponding to the current value of the currentQuestion variable:

function askQuestion() {

        switch (currentQuestion) {
            case 1:
            speak("You walk on a solitary road and a homeless person starts following you. What do you do?", function() {
                addOptions(["Fight with him", "Turn around and ask him what is he doing",
                    "Start running for your life"],2);
                addReplies(['It turns out he is a former US Navy Seal so he beats you until you fall in comma',
                    "He says he is here to kill you, pulls a knife from his pocket and eliminates you as you stay frozen.",
                    "You start running and the homeless man tries to catch up with you but your fear makes you escape with ease"]);
            });

            break;
            case 2:
                speak("You continue on your journey for hours without any signs of water and encounter a small bottle filled with shady liquid with greenish color. What do you do?",
                function() {
                    addOptions(["Drink it",
                        "Put it in your backpack"],1);
                    addReplies(['It appears that the bottle contains snake venom and you become immediately paralyzed and a slow and painful death follows.',
                        "You carefully put the bottle in your backpack and notice that a single drop of it, left on the bottle, kills the small  Pygmy Marmoset monkey you carry in yoour backpack  .",
                    ]);
                });

                break;
            case 3:
                speak("On your road, a young woman who is barely dressed appears and asks for help because she is being assaulted. What do you do?",function() {
                    addOptions(["Say that you are going to help her and wait for her attacker",
                        "Say that you are unable to help her and continue on your way"],1);
                    addReplies(["The attacker turns out to be the tallest guy you've met, weighting 200 kg and all muscled up. He punches you in the face and you fall into a comma",
                        "You continue on your journey and manage to see her attacker in the distance. It is something so big that you conclude that she was dealing with a grizzly bear."]);

                });
        }
    }

Conclusion

The Speech Synthesis API will have many uses in the web. From audio games to an email client that will read your emails out loud – everything is possible.

Author Ivan Dimov

Ivan is a student of IT, a freelance web designer/developer and a tech writer. He deals with both front-end and back-end stuff. Whenever he is not in front of an Internet-enabled device he is probably reading a book or traveling. You can find more about him at: http://www.dimoff.biz. facebook, twitter


Tutorial Categories:

Leave a Reply

Your email address will not be published. Required fields are marked *