如何在每次查看 youtube.com/watch 页面时运行脚本?

问题描述 投票:0回答:1

我正在编写一个 Chrome 扩展程序,该扩展程序应该在访问 Youtube 观看页面时运行

youtube.com/watch?
。我 10 年前读过这个问题,那里的解决方案似乎工作不一致。

我的

manifest.json
有这个。我相信这意味着
content.js
应该在每个 Youtube 页面上运行,而不仅仅是观看页面。

"content_scripts": [
    {
      "js": ["scripts/content.js"],
      "matches": ["https://www.youtube.com/*"]
    }
]

我的

content.js
文件当前有一个事件侦听器,我从这篇文章获得了它。我发现这不会在每次加载观看页面时运行。我有时需要刷新监视页面才能运行脚本。 从功能上讲,我正在读取视频的当前时间、持续时间和播放速度,以计算剩余观看时间。

document.addEventListener("yt-navigate-start", removeRemainingTime);
document.addEventListener("yt-navigate-finish", setupRemainingTimeDisplay);

let intervalId;

function setupRemainingTimeDisplay() {
  const video = document.querySelector("video");
  const timeWrapper = document.querySelector(".ytp-time-wrapper");

  if (timeWrapper && video) {
    // Create or find the existing span for remaining time
    let remainingTime = document.querySelector(".remaining-time");
    if (!remainingTime) {
      remainingTime = document.createElement("span");
      remainingTime.className = "remaining-time";
      remainingTime.style.color = "#ddd";
      timeWrapper.appendChild(remainingTime);
    }

    // Update remaining time every second
    intervalId = setInterval(() => {
      updateRemainingTime(video, remainingTime);
    }, 1000);
  }
}

function updateRemainingTime(video, remainingTime) {
  const { duration, playbackRate, currentTime } = video;

  if (!duration || isNaN(playbackRate) || isNaN(currentTime)) {
    remainingTime.textContent = " • Invalid time";
    return;
  }

  const timeLeft = calculateRemainingTime(currentTime, playbackRate, duration);
  remainingTime.textContent = ` • ${formatTimestamp(timeLeft)} left`;
}

function calculateRemainingTime(currentTime, playbackRate, duration) {
  return Math.max((duration - currentTime) / playbackRate, 0);
}

function formatTimestamp(seconds) {
  const totalSeconds = Math.floor(seconds);
  const hours = Math.floor(totalSeconds / 3600);
  const minutes = Math.floor((totalSeconds % 3600) / 60);
  const secs = totalSeconds % 60;

  if (hours > 0) {
    return `${hours}:${String(minutes).padStart(2, "0")}:${String(
      secs
    ).padStart(2, "0")}`;
  } else {
    return `${minutes}:${String(secs).padStart(2, "0")}`;
  }
}

function removeRemainingTime() {
  const remainingTimeElements = document.querySelectorAll(".remaining-time");
  remainingTimeElements.forEach((element) => element.remove());
  clearInterval(intervalId);
}

如何确保每次访问 YouTube 观看页面时

content.js
都会运行?

youtube youtube-data-api
1个回答
0
投票

此问题有多种可能的解决方案。

一种选择是使用

history.pushState
,但 YouTube 默认情况下不会触发此事件。另一种方法是使用
MutationObserver
来检测页面内容何时发生更改。

结合这两种方法可能会产生更好的结果。

最佳方法取决于 content.js 文件中的逻辑。

这里有一个示例代码,演示如何使用

MutationObserver

const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation.type === 'childList') {
      const video = document.querySelector('video');
      if (video) {
        removeRemainingTime();
        setupRemainingTimeDisplay();
      }
    }
  });
});
© www.soinside.com 2019 - 2024. All rights reserved.