如何在JavaScript中使用cookie观看YouTube视频所花费的时间?

发布于 2025-01-30 01:10:39 字数 5714 浏览 1 评论 0原文

我正在寻找一种方法来自动跟踪每天看YouTube的时间(因此计时器在午夜重置)。捕获是,我希望计时器只能记录观看视频的时间,而不是计算浏览YouTube或暂停视频时的时间。我还没有找到可以实现此目的的浏览器扩展程序,因此我尝试使用称为页面操作器的Chrome扩展程序自己尝试执行此操作,该扩展程序将我自己的JavaScript代码注入YouTube网站。

我的代码通过使用视频元素的方法来计算视频上观看的时间,如所述在这里。由于我不希望计时器在YouTube关闭时重置,因此我的代码将观看YouTube观看的时间存储在一个名为TimeWatched的cookie中,该 将在其创建的午夜到期。计时器显示在YouTube视频上方,如< p>元素。

计时器有时会冻结而没有任何控制台错误,这可能是因为播放返回的计时对象有时是空的(零的长度),而似乎不应该是(因为您一直在播放视频)。怎么了?是否有一种更简单的方法可以实现我要做的事情?

我的代码:

max_time_in_minutes = 30;

//setCookie() and getCookie() are functions taken from w3schools
//https://www.w3schools.com/js/js_cookies.asp#:~:text=JavaScript%20can%20create%2C%20read%2C%20and,cookie%20property.
//I modified the setCookie() function to set the expiration date of the cookie to 11:59 pm on the current day
function setCookie(cname, cvalue) {
  const d = new Date();
  d.setHours(23, 59, 59, 999)
  let expires = "expires="+ d.toUTCString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

function getCookie(cname) {
  let name = cname + "=";
  let decodedCookie = decodeURIComponent(document.cookie);
  let ca = decodedCookie.split(';');
  for(let i = 0; i <ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}



function getCookieTime(){
  //Returns how much time is stored in the timewatched cookie (in seconds)
  //If there is no timewatched cookie, getCookie() will return a blank string
  //This function is called only once, 2 seconds after the page loads.
  
  var cookieTime = parseInt(getCookie("timewatched"))
  if(Number.isNaN(cookieTime)){
    //If there is no timewatched cookie, create one that's set to zero.
    console.log("Starting from zero...")
    cookieTime = 0;
    document.cookie = "timewatched:0"
  }
  return cookieTime;
}

function getTimeWatched(){
  //Returns how much time the user has spent watching YouTube,
  //including how much time was in the timewatched cookie at the time of the page load.
  
  //Add up all the times from the videoElement.played() array
  var playedLength = videoElement.played.length 
  var ttw = 0; //total time watched in seconds
  for(var i = 0; i < playedLength; i ++){
    ttw += videoElement.played.end(i) - videoElement.played.start(i)
  }
  
  //Last step: add the cookieTimeAtStart value to the sum.
  return ttw + cookieTimeAtStart;
}

function initiateTimer(){
  //This function is called 2 seconds after the page loads
  //The last line of code calls this function (see bottom)
  
  //Gets how many seconds are in the timewatched cookie at the start of the page load
  //If there is no timewatched cookie, one will be created and set to zero seconds
  cookieTimeAtStart = getCookieTime();
  
  
  videoElement = document.querySelectorAll("video")[0]
  pvideosrc = videoElement.src
  
  console.log("Cookie time at start: " + cookieTimeAtStart)
  
  totalTimeWatched = 0;
  
  //timerElement is the <p> element that will appear above the video that shows time spent watching.
  timerElement = document.createElement('p')
  timerElement.innerHTML = "this is the timer element" //This will be changed
  timerElement.setAttribute('style', 'font-size:15px; color:white')
  
  //divElement is a <div> element that already exists on the YouTube page. It will be the parent of the timerElement
  divElement = document.querySelectorAll('div[id="primary"][class="style-scope ytd-watch-flexy"]')[0]
  
  divElement.prepend(timerElement)
  
  updateTimer(); //updateTimer() is a recursive function that's called every 5 seconds
}

function updateTimer(){
  //This function is called every five seconds. It updates the totalTimeWatched variable
  
  
  //Check to see if the user has switched videos since the last timer update. If so,
  //recalculate cookieTimeAtStart
  //cookieTimeAtStart needs to be recalculated every time the user switches to a new video.
  //However, clicking on a new video does not refresh the YouTube page. As an alternative, we will
  //recalculate cookieTimeAtStart whenever the user clicks on anything that changes the src of the video element.
  videoElement = document.querySelectorAll("video")[0]
  var videosrc = videoElement.src
  if(videosrc !== pvideosrc){
    console.log("NEW PAGE!")
    cookieTimeAtStart = getCookieTime();
    console.log("Cookie time at start: " + cookieTimeAtStart)
  }
  pvideosrc = videosrc;
  
  totalTimeWatched = getTimeWatched();
  
  var ttwstr = Math.round(totalTimeWatched)
  
  //Store the total time watched in seconds in our timewatched cookie
  //The cookie will expire at midnight of the current day
  document.cookie = setCookie("timewatched", ttwstr.toString())
  
  //Update the timerElement to show the total time watched in minutes and seconds
  var minutes = Math.floor(totalTimeWatched / 60)
  var seconds = Math.round(totalTimeWatched) % 60
  seconds = seconds.toString()
  seconds = seconds.padStart(2,"0")
  timerElement.innerHTML = "Watch time today: " + minutes + ":" + seconds
  
  //If user has spent more than 30 minutes watching YouTube today, alert them.
  if(totalTimeWatched > max_time_in_minutes * 60 && totalTimeWatched < (max_time_in_minutes * 60) + 5)confirm("You have exceeded 30 minutes on YouTube today. Proceed?")
  
  //Call updateTimer() again in five seconds (recursive)
  setTimeout(updateTimer, 5000)
}

//initiateTimer() will be called 2 seconds after the page loads 
setTimeout(initiateTimer, 2000)

I'm looking for a way to automatically track how much time I spend watching YouTube each day (so the timer resets at midnight). The catch is, I want the timer to only log time spent watching videos, not counting time browsing YouTube or when a video is paused. I've not found a browser extension that can achieve this, so I've tried doing it myself by using a Chrome extension called Page Manipulator that injects my own Javascript code into the YouTube website.

My code calculates the time watched on a video by using the video element's played method as described here. Since I don't want the timer to reset when YouTube is closed, my code stores the time spent watching YouTube in a cookie called timewatched, which is set to expire on the midnight of the day it's created. The timer appears above the YouTube video as a <p> element.

The timer sometimes freezes without any console error, possibly because the timeRanges object returned by played is sometimes empty (length of zero) when it seems like it shouldn't be (because you've been playing the video). What's gone wrong? Is there a simpler way to achieve what I'm trying to do?

My code:

max_time_in_minutes = 30;

//setCookie() and getCookie() are functions taken from w3schools
//https://www.w3schools.com/js/js_cookies.asp#:~:text=JavaScript%20can%20create%2C%20read%2C%20and,cookie%20property.
//I modified the setCookie() function to set the expiration date of the cookie to 11:59 pm on the current day
function setCookie(cname, cvalue) {
  const d = new Date();
  d.setHours(23, 59, 59, 999)
  let expires = "expires="+ d.toUTCString();
  document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

function getCookie(cname) {
  let name = cname + "=";
  let decodedCookie = decodeURIComponent(document.cookie);
  let ca = decodedCookie.split(';');
  for(let i = 0; i <ca.length; i++) {
    let c = ca[i];
    while (c.charAt(0) == ' ') {
      c = c.substring(1);
    }
    if (c.indexOf(name) == 0) {
      return c.substring(name.length, c.length);
    }
  }
  return "";
}



function getCookieTime(){
  //Returns how much time is stored in the timewatched cookie (in seconds)
  //If there is no timewatched cookie, getCookie() will return a blank string
  //This function is called only once, 2 seconds after the page loads.
  
  var cookieTime = parseInt(getCookie("timewatched"))
  if(Number.isNaN(cookieTime)){
    //If there is no timewatched cookie, create one that's set to zero.
    console.log("Starting from zero...")
    cookieTime = 0;
    document.cookie = "timewatched:0"
  }
  return cookieTime;
}

function getTimeWatched(){
  //Returns how much time the user has spent watching YouTube,
  //including how much time was in the timewatched cookie at the time of the page load.
  
  //Add up all the times from the videoElement.played() array
  var playedLength = videoElement.played.length 
  var ttw = 0; //total time watched in seconds
  for(var i = 0; i < playedLength; i ++){
    ttw += videoElement.played.end(i) - videoElement.played.start(i)
  }
  
  //Last step: add the cookieTimeAtStart value to the sum.
  return ttw + cookieTimeAtStart;
}

function initiateTimer(){
  //This function is called 2 seconds after the page loads
  //The last line of code calls this function (see bottom)
  
  //Gets how many seconds are in the timewatched cookie at the start of the page load
  //If there is no timewatched cookie, one will be created and set to zero seconds
  cookieTimeAtStart = getCookieTime();
  
  
  videoElement = document.querySelectorAll("video")[0]
  pvideosrc = videoElement.src
  
  console.log("Cookie time at start: " + cookieTimeAtStart)
  
  totalTimeWatched = 0;
  
  //timerElement is the <p> element that will appear above the video that shows time spent watching.
  timerElement = document.createElement('p')
  timerElement.innerHTML = "this is the timer element" //This will be changed
  timerElement.setAttribute('style', 'font-size:15px; color:white')
  
  //divElement is a <div> element that already exists on the YouTube page. It will be the parent of the timerElement
  divElement = document.querySelectorAll('div[id="primary"][class="style-scope ytd-watch-flexy"]')[0]
  
  divElement.prepend(timerElement)
  
  updateTimer(); //updateTimer() is a recursive function that's called every 5 seconds
}

function updateTimer(){
  //This function is called every five seconds. It updates the totalTimeWatched variable
  
  
  //Check to see if the user has switched videos since the last timer update. If so,
  //recalculate cookieTimeAtStart
  //cookieTimeAtStart needs to be recalculated every time the user switches to a new video.
  //However, clicking on a new video does not refresh the YouTube page. As an alternative, we will
  //recalculate cookieTimeAtStart whenever the user clicks on anything that changes the src of the video element.
  videoElement = document.querySelectorAll("video")[0]
  var videosrc = videoElement.src
  if(videosrc !== pvideosrc){
    console.log("NEW PAGE!")
    cookieTimeAtStart = getCookieTime();
    console.log("Cookie time at start: " + cookieTimeAtStart)
  }
  pvideosrc = videosrc;
  
  totalTimeWatched = getTimeWatched();
  
  var ttwstr = Math.round(totalTimeWatched)
  
  //Store the total time watched in seconds in our timewatched cookie
  //The cookie will expire at midnight of the current day
  document.cookie = setCookie("timewatched", ttwstr.toString())
  
  //Update the timerElement to show the total time watched in minutes and seconds
  var minutes = Math.floor(totalTimeWatched / 60)
  var seconds = Math.round(totalTimeWatched) % 60
  seconds = seconds.toString()
  seconds = seconds.padStart(2,"0")
  timerElement.innerHTML = "Watch time today: " + minutes + ":" + seconds
  
  //If user has spent more than 30 minutes watching YouTube today, alert them.
  if(totalTimeWatched > max_time_in_minutes * 60 && totalTimeWatched < (max_time_in_minutes * 60) + 5)confirm("You have exceeded 30 minutes on YouTube today. Proceed?")
  
  //Call updateTimer() again in five seconds (recursive)
  setTimeout(updateTimer, 5000)
}

//initiateTimer() will be called 2 seconds after the page loads 
setTimeout(initiateTimer, 2000)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文