Auto-Select YouTube Subtitles by Sapioit

Automatically selects the YouTube subtitles with the text "English (auto-generated)"

当前为 2023-07-30 提交的版本,查看 最新版本

// ==UserScript==
// @name         Auto-Select YouTube Subtitles by Sapioit
// @namespace    Sapioit
// @copyright    Sapioit, 2020 - Present
// @author       sapioitgmail.com
// @license      GPL-2.0-only; http://www.gnu.org/licenses/gpl-2.0.txt
// @version      2.13.1.9
// @description  Automatically selects the YouTube subtitles with the text "English (auto-generated)"
// @match        https://*.youtube.com/*
// @match        https://youtube.com/*
// @match        https://youtu.be/*
// @icon         https://youtube.com/favicon.ico
// @grant        none
// ==/UserScript==

localStorage.setItem('currentWatchMetadataValue', 0);
localStorage.setItem('consecutiveUnchangedCount', 0);

let repeatInterval = 5000; // 1000 milliseconds = 1 second; 10000 milliseconds = 10 second;
let waitInterval = 5; // Adjust the delay (in milliseconds) if needed. 1000 = 1 second.


function title_has_changed (count = 3) {
  console.info("%cAuto-Select YouTube Subtitles by Sapioit: title_has_changed: %cChecking title.", "color: yellow; background-color: black;", "color: white");

  // Check if the value of the title (the first "yt-formatted-string.style-scope.ytd-watch-metadata" element) has changed
  let firstWatchMetadataElement = document.querySelector('h1 yt-formatted-string.style-scope.ytd-watch-metadata');

  if ( firstWatchMetadataElement === null || (typeof firstWatchMetadataElement) === 'undefined') {
    console.info("Auto-Select YouTube Subtitles by Sapioit: title_has_changed: %cThe 'h1 yt-formatted-string.style-scope.ytd-watch-metadata' is either NULL or UNDEFINED.", "color: red");
    console.info("%cAuto-Select YouTube Subtitles by Sapioit: title_has_changed: %c", "color: red", "color: default", firstWatchMetadataElement , (typeof firstWatchMetadataElement));
    return false;
  }

  console.info("%cAuto-Select YouTube Subtitles by Sapioit: title_has_changed:", "color: cyan", (firstWatchMetadataElement.textContent.trim()) );
  console.info("%cAuto-Select YouTube Subtitles by Sapioit: title_has_changed:", "color: cyan", (firstWatchMetadataElement.textContent.trim() !== '') , ' ' , (firstWatchMetadataElement) );

  if ( firstWatchMetadataElement.textContent.trim() !== '') {
    // Get the current value of the title
    const currentWatchMetadataValue = firstWatchMetadataElement.textContent.trim();
    console.info("%cAuto-Select YouTube Subtitles by Sapioit: title_has_changed: %cTitle found.", "color: yellow; background-color: black;", "color: white");

    // Get the consecutive unchanged count from localStorage, or set it to 0 if it's not available
    let consecutiveUnchangedCount = parseInt(localStorage.getItem('consecutiveUnchangedCount')) || 0;

    // Increment the consecutiveUnchangedCount if the value is the same
    consecutiveUnchangedCount++;

    // Update the stored value and consecutiveUnchangedCount in localStorage
    localStorage.setItem('currentWatchMetadataValue', currentWatchMetadataValue);
    localStorage.setItem('consecutiveUnchangedCount', consecutiveUnchangedCount.toString());

    console.log("Auto-Select YouTube Subtitles by Sapioit: title_has_changed: Try nr #" + (1+consecutiveUnchangedCount) );

    // Check if the current value is the same as the previous one stored in localStorage
    if (localStorage.getItem('currentWatchMetadataValue') === currentWatchMetadataValue) {

      // Stop the function if the title value hasn't changed for the last three checks (consecutiveUnchangedCount is less than 4)
      if ( consecutiveUnchangedCount < (count+1) ) {
        console.log("Auto-Select YouTube Subtitles by Sapioit: title_has_changed: First 'yt-formatted-string.style-scope.ytd-watch-metadata' element has not changed for the last three checks. Stopping check.");
        return false; // Return that the title has not changed.
      } else {
        // Reset the consecutiveUnchangedCount if the value has changed
        consecutiveUnchangedCount = 0;

        // Update the stored value and consecutiveUnchangedCount in localStorage
        localStorage.setItem('currentWatchMetadataValue', currentWatchMetadataValue);
        localStorage.setItem('consecutiveUnchangedCount', consecutiveUnchangedCount.toString());
        return true; // Return that the title has changed.
      }
    } else {
      // Reset the consecutiveUnchangedCount if the value has changed
      consecutiveUnchangedCount = 0;

      // Update the stored value and consecutiveUnchangedCount in localStorage
      localStorage.setItem('currentWatchMetadataValue', currentWatchMetadataValue);
      localStorage.setItem('consecutiveUnchangedCount', consecutiveUnchangedCount.toString());
      return true; // Return that the title has changed.
    }
  } else {
    console.log("Auto-Select YouTube Subtitles by Sapioit: title_has_changed: Checking title FAILED.");
  }
  return false; // Return that the title has changed.
  // Usage example:
  if ( title_has_changed() ){
    return;
  }
  if ( title_has_changed(3) ){
    return;
  }
}


