Solution 1 :

The waiting event should fit your needs.

You can try this demo while you simulate bad network with the dropdown in Chrome’s Network tab (e.g: Slow 3G)

const video = document.getElementById('mwe_player_0');
video.onwaiting = function() { console.log('onwaiting'); };
<video id="mwe_player_0" controls="" preload="none" style="width:800px;height:450px"><source src="" type="video/webm; codecs=&quot;vp8, vorbis&quot;"></video>

Note that this demo works with HTMLAudioElement as well (because it inherits HTMLMediaElement). The video demo is just easier to test.

Solution 2 :

If you want to start an event when the user pauses the audio then this snippet will do the job. I didn’t test it on mobile in the notification drawer but I think it’ll work.

const video = document.querySelector('video');

video.addEventListener('pause', (event) => {
  console.log('The Boolean paused property is now true. Either the ' + 
  'pause() method was called or the autoplay attribute was toggled.');

resource: audio element events

resource: pause event

I also found a helpful answer to what you are trying to do 2 (at least from what I understand) and why it’s a bad technique. Link to question

3 Events: stalled / waiting check the events resource

Problem :

When playing a live audio stream, like web radio, through <audio> or Audio(), the pause event can fire in (at least) three ways:

  1. user clicks on the pause button (with <audio controls>)
  2. user clicks the browsers global audio controls
    • iOS: Control Center
    • Android: browser’s notification drawer (at least Chrome, Opera, Firefox)
    • Desktop: Media Session API controls, but uninitialized, without explicit setActionHandler (might be hidden behind a flag as of now)
  3. a buffer underrun caused by various network conditions

Is it possible to distinguish between 1/2 and 3?

  • Ideally, there would be an event property like isTrusted, which I am missing
  • I have tried to guess, looking esp. at readyState and networkState, but both are very inconclusive, especially across browsers (e.g. the interpretation/semantics of HAVE_FUTURE_DATA vs HAVE_ENOUGH_DATA)
  • I have shied away from making a “decaying state machine”, juggling other events. A buffer underrun is often preceded by stalled events, and sometimes followed by ended events. A cross-browser implementation seems crazy complex and the danger of false positives very high.

Am I out of luck until Media Session lands everywhere?

Note: this question looks like a solution, but unfortunately isn’t — browsers handle live streams’ “ends” differently and inconsistently.


Comment posted by kubi

Thanks, but again, I’d have to set some flag, like

Comment posted by kubi

…tl;dr: I had looked at this & other events, still frustratingly implicit guess-work, at best.

Comment posted by Guerric P

Why do you have to deal with the

Comment posted by kubi


Comment posted by kubi

Nope, sorry. This just listens for the event, but does not discern its origin. Also, I am not trying to do any UA/mobile-sniffing in the classic sense.