Skip to content

Instantly share code, notes, and snippets.

@chsbuffer
Last active April 17, 2022 14:33
Show Gist options
  • Save chsbuffer/8990b3500c0a153bfcbe87e16f4a586e to your computer and use it in GitHub Desktop.
Save chsbuffer/8990b3500c0a153bfcbe87e16f4a586e to your computer and use it in GitHub Desktop.
Youtube 中文字幕,不存在则从英语翻译
// ==UserScript==
// @name Youtube subtitle follow browser languages
// @version 0.1
// @description You are a horrible website. I'm serious, that's what it says: A horrible website. We weren't even testing for that.
// @author ChsBuffer
// @match https://*.youtube.com/*
// @grant unsafeWindow
// @run-at document-end
// @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// ==/UserScript==
(function() {
'use strict';
const selectSubtitle = async (player, response) => {
let captions = response.captions?.playerCaptionsTracklistRenderer?.captionTracks
if (!captions) return
let langs = captions.map((obj) => obj.languageCode)
console.log(langs)
// all chinese language code result: ['zh', 'zh-CN', 'zh-Hans', 'zh-Hant', 'zh-HK', 'zh-TW']
let lang = langs.filter(l => l.startsWith('zh'))?.sort(Intl.Collator().compare)[0]
if (lang) {
console.log(lang)
player.setOption('captions', 'track', {'languageCode': lang})
player.toggleSubtitlesOn()
} else {
lang = captions.filter((o) => o.languageCode.startsWith('en')).sort((a, b) => (b.kind == 'asr' ? 0 : 1) - (a.kind == 'asr' ? 0 : 1 ))[0]?.languageCode
if (lang) {
console.log(lang+' -> zh-Hans')
player.setOption('captions', 'track', {'languageCode': lang, 'translationLanguage': {'languageCode': 'zh-Hans', 'languageName': '中文(简体)' } } )
player.toggleSubtitlesOn()
}
}
}
const load = async (response) => {
const player = document.querySelector('#movie_player')
const _selectSubtitle = async () => {
player.removeEventListener('videodatachange', _selectSubtitle)
// Let's wait 1000ms to avoid the player being busy setting Roman subtitle and ignoring us
setTimeout(selectSubtitle, 1000, player, response)
}
player.addEventListener('videodatachange', _selectSubtitle)
}
// https://greasyfork.org/zh-TW/scripts/369400-local-youtube-downloader
// fetch hook
const ff = fetch
unsafeWindow.fetch = (...args) => {
if (args[0] instanceof Request) {
return ff(...args).then(resp => {
if (resp.url.includes('player')) {
resp.clone().json().then(load)
}
return resp
})
}
return ff(...args)
}
unsafeWindow.addEventListener('yt-navigate-finish', () => {
// init hook, called once at a fresh page
const firstResp = unsafeWindow?.ytplayer?.config?.args?.raw_player_response
if (firstResp) {
load(firstResp)
}
}, {once: true})
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment