javascriptmedia-playertampermonkeyuserscripts

How to select the currently active / most recently focused video on a page with multiple videos?


On a page with multiple videos the currently active / most recently focused video reacts to standard keyboard actions like Space to play/pause the video or F to toggle full screen mode. This is already the case after initially selecting/clicking the respective video. But how to select this video to be able to perform custom keyboard actions like S to access the settings?

I tried an click event listener on the document's body taking advantage of event delegation to select the closest video wrapper along with its containing video element. This, of course, only works if the video is clicked with the mouse and not if it is selected with the keyboard. But most importantly, it only works after the second click, because the first one apparently only activates the video in the first place.

So how does the browser do this and how can I mimic this behavior?

Edit: The video elements are generated dynamically. See here.


Solution

  • Use MutationObserver

    MutationObserver can be configured to detect video elements as they are dynamically added to the page. The current video can be detected by listening for the play event on the added videos.

    The following TamperMonkey script tracks the current (or last played) video.

    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      2025-05-11
    // @description  Detect last played video
    // @author       Friedrich Merz
    // @match        https://www.tagesschau.de/multimedia
    // @icon         https://www.google.com/s2/favicons?sz=64&domain=tagesschau.de
    // @grant        none
    // ==/UserScript==
    
    (function () {
      "use strict";
    
      let currentVideo;
    
      new MutationObserver((mutationList) => {
        for (const mutation of mutationList) {
          mutation.addedNodes.forEach((node) => {
            if (node.tagName === "VIDEO") {
              console.log("A new video was added");
              node.addEventListener("play", (e) => {
                currentVideo = e.target;
                console.log("playing video", currentVideo.src);
              });
            }
          });
        }
      }).observe(document.body, { childList: true, subtree: true });
    })();