Skip to content

Instantly share code, notes, and snippets.

@carcigenicate
Created February 26, 2023 23:06
Show Gist options
  • Save carcigenicate/71e044332421649c51d48a17f2c97038 to your computer and use it in GitHub Desktop.
Save carcigenicate/71e044332421649c51d48a17f2c97038 to your computer and use it in GitHub Desktop.
YouTube Subtitle Language Changer
// ==UserScript==
// @name Subtitle Language Changer
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Spawns a small textbox and button to easily allow changing YouTube's subtitle language.
// @author You
// @match https://www.youtube.com/watch*
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
const SETTINGS_BTN_PATH = '#movie_player > div.ytp-chrome-bottom > div.ytp-chrome-controls > div.ytp-right-controls > button.ytp-button.ytp-settings-button';
const SUBTITLES_BTN_PATH = '#ytp-id-18 > div > div > div:nth-child(4) > div.ytp-menuitem-label > div > span:nth-child(1)';
const ENGLISH_BTN_PATH = '#ytp-id-18 > div > div.ytp-panel-menu > div:nth-child(2) > div';
const LANGUAGE_SELECT_BTN_PATH = '#ytp-id-18 > div > div.ytp-panel-menu > div:nth-child(3) > div';
const LANGUAGE_CONTAINER_PATH = '#ytp-id-18 > div > div.ytp-panel-menu'; // > div:nth-child(5) > div
function clickInOrder(selectors, delay) {
return new Promise((resolve) => {
const selectorCopy = [...selectors];
function loop() {
if (selectorCopy.length > 0) {
const elem = document.querySelector(selectorCopy.splice(0, 1)[0]);
console.log("CLICKING", elem);
elem.click();
setTimeout(loop, delay);
} else {
resolve();
}
}
loop();
});
}
async function changeSubtitleLanguage(language) {
await clickInOrder([
SETTINGS_BTN_PATH,
SUBTITLES_BTN_PATH,
ENGLISH_BTN_PATH,
SUBTITLES_BTN_PATH,
LANGUAGE_SELECT_BTN_PATH
], 400);
const languagesParent = document.querySelector(LANGUAGE_CONTAINER_PATH);
const loweredSelection = language.toLowerCase();
const languageBtn = [...languagesParent.children].find((child) => child.firstChild.innerHTML.toLowerCase() === loweredSelection);
if (languageBtn) {
languageBtn.click();
} else {
console.error("Could not find language", language);
}
}
const inputHTML = `
<input id='languageSelectInput' />
<button id='languageSelectBtn'>Change</button>
`;
const container = document.createElement('div');
container.innerHTML = inputHTML;
document.body.appendChild(container);
container.style.position = 'absolute';
container.style.top = '4vw';
container.style.left = '2vw';
container.style.zIndex = '99999';
container.style.backgroundColor = 'white';
document.getElementById('languageSelectBtn').onclick = () => {
const input = document.getElementById('languageSelectInput');
changeSubtitleLanguage(input.value);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment