Peertube background video & video element

Hello,
I would like to play Peertube videos from my own selfhosted server instead of using vimeo / youtube.

I’m now acting directly in the DOM, so I can replace a YT/Vimeo video with the Peertube + Peertube js CDN https://unpkg.com/@peertube/embed-api/build/player.min.js

But I would like to solve this in a cleaner way, is there a way to do a plugin / function in in functions php to add this special control ? (so I avoid loading unnecessary libs)

In any case, I also propose this a FR as Peertube is the only way to self-stream videos.

Cheers

This is my current code + lib enqueue in the child theme

/**
 * PeerTube Background Enhancer for Bricks Builder v0.1
 *
 */

(function () {
  "use strict";

  function isPeerTubeURL(url) {
    return (
      url &&
      (url.includes("/videos/embed/") ||
        url.includes("/w/") ||
        url.includes("peertube"))
    );
  }

  function getPeerTubeEmbedURL(url) {
    if (url.includes("/videos/embed/")) {
      return `${url}?autoplay=1&muted=1&loop=1&controls=0`;
    }

    if (url.includes("/w/")) {
      const uuid = url.split("/w/")[1].split("?")[0];
      const baseUrl = url.split("/w/")[0];
      return `${baseUrl}/videos/embed/${uuid}?autoplay=1&muted=1&loop=1&controls=0`;
    }

    return url;
  }

  function replacePeerTubeVideo(videoElement) {
    const videoUrl = videoElement.src;
    if (!isPeerTubeURL(videoUrl)) return;

    const iframe = document.createElement("iframe");
    iframe.src = getPeerTubeEmbedURL(videoUrl);
    iframe.style.cssText = videoElement.style.cssText;
    iframe.setAttribute("allowfullscreen", "");
    iframe.setAttribute("allow", "autoplay; fullscreen");
    iframe.setAttribute("frameborder", "0");

    // Copy bricks attr.
    if (videoElement.autoplay) iframe.setAttribute("data-autoplay", "true");
    if (videoElement.loop) iframe.setAttribute("data-loop", "true");
    if (videoElement.muted) iframe.setAttribute("data-muted", "true");

    videoElement.parentNode.replaceChild(iframe, videoElement);

    console.log("PeerTube video replaced:", videoUrl);
  }

  function processPeerTubeVideos() {
    // Background videos
    const backgroundVideos = document.querySelectorAll(
      ".bricks-background-video-wrapper video"
    );
    backgroundVideos.forEach((video) => {
      if (
        isPeerTubeURL(video.src) &&
        !video.hasAttribute("data-peertube-processed")
      ) {
        video.setAttribute("data-peertube-processed", "true");
        replacePeerTubeVideo(video);
      }
    });

    //Video elements
    const normalVideos = document.querySelectorAll(".brxe-video video");
    normalVideos.forEach((video) => {
      if (
        isPeerTubeURL(video.src) &&
        !video.hasAttribute("data-peertube-processed")
      ) {
        video.setAttribute("data-peertube-processed", "true");
        // Controls
        const embedUrl = getPeerTubeEmbedURL(video.src).replace(
          "controls=0",
          "controls=1"
        );
        const iframe = document.createElement("iframe");
        iframe.src = embedUrl;
        iframe.style.cssText = `width: 100%; height: 100%; border: none;`;
        iframe.setAttribute("allowfullscreen", "");
        iframe.setAttribute("allow", "autoplay; fullscreen");
        iframe.setAttribute("frameborder", "0");

        video.parentNode.replaceChild(iframe, video);
        console.log("PeerTube normal video replaced:", video.src);
      }
    });
  }

  /**
   * Watch DOM for Lazy loaded stuff
   */
  function startObserver() {
    const observer = new MutationObserver(() => {
      setTimeout(processPeerTubeVideos, 100);
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true,
    });
  }

  /**
   * Init
   */
  function init() {
    processPeerTubeVideos();
    startObserver();
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", init);
  } else {
    init();
  }
  
  window.processPeerTubeVideos = processPeerTubeVideos;
})();