← All posts

Tutorials

Stop video and audio autoplay on every page

Few things are worse than opening a tab and getting blasted with sound. Browser autoplay policies help, but muted video still moves and background audio still slips through. A JustZix rule shuts it all down the instant it starts.

The strategy

Instead of trying to predict which element will autoplay, you react. Every media element fires a play event when it starts. Listen for that event in capture mode, and if the playback was not started by you, pause it.

document.addEventListener('play', function (e) {
  var m = e.target;
  if (m && (m.tagName === 'VIDEO' || m.tagName === 'AUDIO')) {
    m.pause();
  }
}, true);

This is blunt: it pauses everything, including videos you click. The full recipe below adds an allow-list so your own clicks still work.

Pause autoplay but keep clicks working

The trick is to record a timestamp whenever the user interacts with the page. If a play event fires far from any interaction, it is autoplay and gets paused.

(function () {
  var lastInteraction = 0;
  ['pointerdown', 'keydown', 'touchstart'].forEach(function (evt) {
    document.addEventListener(evt, function () {
      lastInteraction = Date.now();
    }, true);
  });

  document.addEventListener('play', function (e) {
    var m = e.target;
    if (!m || (m.tagName !== 'VIDEO' && m.tagName !== 'AUDIO')) { return; }
    var sinceClick = Date.now() - lastInteraction;
    if (sinceClick > 800) {
      m.pause();
      m.autoplay = false;
    }
  }, true);
})();

An 800 millisecond window is generous enough to count a click as intentional while still catching media that starts on page load. Setting autoplay = false stops the element from retrying.

Mute as a fallback

Some players are persistent and restart playback in a loop. Rather than fight an endless pause battle, mute first so the page is at least silent, then pause.

document.addEventListener('play', function (e) {
  var m = e.target;
  if (m && (m.tagName === 'VIDEO' || m.tagName === 'AUDIO')) {
    m.muted = true;
    m.volume = 0;
    m.pause();
  }
}, true);

Muting plus zero volume covers both the simple muted flag and players that read volume directly.

Default new media to muted

You can also be proactive. This rule mutes any media element as soon as it appears, before it has a chance to make noise. It pairs well with the pause logic above.

(function () {
  function mute(m) {
    m.muted = true;
    m.setAttribute('muted', '');
  }
  document.querySelectorAll('video, audio').forEach(mute);
  new MutationObserver(function (records) {
    records.forEach(function (rec) {
      rec.addedNodes.forEach(function (n) {
        if (n.nodeType !== 1) { return; }
        if (n.tagName === 'VIDEO' || n.tagName === 'AUDIO') { mute(n); }
        else if (n.querySelectorAll) {
          n.querySelectorAll('video, audio').forEach(mute);
        }
      });
    });
  }).observe(document.documentElement, { childList: true, subtree: true });
})();

Things to watch for

Pick up a ready version in our ready-made examples or download JustZix. Once pages are quiet, you may want real controls back — see force native controls on every video.

Rate this post

No ratings yet — be the first.

Try it yourself

Install JustZix and paste any snippet from this article. Two minutes from zero to a working rule across all your devices.

Get JustZix

Features · How it works · Examples · Use cases