function checkSubtitles() {
  if ( title_has_changed(12) ){
    return;
  }
  console.log("Auto-Select YouTube Subtitles by Sapioit: checkSubtitles: Checking subtitles.");
  // Check if the value of ytp-menuitem-content is 'English (auto-generated)'
  let menuItems = document.querySelectorAll('.ytp-menuitem');
  let subtitlesButton = document.querySelector('.ytp-subtitles-button');
  let autoGeneratedMenuItem;

  for (let menuItem of menuItems) {
    let menuLabel = menuItem.querySelector('.ytp-menuitem-label span:first-child');
    let menuContent = menuItem.querySelector('.ytp-menuitem-content');

    if ( menuLabel && menuLabel.textContent.trim() === 'Subtitles/CC'
        && menuContent && menuContent.textContent.trim() !== 'English (auto-generated)' ){
      autoGeneratedMenuItem = menuItem;
      break;
    }
  }

  // Run the code if the condition is not met
  if (subtitlesButton && subtitlesButton.getAttribute('title') !== 'Subtitles/closed captions unavailable') {
    if (autoGeneratedMenuItem || subtitlesButton.getAttribute('aria-pressed') !== 'true' ) {
      // Change the subtitles
      //alert(subtitlesButton.outerHTML);
      ChangeSubtitles();
    } else {
      console.log("Auto-Select YouTube Subtitles by Sapioit: checkSubtitles: Subtitles did not need to be updated.");
    }
  } else {
    console.log("Auto-Select YouTube Subtitles by Sapioit: checkSubtitles: There are no subtitles available.");
  }
}

// Schedule to run the code every so often
setInterval(checkSubtitles, repeatInterval); // 1000 milliseconds = 1 second; 10000 milliseconds = 10 second;

window.addEventListener('DOMContentLoaded', () => {
  setTimeout(checkSubtitles, waitInterval);
});

function ChangeSubtitles() {
  'use strict';

  // Find the gear icon
  //const gearIcon = document.querySelector('.ytp-settings-button');
  const gearIcon = document.querySelectorAll('.ytp-settings-button');
  console.log(gearIcon[0].outerHTML);

  // Find the subtitles icon
  const subtitlesButton = document.querySelector('.ytp-subtitles-button');

  // Click the gear icon to open the menu
  gearIcon[0].click();
  //document.querySelector('.ytp-settings-button').click();

  // Wait for the menu to open
  setTimeout(() => {
    // Find the third menu item
    let menuItems = document.querySelectorAll('.ytp-menuitem-label span');
    let thirdMenuItem;

    // Loop through each element in the 'menuItems' array.
    for (let j = 0; j < menuItems.length; j++) {
      // Get the current menu item element and its closest ancestor with the class 'ytp-menuitem'.
      let menuItem = menuItems[j].closest('.ytp-menuitem');

      // If 'menuItem' exists and has a child with the class 'ytp-menuitem-label' that has the first child a 'span', and its text content is 'Subtitles/CC'.
      if (menuItem && menuItem.querySelector('.ytp-menuitem-label span:first-child').textContent.trim() === 'Subtitles/CC') {
        // If the condition is true, assign the 'menuItem' element to the variable 'thirdMenuItem'.
        thirdMenuItem = menuItem;

        // Exit the loop immediately since the desired menu item is found.
        break;
      }
    }


    // Click the third menu item
    if (thirdMenuItem) {
      (thirdMenuItem).click();
    }

    // Wait for the "Subtitles/CC" menu to open
    setTimeout(() => {
      // Find the "English (auto-generated)" menu item
      let menuLabels = document.querySelectorAll('.ytp-menuitem-label');
      let autoGeneratedMenuItem;

      for (let i = 0; i < menuLabels.length; i++) {
        if (menuLabels[i].textContent.trim() === 'English (auto-generated)') {
          autoGeneratedMenuItem = menuLabels[i];
          break;
        }
      }

      // Click the "English (auto-generated)" menu item if found
      if (autoGeneratedMenuItem) {
        (autoGeneratedMenuItem).click();
      }
      // Wait for the "English (auto-generated)" option to be selected
      setTimeout(() => {
        let element = document.querySelector('.ytp-settings-menu');
        let computedStyle = getComputedStyle(element);
        if (computedStyle.display !== 'none') {
          // Click the gear icon to open the menu
          gearIcon[0].click();
        }
        setTimeout(() => {
          if (subtitlesButton.getAttribute('aria-pressed') !== 'true') {
            //alert(subtitlesButton.outerHTML);
            (subtitlesButton).click();
          }
        }, waitInterval); // Adjust the delay (in milliseconds) if needed
      }, waitInterval); // Adjust the delay (in milliseconds) if needed
    }, waitInterval); // Adjust the delay (in milliseconds) if needed
  }, waitInterval); // Adjust the delay (in milliseconds) if needed
  console.log("Auto-Select YouTube Subtitles by Sapioit: ChangeSubtitles: Subtitles changed.");
}

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址