// ==UserScript==
// @name YouTubeで自動翻訳字幕(日本語)を常にオン
// @description B:再度試みる N.:次の動画 P,:前の動画
// @version 0.3
// @run-at document-idle
// @match *://www.youtube.com/*
// @grant none
// @namespace http://greasyfork.icu/users/181558
// ==/UserScript==
(function() {
const WAIT_PAGEOPEN = 600; // ミリ秒
const WAIT_EACHACTION = 600; // ミリ秒
const ENABLE_EVENJAPANESE = 0; // 日本語タイトルの動画でも実行
const ENABLE_EVENEMBED = 1; // 埋め込みでも実行
document.addEventListener('keydown', function(e) {
if (/input|textarea/i.test(e.target.tagName) == false) {
var key = (e.shiftKey ? "Shift+" : "") + (e.altKey ? "Alt+" : "") + (e.ctrlKey ? "Ctrl+" : "") + e.key;
if (key == "b") {
toJP();
e.preventDefault();
return false;
}
if (key == "n" || key == ".") {
elecli('//a[@class="ytp-next-button ytp-button" and @aria-label="次へ(SHIFT+n)"]|//a[@class="ytp-next-button ytp-button cleaned" and @role="button" and @aria-label="次へ(SHIFT+n)"]');
e.preventDefault();
return false;
}
if (key == "p" || key == ",") {
elecli('//a[@class="ytp-prev-button ytp-button" and @aria-label="前へ(SHIFT+p)"]|//a[@class="ytp-prev-button ytp-button cleaned" and @role="button" and @aria-label="前へ(SHIFT+p)"]');
e.preventDefault();
return false;
}
}
}, false);
var href = location.href;
var observer = new MutationObserver(function(mutations) {
if (href !== location.href) {
href = location.href;
run(WAIT_PAGEOPEN * 3);
}
});
observer.observe(document, { childList: true, subtree: true });
if (window == parent) run(WAIT_PAGEOPEN);
for (let ele of elegeta('//div[@id="player"]/div/div/button[@aria-label="再生"]')) {
ele.addEventListener('click', () => { setTimeout(run, WAIT_PAGEOPEN) });
}
return;
function run(delay = 500) {
setTimeout(function() {
// console.log("run");
var title = eleget0('//h1/yt-formatted-string');
if (!(location.href.match(/\/embed/)) && !title) { setTimeout(() => { run(); }, 100); return; }
if (!ENABLE_EVENJAPANESE && title && title.innerText.match(/[\u30a0-\u30ff\u3040-\u309f\u3005-\u3006\u30e0-\u9fcf]+/)) return; // タイトルに日本語あるならやめる
toJP();
}, delay);
}
function toJP() {
if (!(location.href.match(ENABLE_EVENEMBED ? /:\/\/www\.youtube\.com\/watch\?|:\/\/www\.youtube\.com\/embed/ : /:\/\/www\.youtube\.com\/watch\?/))) return;
if (eleget0('//button[@class="ytp-subtitles-button ytp-button" and @aria-label="字幕(c)"]')) { // 字幕ボタン
elecli('//button[@class="ytp-subtitles-button ytp-button" and @aria-label="字幕(c)" and @aria-pressed="false"]', 1); // 字幕ボタン
elecli('//div[@class="ytp-right-controls"]/button[@aria-label="設定"]', 2); // 設定ボタン
elecli('//div[@class="ytp-menuitem-label"]/div/span[text()="字幕"]', 3, "close", "smooth");
elecli('//div[@class="ytp-menuitem-label" and text()="自動翻訳"]', 4, "close", "instant");
elecli('//div[@class="ytp-menuitem-label" and text()="日本語"]', 5, "close");
elecli('//div[last()]/button[@data-tooltip-target-id="ytp-settings-button" and @aria-expanded="true"]', 7, "blur");
}
}
function elecli(xpath, delay = 0, command = false, beha = null) {
setTimeout(() => {
var ele = eleget0(xpath);
// console.log(xpath, (elegeta(xpath).length));
if (ele) {
var ele = elegeta(xpath);
ele = ele[ele.length - 1]; // 複数ある時は最後の1つ
if (command == "focus") ele.focus();
else {
ele.click();
if (window != parent && beha) {
let foc = eleget0('//div[@id="movie_player"]|//div[@id="player"]');
if (foc) foc.scrollIntoView({ behavior: beha, block: "center", inline: "center" });
}
}
} else {
if (command == "close") {
elecli('//div[last()]/button[@data-tooltip-target-id="ytp-settings-button" and @aria-expanded="true"]');
} //elecli('//div[@id="movie_player"]|//div[@id="player"]/div/div/video', 0, "focus"); }
}
if (command == "blur") elecli('//div[@id="movie_player"]|//div[@id="player"]/div/div/video', 0, "focus");
}, delay * WAIT_EACHACTION)
}
function eleget0(xpath, node = document) {
if (!xpath) return null;
try {
var ele = document.evaluate(xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
return ele.snapshotLength > 0 ? ele.snapshotItem(0) : "";
} catch (e) { return null; }
}
function elegeta(xpath, node = document) {
var ele = document.evaluate("." + xpath, node, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var array = [];
for (var i = 0; i < ele.snapshotLength; i++) array[i] = ele.snapshotItem(i);
return array;
}
})()