Home > Software engineering >  How to avoid keyboard control to audio in JS
How to avoid keyboard control to audio in JS

Time:12-27

I have a very simple application that will display typing audio when user typing something and will stop the audio when user stop typing.

Here is the code:

let audio = new Audio('https://www.fesliyanstudios.com/play-mp3/768')
let timeout;
let input = document.querySelector('input')
input.onkeydown=function(){
    window.clearTimeout(timeout)
   audio.play()
   
}
input.onkeyup= function(){
    window.clearTimeout(timeout)
    timeout = setTimeout(()=>{audio.pause()},1000);
}
<input></input>

However, I found that there is a start/stop audio/video key (F8 key in some keyboard) on my keyboard and if user pressed this key, the typing audio will be played. "

Is there a way that I could avoid this from happening?

Thanks for any responds!

CodePudding user response:

This is a good question! The answer is that the browser assumes anything in a standard media element is controllable externally, so play/pause control can be done by keyboards, Bluetooth controllers, lock screen controls, etc.

A solution is to use the Web Audio API for playback instead. This is probably better for your use case anyway, as it gives you more control over the buffering and timing of your audio sample.

You'll first get the audio source data, decode it to a PCM buffer, and then play it back through an AudioBufferSourceNode. Untested code, but try something like this in an async function:

// Set up audio context and source node
const audioContext = new AudioContext();
const sourceNode = audioContext.createBufferSource();
sourceNode.connect(audioContext.destination);

// Make HTTP request for audio data
const res = await fetch('https://www.fesliyanstudios.com/play-mp3/768');
if (!res.ok) {
  throw res.status;
}

// Get the raw data and decode it to PCM
sourceNode.buffer = await audioContext.decodeAudioData(
  await res.arrayBuffer()
);

// Start playback
sourceNode.start();

Note that you should only create this audio context when there is user interaction. If you want to create it early, you can always call .resume() with user interaction. This is required to avoid autoplay policy issues

Hopefully this gets you started!

  • Related