← All posts

Tutorials

Control video playback speed on any site

Most video players cap speed at 2x or hide the control entirely. The browser does not have that limit. A short JustZix rule gives you fine-grained speed control on every video on the page, no matter who built the player.

Why a rule beats the player UI

The native HTMLMediaElement exposes a playbackRate property. Player chrome is just a skin on top of it. When you set playbackRate directly you bypass the skin and talk to the element. JustZix lets you attach that code to a URL pattern so it runs automatically every time you open a matching page.

The minimal recipe

Create a JavaScript rule scoped to the sites where you watch long videos. This snippet sets every video to 1.5x and is safe to run more than once:

document.querySelectorAll('video').forEach(function (v) {
  v.playbackRate = 1.5;
});

That works for videos already in the DOM. Many sites load the player after the page, so you also want to catch videos that appear later.

Catching videos added later

A MutationObserver watches the document and applies your speed to any new video. It is defensive: it never throws if a node is not an element.

(function () {
  var target = 1.5;
  function apply(root) {
    var list = root.querySelectorAll ? root.querySelectorAll('video') : [];
    list.forEach(function (v) { v.playbackRate = target; });
  }
  apply(document);
  var obs = new MutationObserver(function (records) {
    records.forEach(function (rec) {
      rec.addedNodes.forEach(function (n) {
        if (n.nodeType === 1) {
          if (n.tagName === 'VIDEO') { n.playbackRate = target; }
          else { apply(n); }
        }
      });
    });
  });
  obs.observe(document.documentElement, { childList: true, subtree: true });
})();

One subtlety: some players reset playbackRate when a new clip starts. To survive that, also listen for the ratechange and loadeddata events and re-apply your value.

document.addEventListener('loadeddata', function (e) {
  var v = e.target;
  if (v && v.tagName === 'VIDEO') { v.playbackRate = 1.5; }
}, true);

The true third argument enables capture, so the handler fires even though media events do not bubble.

Keyboard shortcuts and a speed badge

Watching tutorials is easier when you can nudge the speed without hunting for a menu. This rule binds the bracket keys to step the speed and shows a small badge in the corner.

(function () {
  var speed = 1;
  var badge = document.createElement('div');
  badge.style.cssText = 'position:fixed;top:8px;right:8px;z-index:2147483647;'
    + 'background:#000;color:#fff;font:600 13px sans-serif;'
    + 'padding:4px 8px;border-radius:6px;opacity:0;transition:opacity .3s';
  document.body.appendChild(badge);
  function setSpeed(next) {
    speed = Math.min(5, Math.max(0.25, Math.round(next * 100) / 100));
    document.querySelectorAll('video').forEach(function (v) {
      v.playbackRate = speed;
    });
    badge.textContent = speed + 'x';
    badge.style.opacity = '1';
    clearTimeout(badge._t);
    badge._t = setTimeout(function () { badge.style.opacity = '0'; }, 1200);
  }
  document.addEventListener('keydown', function (e) {
    if (e.target && /INPUT|TEXTAREA/.test(e.target.tagName)) { return; }
    if (e.key === ']') { setSpeed(speed + 0.25); }
    if (e.key === '[') { setSpeed(speed - 0.25); }
    if (e.key === '\\') { setSpeed(1); }
  });
})();

The badge uses the highest practical z-index so it stays visible over fullscreen players, and it ignores keystrokes while you are typing in a form field.

Scoping the rule

Browse our ready-made examples for a copy-paste version of this rule, or download JustZix to start. When you are done with speed, the next step is reclaiming the picture-in-picture button — see add a picture-in-picture button to any 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