javascripthtml5-audiokey-events

How can I play audio elements in sync with key presses?


HTML

<textarea id="words" name="words"></textarea>
<audio id="type" src="type.mp3"></audio>

JS

document.getElementById('words').onkeydown = function(){
    document.getElementById('type').play();
}

I want to make type.mp3 to play anytime I press any key.

But, it is not played in sync with the key.

I am looking for a pure JS solution.


Solution

  • The audio media element depends on the buffering mechanism of the browser and may not play instantly when play is called.

    To play sounds in sync with key-presses you would have to use the Web Audio API instead which allows you to play a in-memory buffer and therefor instantly.

    Here is an example of how you can load and trigger the sound:

    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    
    var request = new XMLHttpRequest(),
        url = "https://dl.dropboxusercontent.com/s/8fp1hnkwp215gfs/chirp.wav",
        actx = new AudioContext(),
        abuffer;
    
    // load file via XHR
    request.open("GET", url, true);
    request.responseType = "arraybuffer";
    request.onload = function() {
      // Asynchronously decode the audio file data in request.response
      actx.decodeAudioData(request.response,
        function(buffer) {
          if (buffer) {
            abuffer = buffer; // keep a reference to decoded buffer
            setup();          // setup handler
          }
        }
      )
    };
    request.send();
    
      // setup key handler
    function setup() {
      document.getElementById("txt").onkeydown = play;
    }
    
      // play sample - a new buffer source must be created each time
    function play() {
      var src = actx.createBufferSource();
      src.buffer = abuffer;
      src.connect(actx.destination);
      src.start(0);
    }
    <textarea id=txt></textarea>

    (note: there seem to be a bug in Firefox at the time of this writing reporting a column which does not exist in the code at the send() call - if a problem, try the code in Chrome).