Just the weekly tutorials.

How to Automatically Type a Pre-recorded Message Into a Textarea Using JavaScript with HTML Audio Sound (MP3)

This tutorial will explain how to use JavaScript timers (in particular setTimeout, not setInterval) and how to play HTML sounds, in "mp3" format. Audio tags will be used and also replicated(copied.) Copying a sound resource is done to avoid stutter, when the script is trying to play the same "mp3" sound using the same resources. If the sound file is long enough, and is fired quick enough, it may lead to sound replay overlap, which results in an abrupt stop and replay of the same file. In other words, it doesn't sound great, or acceptable for any practical purpose. Overall, the JavaScript source code below will be explained, to achieve the following effect:

Entering Your Own Message


Please wait until the previous message has finished typing. Then, click "Begin Typing" to automatically start typing your message in the textarea below, with HTML audio sounds in MP3 format.

Recording MP3 Sound Effects

I used Audacity sound recorder software to record each keystroke. I cropped them out into separate files and named them key1.mp3 through key7.mp3, and ones for space bar space1.mp3 through space3.mp3. So there are 7 total variations of a keystroke sound and 3 variations of the space bar sound. Audacity is free sound editing software, all I needed was a microphone and a spare keyboard to type on in front of it to capture the effects. The files are then exported in MP3 format. I tried using free sound effects I found online on other sites, however they were too crisp, and didn't really have that natural feel. So I decided to create my own instead. You can use them in your own projects, if you wish.

Preloading MP3 AUDIO Resources

It is common for a website to combine HTML, JavaScript and PHP. The following code is written in PHP. It loops through several MP3 sound files and lists them inside the "src" attribute of several audio tags.

Note: the sound effects (mp3) may not work in all browsers. Please use Chrome browser (my favorite) for ideal results.

This is our sound file canvas that will be used to create keystroke (keypress) sound effects every time a new character is typed into the textarea.

<!-- Preload keystroke MP3s//--> <?php for ($i=0;$i<7;$i++) { ?> <audio preload="" src="<?php print $URL; ?>/sfx/key<?php print $i + 1; ?>.mp3" id="key<?php print $i + 1; ?>"></audio> <?php } ?> <!-- Same as above, for space bar sound effects (they produce a distinct keystroke sound)//--> <?php for ($i=0;$i<3;$i++) { ?> <audio preload="" src="<?php print $URL; ?>/sfx/space<?php print $i + 1; ?>.mp3" id="space<?php print $i + 1; ?>"></audio> <?php } ?>

Of course, you can just type in HTML audio tags as follows. The script produces the exact same equivalent of the following code:

<!-- Preload keystroke MP3s//--> <audio preload="" src="http://www.learnjquery.org/sfx/key1.mp3" id="key1"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/key2.mp3" id="key2"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/key3.mp3" id="key3"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/key4.mp3" id="key4"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/key5.mp3" id="key5"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/key6.mp3" id="key6"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/key7.mp3" id="key7"></audio> <!-- Same as above, for space bar sound effects (they produce a distinct keystroke sound)//--> <audio preload="" src="http://www.learnjquery.org/sfx/space1.mp3" id="space1"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/space2.mp3" id="space2"></audio> <audio preload="" src="http://www.learnjquery.org/sfx/space3.mp3" id="space3"></audio>

The key here is the distinction between regular keystrokes (any character) and the space bar, which produces a slightly augmented sound. It is very distinct to the space bar key. The reason for this is that it makes the sound effects sound more natural. Without variety in keystroke sound this script would have sounded like a sewing machine. I tried.

The Source Code

The source code for this demo is very straightforward and quite simple. The comments above each line explain what's about to happen.

A custom function "random_to" is used to create a random number from 0 to the number argument passed to the "len" parameter. JavaScript doesn't have a convenient way to create whole random numbers. This function is often used in graphics demos and games I have written.

// Helper function to get a random number between 0 and "len" function random_to(len) { return Math.floor((Math.random() * len)); }

Each audio file is stored in a separate variable, they are loaded using document.getElementById JavaScript function on HTML audio tags. For example:

key[0] = document.getElementById("key1");

This loads the resource into key[0]. Then the method play() is used to play the sound. However, one more precaution takes place here.

key[0].cloneNode(true).play()

The function "cloneNode" creates a clone (or an exact copy) of an HTML element. "cloneNode" works on the DOM tree, that is, the entire HTML element structure of your website. By itself, it has nothing to do with playing sounds, we could have copied any HTML element. The purpose for using this function in this script is to avoid sound stutter. Every time the same resource is "played" using the play() function, it restarts the same sound all over again, without giving it a change to finish playing. By cloning the audio tag node over and over again, we create a new HTML element for each sound to be played. This allows us to play multiple sounds simultaneously without stutter. Very useful for demos and JavaScript video games.

The highlight of the code is the "type_message" function. We use a JavaScript "setTimeout" timer function. It is used in a recursive way. In other words, setTimeout is called from within "type_message" function, to call itself over and over again. Each time the function calls itself, the global "window.ci" will traverse forward by one character. If we reached the end of the message, we no longer fire the setTimeout function, which stops the script.

Here is the entire code of this script.

<script language = "javascript"> // Sound effect storage arrays var key = []; var space = []; // How slow or fast will the message type itself? // Delay 150 milliseconds between each keystroke. var MESSAGE_SPEED = 150; // Helper function to get a random number between 0 and "len" function random_to(len) { return Math.floor((Math.random() * len)); } // This is where we initialize our JavaScript application $(document).ready(function() { // Load 7 keystroke sound variations for (var i = 0; i < 7; i++) key[i] = document.getElementById("key" + (i + 1)); // Load 3 spacebar keystroke sound variations for (var i = 0; i < 3; i++) space[i] = document.getElementById("space" + (i + 1)); }); // Type in a single letter into the editor box function type_letter(letter) { var e = $("#editor"); var t = e.val(); e.val(t + letter); } // some global variables var ci = 0; var int = 0; var char = ""; // Auto-type an entire message into the editor box // This function will continue calling itself to type next character, one by one // until last character in "msg" is reached function type_message(msg) { // Message is shorter than 1 character, do nothing if (msg.length <= 0) return; var length = msg.length; if (window.ci < msg.length) { var letter = msg[window.ci]; var next_letter = ""; if (window.ci + 1 < msg.length) next_letter = msg[window.ci + 1]; type_letter(letter); // Play sound from a set of 7 keystroke for regular keys, // Play sound from a set of 3 keystrokes for the space bar to add sound variety if (next_letter == " ") space[random_to(3)].cloneNode(true).play(); else key[random_to(7)].cloneNode(true).play(); // Proceed to the next character in the message queue window.ci++; // Do it all over again, randomize message speed for a more natural sound effect setTimeout(function() { type_message(msg) }, random_to(70 + MESSAGE_SPEED)); } } </script>

How Can This Script Be Used in A Practical Setting?

What is the idea behind this typing script? It can be used in many scenarios. For me, while working on the free jQuery course that will be text-message and (optionally) voice-guided, as the learner goes through a set of various tasks, by typing jQuery code directly into the editor and observing immediate results in an adjacent window.

Online courses need to be at least to some degree interactive, in order to be engaging. In order to accomplish this, I decided to build a messaging system that was fun to interact with. This tutorial explained how I built this messaging system using JavaScript, jQuery. PHP and some HTML code, including playing mp3 files for each key stroke.

You can reuse this code in your own projects. If you are going to, please let me know. I would love to see it implemented elsewhere.

Just the weekly tutorials.