0

I have a vanilla JS web app that plays a sound in reaction to a certain event, and the press of a button stops the sound. That all works fine.

However, I recently started using a dedicated media play/pause button on my mouse and I notice that this button resumes playback of the last sound in that tab, even after it has already been cancelled.

Can I prevent this somehow? For stopping, I'm currently using the standard solution mentioned in this answer:

sound.pause();
sound.currentTime = 0;

This is in Firefox on Windows 10.

I thought of doing preventDefault on the key event since there is no reason to play/pause these (alarm) sounds as though they were media tracks. But basic research suggests that this event is handled by the browser and is not available to JS.

Luke Sawczak
  • 313
  • 4
  • 14

1 Answers1

1

As far as I know this behavior is not specified anywhere. Todays browsers somehow try to "do the right thing" when the user presses a hardware button to toggle sound.

There is a the Media Session Standard which allows to customize the experience but if it's not used browsers try to look for active media elements on the page to apply the events.

At least to my knowledge the Web Audio API is so far not hooked up to any hardware keys. If your files are reasonably small it might make sense to use an AudioBufferSourceNode instead of an audio element.

Anyway a quick fix which seems to work in Firefox and Chrome is to set the currentTime to the duration instead of setting it to zero.

sound.pause();
sound.currentTime = sound.duration;
chrisguttandin
  • 7,025
  • 15
  • 21
  • Nice idea in its simplicity! That worked. And of course for playing I just set currentTime to 0 (again with the idea that there is no intended play/pause behaviour in this app). Note that if the user pauses by using said media play/pause button, Firefox will pause the sound and it will never reach this line of code, and can be resumed by said button; but that's incidental because the app can still stop it intentionally when it does finish, and the alarm sounds are typically not long enough for this to happen by mistake anyway. – Luke Sawczak Feb 02 '22 at 01:01
  • I think you can prevent that by handling the `'pause'` events. They should fire although the pausing was initiated by the browser. The following should work: `sound.onpause = () => sound.currentTime = sound.duration;`. – chrisguttandin Feb 02 '22 at 08:13
  • Thanks -- sadly didn't work in Firefox (I also tried `sound.onpause = e => { e.preventDefault(); };` to no avail). – Luke Sawczak Feb 02 '22 at 18:02
  • I know it doesn't help but it worked for me. :-) I used the latest Firefox on macOS to test this. Are you using another operating system? – chrisguttandin Feb 03 '22 at 11:08