Greasy Fork is available in English.

视频:: 全网VIP视频破解超强集合;爱奇艺、优酷、腾讯视频原网站广告过滤;知乎视频下载;YouTube油管播放助手

常用功能专属集合: 一、一键破解:爱奇艺|腾讯视频|优酷|芒果TV|搜狐视频|乐视等VIP特权或会员视频,普通视频去广告高速播放,解析接口贵在稳定够用。支持:Tampermonkey|Violentmonkey|Greasymonkey,版本4.0+以上最佳(每个网站解析按钮位置可自定义,避免遮挡);二、爱奇艺、优酷、腾讯视频原网站广告过滤; 三、为知乎的视频播放器添加下载功能;四、YouTube油管自动跳广告,自动打开翻译字幕,如果打开失败,请手动点击一下字幕按钮。

// ==UserScript==
// @name         视频:: 全网VIP视频破解超强集合;爱奇艺、优酷、腾讯视频原网站广告过滤;知乎视频下载;YouTube油管播放助手
// @namespace    fengdiansanren_video_text_helper
// @version      1.0.2
// @description  常用功能专属集合: 一、一键破解:爱奇艺|腾讯视频|优酷|芒果TV|搜狐视频|乐视等VIP特权或会员视频,普通视频去广告高速播放,解析接口贵在稳定够用。支持:Tampermonkey|Violentmonkey|Greasymonkey,版本4.0+以上最佳(每个网站解析按钮位置可自定义,避免遮挡);二、爱奇艺、优酷、腾讯视频原网站广告过滤; 三、为知乎的视频播放器添加下载功能;四、YouTube油管自动跳广告,自动打开翻译字幕,如果打开失败,请手动点击一下字幕按钮。 
// @author       人鬼情未了、王超、crud-boy
// @copyright    人鬼情未了, 王超 、crud-boy
// @include      https://*.youku.com/v_*
// @include      https://*.iqiyi.com/v_*
// @include      https://*.iqiyi.com/w_*
// @include      https://*.iqiyi.com/a_*
// @include      https://*.le.com/ptv/vplay/*
// @include      https://v.qq.com/x/cover/*
// @include      https://v.qq.com/x/page/*
// @include      https://*.tudou.com/listplay/*
// @include      https://*.tudou.com/albumplay/*
// @include      https://*.tudou.com/programs/view/*
// @include      https://*.mgtv.com/b/*
// @include      https://film.sohu.com/album/*
// @include      https://tv.sohu.com/v/*
// @include      https://*.baofeng.com/play/*
// @include      https://vip.pptv.com/show/*
// @include      https://v.pptv.com/show/*
// @include      *://www.zhihu.com/*
// @include      *://v.vzuu.com/video/*
// @include      *://video.zhihu.com/video/*
// @include      *://www.youtube.com/watch?v=*
// @connect      zhihu.com
// @connect      vzuu.com
// @require      http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @grant        GM_info
// @grant        GM_download
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_openInTab
// @run-at       document-end
// ==/UserScript==

(function() {
	'use strict';	
    var $ = $ || window.$;
    var window_url = window.location.href;
    var website_host = window.location.host;
	if(window.top != window.self){
    	return;
    }
			
	var playback={};
	playback.getWebsiteName=function(){
		var name="other";
		if(website_host.indexOf("iqiyi.com")!=-1){
			name="iqiyi";
		}else if(website_host.indexOf("qq.com")!=-1){
			name="qq";
		}else if(website_host.indexOf("youku.com")!=-1){
			name="youku";
		}else if(website_host.indexOf("mgtv.com")!=-1){
			name="mgtv";
		}else if(website_host.indexOf("tudou.com")!=-1){
			name="tudou";
		}else if(website_host.indexOf("sohu.com")!=-1){
			name="sohu";
		}
		return name;
	};
	playback.isVideoWebsite=function(){
		var host = window.location.host;
		var videoWebsites = ["iqiyi.com","v.qq.com","youku.com", "le.com","tudou.com","mgtv.com","sohu.com","acfun.cn","baofeng.com","pptv.com"];
   		for(var b=0; b<videoWebsites.length; b++){
	   		if(host.indexOf(videoWebsites[b]) != -1){
	   			return true;
	   		}
	   	}
   		return false;
	}
	playback.start=function(){
		if(!this.isVideoWebsite()) return;
		var left=0;
		var top=300;
		var playerBoxPosition=GM_getValue("playerBoxPosition_"+playback.getWebsiteName());
		if(!!playerBoxPosition){
			left=playerBoxPosition.left;
			top=playerBoxPosition.top;
		}
		var css = "#fengdiansanren_video_player_box{position:fixed; top:"+top+"px; left:"+left+"px; z-index:999999; width:20px;background-color:red; padding:5px 0px;};"
			css += "#fengdiansanren_video_player_box>div{width:100%; height:20px;text-align:center;}";
			css += "#fengdiansanren_video_player_box>div>img{width:90%;}";
			css += "#fengdiansanren_video_player_jump{cursor:pointer;}"
			css += "#fengdiansanren_video_player_box_move{cursor:move;margin-top:5px;}"
		
		$("head").append("<style>"+css+"</style>")
		
		var moveImage="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAADjUlEQVRoQ+2YTYiVVRjHf38ESQXXVhsHl4IIJRpumsGFWo2jtZnGtrqSMTC36SYQg/ADomiVXxs/SvyghTqroahAW7QbdJNKmyAwR0QfeeC5cubl3vuemXve5A73rO573/Oe8/+d85zn44g+b+pz/QwAXvUODnZg0e6AmU0CXwLPgQ2S/mgCthETMrONwC1gWYh+BGyR9HNpiOIAZjYMnAFer4h9CExIulkSoiiAmb0HnAVWdhD5b0BcKQVRDMDMtgOXgSUh7j9gefx+nJjTM+AjST+UgCgJ4Db/boiaBc4Du+P5tIsGXovnKUluaj23kgATgAu9B3wKrAc+D4WHgTvASeANB5Pk56TnVgzAlZjZakkO4L8PpQCS/HlOn57VQ3O5UCeAEqLTMYruQDrwYgD4BPg+oIYlTZVefR+vsR0Ie98G/C3p9ybEzwsg/PxnwHelPEgVysz2AOPAUUnXcqCzdiAi7I9JkBpqeZucSXL6uAcD7kZfD3Y7JF2t+7YWIHIbj5qt9OCepKG6gRfy3swcwEG8edoxJskDZMfWFSCyyktJYuYRdjwnDTCzncCB2LVJSb/UQZnZGHAuidgPgJ3dvu0IYGbrgGlgRUzsuc1FYKYixNOCOR7GzPYBxyv91kr6s+Jq3eY9MqdtDbAryaN83gOSvm63AN0AngBL61Yt3r+dehoz87zfa4K0/SRpa+sPMxsF/FzltKeS2mopBbBd0vVEXDuAaUmbkz6e+HW174RsVlKrOJoD3A1gP/BFkgZ7SnyhjQnNSDpVMY2DwJHK0u6S5OfpZTOzt4AP2pjQh8m8bkLvdCpJ6w7xJsAnXRWT+CH+uCqkagNm5qv7foj7xys0SSfqbCUOvhdErbTbqzg/xB1L0Rw3OhIQLTd6X9KbdWIW8t7M/koOtbtRF9+1BK0FcCFm5qvpsaBVbf0fgcxjQG3pmQUQEO6j/arknKRvF7LCdd8kqcSxnFjj42UD1E3e7n2chZWSvFZupDUGEB7mt1C9t6ldaxKgbUlZehsGAJXA1L9FfXiQb7pcq9wGvop0udiZKGZCZtb3F1vdrhbTa0avtkZzS8a6Q19sByLY5Vzuei5VWyrWCW+9LwoQEJ2u17268uv13BQ6i6E4QEB4MXOjUs2N5JSVWaqTTo0ABISXpL9GuuI1cduScL6Cq/0bA+hVWO73A4DclWqq32AHmlrZ3HH7fgdeAL7GSUBqsOkSAAAAAElFTkSuQmCC";
		var playerImage="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAABtklEQVRoQ+2YTytFQRjGn+czKBtbK7u79jl8CFtLK3auhYWFJEmS5EY3KQtlIZIotyRJkhQLIUWRbkdT79RZUHf+n1Nz1jPz/n7vM9OZc4iaP6w5P7JA6gRzAjkBxw7kLeTYQOfpxgkURTECYBzAAIB1AFMkH51JLBewEbgBMFiqdycSC5YMTtNsBIp/Km6LyLETkeFknwKqdFdJiMiHIYvVcN8CGqIDoElSnZGgTygBDb0qaVyGsggtoLjfRGI6hEQMAc19ICK7PkViCmjuORF58CGSQkBx34vEvKtEKgHNvSMiR7YiqQUUt3oxNkXk3VSkCgKa+UIk1kwkqiSguSdJTvQqUUWBV5J9dRbokGzUVeAFwCjJVh0FVuQQX/UKr8ZV4QycC/iGCbgem1LgR74d1LX70wY+ZQJt6fqJLXiqBG4FfNEVPIXArMA/+YKPtYX2BXzPJ3iMBJ4FfCYEeGiBZYG/DgkfYgudCfhmaHDfCXyX/gd9xYK3TeAQwHAJcku6fhoT3CWBIQBjAPoBtEkupQC3FkgJ+1dt47tQFvDcgZyA54YaL5cTMG6Z5wk5Ac8NNV7uF+15tDGwBHN+AAAAAElFTkSuQmCC";
		var html = "<div id='fengdiansanren_video_player_box'>"+
					"<div id='fengdiansanren_video_player_jump' name='跳转到解析'><img src='"+playerImage+"'></div>"+
					"<div id='fengdiansanren_video_player_box_move' name='移动按钮'><img src='"+moveImage+"'></div>"+
				"</div>";
		$("body").append(html);
		
		$("#fengdiansanren_video_player_jump").on("click", function(){
			var playbackWebsite="http://kiwi8.top/mov/s?url="+window_url;
			GM_openInTab(playbackWebsite, {active: true});
		});
	};
	playback.start();
	if(!playback.isVideoWebsite()) return; //不是视频网址执行到此处
	
	var playerBoxMove={};
	playerBoxMove.point={"x":0,"y":0,"l":0,"t":0,};
	playerBoxMove.isDown=false;
	playerBoxMove.$box=document.getElementById('fengdiansanren_video_player_box_move');
	playerBoxMove.$box.onmousedown = function(e) {
		//阻止默认事件
		e.preventDefault();
        e.stopPropagation();
	    //获取x坐标和y坐标
	    playerBoxMove.point.x = e.clientX;
	    playerBoxMove.point.y = e.clientY;
	    //获取左部和顶部的偏移量
	    playerBoxMove.point.l = playerBoxMove.$box.parentNode.offsetLeft;
	    playerBoxMove.point.t = playerBoxMove.$box.parentNode.offsetTop;
	    //开关打开
	    playerBoxMove.isDown = true;
	    //设置样式  
	    playerBoxMove.$box.style.cursor = 'move';
	}
	window.onmousemove = function(e) {
		//阻止默认事件
		e.preventDefault();
        e.stopPropagation();
	    if (playerBoxMove.isDown == false) {
	        return;
	    }
	    //获取x和y
	    var nx = e.clientX;
	    var ny = e.clientY;
	    //计算移动后的左偏移量和顶部的偏移量
	    var nl = nx - (playerBoxMove.point.x - playerBoxMove.point.l);
	    var nt = ny - (playerBoxMove.point.y - playerBoxMove.point.t);
		//更新位置
	    playerBoxMove.$box.parentNode.style.left = nl + 'px';
	    playerBoxMove.$box.parentNode.style.top = nt + 'px';
	    GM_setValue("playerBoxPosition_"+playback.getWebsiteName(),{"left":nl, "top":nt})
	}
	playerBoxMove.$box.onmouseup = function() {
	    //开关关闭
	    playerBoxMove.isDown = false;
	    playerBoxMove.$box.style.cursor = 'move';
	}
	
	//视频网站广告过滤
	var videoWebsiteADRemove={};
	videoWebsiteADRemove.method1=function(){
		window._setTimeout = window.setTimeout
        window.setTimeout = function (handler, timeout, ...arg) {
            window._setTimeout(handler, timeout / 30, ...arg)
        }
	};
	videoWebsiteADRemove.method2=function(){
		window._setInterval = window.setInterval
        window.setInterval = function (handler, timeout, ...arg) {
            window._setInterval(handler, timeout / 30, ...arg)
        }
	};
	videoWebsiteADRemove.method3=function(){
		window.rate = 0
        window.Date.now = ()=>{return new window.Date().getTime() + (window.rate += 10000)}
        setInterval(()=>{window.rate = 0}, 600000)
	};
	videoWebsiteADRemove.youku=function(){
		var $that=this;
		window.onload = function () {
            if (!document.querySelectorAll('video')[1]) {
                setInterval(()=>{document.querySelectorAll('video')[1].playbackRate = 16},100)
            } else {
               $that.method1()
            }
        }
	};
	videoWebsiteADRemove.iqiyi=function(){
		this.method3();
	};
	videoWebsiteADRemove.qq=function(){
		setInterval(()=>{
            if (document.querySelectorAll('video')[0].status == 'IDLE') {
                setInterval(()=>{
                    document.querySelectorAll('video')[2].playbackRate = 16
                    document.querySelectorAll('video')[3].playbackRate = 16
                },100)
            }
        },100);
	};
	videoWebsiteADRemove.start=function(){
		switch (website_host) {
	        case 'v.youku.com':
	            this.youku();
	            break
	        case 'v.qq.com' :
	            this.qq()
	            break
	        case 'www.iqiyi.com' :
	            this.iqiyi()
	            break
	        default :
	            break
	    }
	};
	videoWebsiteADRemove.start();
})();

//知乎视频下载
//https://greasyfork.org/zh-CN/scripts/39206
(async () => {
    if (window.location.host == 'www.zhihu.com') return;

    const playlistBaseUrl = 'https://lens.zhihu.com/api/videos/';
    //const videoBaseUrl = 'https://video.zhihu.com/video/';
    const videoId = window.location.pathname.split('/').pop(); // 视频id
    const menuStyle = 'transform:none !important; left:auto !important; right:-0.5em !important;';
    const playerId = 'player';
    const coverSelector = '#' + playerId + ' > div:first-child > div:first-child > div:nth-of-type(2)';
    const controlBarSelector = '#' + playerId + ' > div:first-child > div:first-child > div:last-child > div:last-child > div:first-child';
    const svgDownload = '<path d="M9.5,4 H14.5 V10 H17.8 L12,15.8 L6.2,10 H9.5 Z M6.2,18 H17.8 V20 H6.2 Z"></path>';
    let player = document.getElementById(playerId);
    let resolutionMap = {'标清': 'sd', '高清': 'ld', '超清': 'hd'};
    let videos = []; // 存储各分辨率的视频信息
    let downloading = false;

    function getBrowerInfo() {
        let browser = (function (window) {
            let document = window.document;
            let navigator = window.navigator;
            let agent = navigator.userAgent.toLowerCase();
            // IE8+支持.返回浏览器渲染当前文档所用的模式
            // IE6,IE7:undefined.IE8:8(兼容模式返回7).IE9:9(兼容模式返回7||8)
            // IE10:10(兼容模式7||8||9)
            let IEMode = document.documentMode;
            let chrome = window.chrome || false;
            let system = {
                // user-agent
                agent: agent,
                // 是否为IE
                isIE: /trident/.test(agent),
                // Gecko内核
                isGecko: agent.indexOf('gecko') > 0 && agent.indexOf('like gecko') < 0,
                // webkit内核
                isWebkit: agent.indexOf('webkit') > 0,
                // 是否为标准模式
                isStrict: document.compatMode === 'CSS1Compat',
                // 是否支持subtitle
                supportSubTitle: function () {
                    return 'track' in document.createElement('track');
                },
                // 是否支持scoped
                supportScope: function () {
                    return 'scoped' in document.createElement('style');
                },

                // 获取IE的版本号
                ieVersion: function () {
                    let rMsie = /(msie\s|trident.*rv:)([\w.]+)/;
                    let match = rMsie.exec(agent);
                    try {
                        return match[2];
                    } catch (e) {
                        return IEMode;
                    }
                },
                // Opera版本号
                operaVersion: function () {
                    try {
                        if (window.opera) {
                            return agent.match(/opera.([\d.]+)/)[1];
                        }
                        else if (agent.indexOf('opr') > 0) {
                            return agent.match(/opr\/([\d.]+)/)[1];
                        }
                    } catch (e) {
                        return 0;
                    }
                }
            };

            try {
                // 浏览器类型(IE、Opera、Chrome、Safari、Firefox)
                system.type = system.isIE ? 'IE' :
                    window.opera || (agent.indexOf('opr') > 0) ? 'Opera' :
                        (agent.indexOf('chrome') > 0) ? 'Chrome' :
                            //safari也提供了专门的判定方式
                            window.openDatabase ? 'Safari' :
                                (agent.indexOf('firefox') > 0) ? 'Firefox' :
                                    'unknow';

                // 版本号
                system.version = (system.type === 'IE') ? system.ieVersion() :
                    (system.type === 'Firefox') ? agent.match(/firefox\/([\d.]+)/)[1] :
                        (system.type === 'Chrome') ? agent.match(/chrome\/([\d.]+)/)[1] :
                            (system.type === 'Opera') ? system.operaVersion() :
                                (system.type === 'Safari') ? agent.match(/version\/([\d.]+)/)[1] :
                                    '0';

                // 浏览器外壳
                system.shell = function () {
                    if (agent.indexOf('edge') > 0) {
                        system.version = agent.match(/edge\/([\d.]+)/)[1] || system.version;
                        return 'Edge';
                    }
                    // 遨游浏览器
                    if (agent.indexOf('maxthon') > 0) {
                        system.version = agent.match(/maxthon\/([\d.]+)/)[1] || system.version;
                        return 'Maxthon';
                    }
                    // QQ浏览器
                    if (agent.indexOf('qqbrowser') > 0) {
                        system.version = agent.match(/qqbrowser\/([\d.]+)/)[1] || system.version;
                        return 'QQBrowser';
                    }
                    // 搜狗浏览器
                    if (agent.indexOf('se 2.x') > 0) {
                        return '搜狗浏览器';
                    }

                    // Chrome:也可以使用window.chrome && window.chrome.webstore判断
                    if (chrome && system.type !== 'Opera') {
                        let external = window.external;
                        let clientInfo = window.clientInformation;
                        // 客户端语言:zh-cn,zh.360下面会返回undefined
                        let clientLanguage = clientInfo.languages;

                        // 猎豹浏览器:或者agent.indexOf("lbbrowser")>0
                        if (external && 'LiebaoGetVersion' in external) {
                            return 'LBBrowser';
                        }
                        // 百度浏览器
                        if (agent.indexOf('bidubrowser') > 0) {
                            system.version = agent.match(/bidubrowser\/([\d.]+)/)[1] ||
                                agent.match(/chrome\/([\d.]+)/)[1];
                            return 'BaiDuBrowser';
                        }
                        // 360极速浏览器和360安全浏览器
                        if (system.supportSubTitle() && typeof clientLanguage === 'undefined') {
                            let storeKeyLen = Object.keys(chrome.webstore).length;
                            let v8Locale = 'v8Locale' in window;
                            return storeKeyLen > 1 ? '360极速浏览器' : '360安全浏览器';
                        }
                        return 'Chrome';
                    }
                    return system.type;
                };

                // 浏览器名称(如果是壳浏览器,则返回壳名称)
                system.name = system.shell();
                // 对版本号进行过滤过处理
                // System.version = System.versionFilter(System.version);

            } catch (e) {
                // console.log(e.message);
            }

            return system;

        })(window);

        if (browser.name == undefined || browser.name == '') {
            browser.name = 'Unknown';
            browser.version = 'Unknown';
        }
        else if (browser.version == undefined) {
            browser.version = 'Unknown';
        }
        return browser;
    }

    function fetchRetry(url, options = {}, times = 1, delay = 1000, checkStatus = true) {
        return new Promise((resolve, reject) => {
            // fetch 成功处理函数
            function success(res) {
                if (checkStatus && !res.ok) {
                    failure(res);
                }
                else {
                    resolve(res);
                }
            }

            // 单次失败处理函数
            function failure(error) {
                times--;

                if (times) {
                    setTimeout(fetchUrl, delay);
                }
                else {
                    reject(error);
                }
            }

            // 总体失败处理函数
            function finalHandler(error) {
                throw error;
            }

            function fetchUrl() {
                return fetch(url, options)
                    .then(success)
                    .catch(failure)
                    .catch(finalHandler);
            }

            fetchUrl();
        });
    }

    // 下载指定url的资源
    async function downloadUrl(url, name = (new Date()).valueOf() + '.mp4') {
        let browser = getBrowerInfo();

        // Greasemonkey 需要把 url 转为 blobUrl
        if (GM_info.scriptHandler == 'Greasemonkey') {
            let res = await fetchRetry(url);
            let blob = await res.blob();
            url = URL.createObjectURL(blob);
        }

        // Chrome 可以使用 Tampermonkey 的 GM_download 函数绕过 CSP(Content Security Policy) 的限制
        if (window.GM_download) {
            GM_download({url, name});
        }
        else {
            // firefox 需要禁用 CSP, about:config -> security.csp.enable => false
            let a = document.createElement('a');
            a.href = url;
            a.download = name;
            // a.target = '_blank';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);

            setTimeout(function () {
                URL.revokeObjectURL(url);
            }, 100);
        }
    }

    function humanSize(size) {
        let n = Math.log(size) / Math.log(1024) | 0;
        return (size / Math.pow(1024, n)).toFixed(0) + ' ' + (n ? 'KMGTPEZY'[--n] + 'B' : 'Bytes');
    }

    if (!player) return;

    // 获取视频信息
    const res = await fetchRetry(playlistBaseUrl + videoId, {
        headers: {
            'referer': 'refererBaseUrl + videoId',
            'authorization': 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20' // in zplayer.min.js of zhihu
        }
    }, 3);
    const videoInfo = await res.json();

    // 获取不同分辨率视频的信息
    for (let [key, video] of Object.entries(videoInfo.playlist)) {
        video.name = key;

        if (!videos.find(v => v.width == video.width)) {
            videos.push(video);
        }
    }

    // 按分辨率大小排序
    videos = videos.sort(function (v1, v2) {
        return v1.width == v2.width ? 0 : (v1.width > v2.width ? 1 : -1);
    }).reverse();

    document.addEventListener('DOMNodeInserted', (evt) => {
        let domControlBar = evt.relatedNode.querySelector(':scope > div:last-child > div:first-child');
        if (!domControlBar || domControlBar.querySelector('.download')) return;

        let domFullScreenBtn = domControlBar.querySelector(':scope > div:nth-last-of-type(1)');
        let domResolutionBtn = domControlBar.querySelector(':scope > div:nth-last-of-type(3)');
        let domDownloadBtn, defaultResolution, buttons;
        if (!domFullScreenBtn || !domFullScreenBtn.querySelector('button')) return;

        // 克隆分辨率菜单或全屏按钮为下载按钮
        domDownloadBtn = (domResolutionBtn && (domResolutionBtn.className == domFullScreenBtn.className))
            ? domResolutionBtn.cloneNode(true)
            : domFullScreenBtn.cloneNode(true);

        defaultResolution = domDownloadBtn.querySelector('button').innerText;

        // 生成下载按钮图标
        domDownloadBtn.querySelector('button:first-child').outerHTML = domFullScreenBtn.cloneNode(true).querySelector('button').outerHTML;
        domDownloadBtn.querySelector('svg').innerHTML = svgDownload;
        domDownloadBtn.className = domDownloadBtn.className + ' download';

        buttons = domDownloadBtn.querySelectorAll('button');

        // button 元素添加对应的下载地址
        buttons.forEach(dom => {
            let video = videos.find(v => v.name == resolutionMap[dom.innerText || defaultResolution]);
            video = video || videos[0];
            dom.dataset.video = video.play_url;
            if (dom.innerText) {
                (dom.innerText = `${dom.innerText} (${humanSize(video.size)})`);
            }
            else if (buttons.length == 1) {
                dom.nextSibling.querySelector('div').innerText = humanSize(video.size);
            }
        });

        // 鼠标事件 - 显示菜单
        domDownloadBtn.addEventListener('pointerenter', () => {
            let domMenu = domDownloadBtn.querySelector('div:nth-of-type(1)');
            if (domMenu) {
                domMenu.style.cssText = menuStyle + 'opacity:1 !important; visibility:visible !important';
            }
        });

        // 鼠标事件 - 隐藏菜单
        domDownloadBtn.addEventListener('pointerleave', () => {
            let domMenu = domDownloadBtn.querySelector('div:nth-of-type(1)');
            if (domMenu) {
                domMenu.style.cssText = menuStyle;
            }
        });

        // 鼠标事件 - 选择菜单项
        domDownloadBtn.addEventListener('pointerup', event => {
            if (downloading) {
                alert('当前正在执行下载任务,请等待任务完成。');
                return;
            }

            let e = event.srcElement || event.target;

            while (e.tagName != 'BUTTON') {
                e = e.parentNode;
            }

            downloadUrl(e.dataset.video);
        });

        // 显示下载按钮
        domControlBar.appendChild(domDownloadBtn);

    });
})();

//https://greasyfork.org/zh-CN/scripts/382426
//youtube自动切换中文字幕
(function() {
    'use strict';
    
    var window_url = window.location.href;
    var website_host = window.location.host;
    
    if(website_host.indexOf("youtube.com")==-1){  //不是youtube就不执行
    	return;
    }
    var lang = null;
    function i8nInit(){
        try{
            lang = document.querySelector('html').getAttribute('lang').trim();
        }catch(err){

        };
    }

    function tr(text) {
        switch(lang) {
            case 'zh-CN':
            case 'zh':
                return i8nZhHans(text);
            case 'zh-TW':
            case 'zh-HK':
                return i8nZhHant(text);
            case 'en-US':
            case 'en':
            case 'en-GB':
                return i8nEnUS(text);
            default:
                return text;
        }
    }

    function i8nZhHans(text) {
        switch(text){
            case '开启翻译字幕':
            case '关闭翻译字幕':
            case '字幕':
            case '添加字幕':
            case '关闭':
            case '中文':
            case '简体':
            case '繁体':
            case '台湾':
            case '香港':
            case '自动翻译':
            case '自动生成':
            default:
                break;
        }
        return text;
    }

    function i8nZhHant(text) {
        switch(text){
            case '开启翻译字幕':
                return '開啟翻譯字幕';
            case '关闭翻译字幕':
                return '關閉翻譯字幕';
            case '字幕':
                return '字幕';
            case '添加字幕':
                return '新增字幕';
            case '关闭':
                return '關閉';
            case '中文':
                return '中文';
            case '简体':
                return '簡體';
            case '繁体':
                return '繁體';
            case '台湾':
                return '台灣';
            case '香港':
                return '香港';
            case '自动翻译':
                return '自動翻譯';
            case '自动生成':
                return '自動產生'
            default:
                break;
        }
        return text;
    }

    function i8nEnUS(text) {
        switch(text){
            case '开启翻译字幕':
                return 'Turn on subtitles';
            case '关闭翻译字幕':
                return 'Turn off subtitles';
            case '字幕':
                return 'Subtitles/CC';
            case '添加字幕':
                return 'add subtitles/CC';
            case '关闭':
                return 'off';
            case '中文':
                return 'Chinese (Simplified)';
            case '简体':
                return 'Chinese (Simplified)';
            case '繁体':
                return 'Chinese (Traditional)';
            case '台湾':
                return 'Chinese (Taiwan)';
            case '香港':
                return 'Chinese (Hong Kong)';
            case '自动翻译':
                return 'Auto-translate';
            case '自动生成':
                return 'auto-generated'
            default:
                break;
        }
        return text;
    }
    
    function getAbsPosition(el){
        var el2 = el;
        var curtop = 0;
        var curleft = 0;
        if (document.getElementById || document.all) {
            do  {
                curleft += el.offsetLeft-el.scrollLeft;
                curtop += el.offsetTop-el.scrollTop;
                el = el.offsetParent;
                el2 = el2.parentNode;
                while (el2 != el) {
                    curleft -= el2.scrollLeft;
                    curtop -= el2.scrollTop;
                    el2 = el2.parentNode;
                }
            } while (el.offsetParent);

        } else if (document.layers) {
            curtop += el.y;
            curleft += el.x;
        }
        return [curtop, curleft];
    };

    function getPlayer() {
        var player = document.querySelector('#ytd-player') || document.querySelector('#player');
        // 如果播放器的设置不在可视区域,就停止自动开启翻译
        var [x, y] = [0, 0]
        try {
            [x, y] = getAbsPosition(player);
        } catch(e) {
            return;
        }

        var visible_area = y + player.clientHeight - 250;
        if (document.scrollingElement.scrollTop > visible_area) {
            return null;
        }

        return player;
    }

    // 添加开关
    function InitTranslateButton(){
        var coltrol_place = document.querySelector('.ytp-chrome-controls .ytp-right-controls');
        if(coltrol_place && coltrol_place.querySelector('.plugins-trans-btn') == null) {
            var trans_coltrol_btn = document.createElement('button');
            trans_coltrol_btn.className = 'plugins-trans-btn';
            trans_coltrol_btn.style = 'position: relative;top: -36%; margin-right:10px; border-radius: 25px;border: none; opacity: 0.95; background-color: #fff; outline:none;';

            trans_coltrol_btn.onclick = function(){
                var trans_coltrol_state = window.localStorage.getItem('plugins-trans-state');
                if(trans_coltrol_state == 'on') {
                    window.localStorage.setItem('plugins-trans-state', 'off');
                    trans_coltrol_btn.innerText = tr('开启翻译字幕');
                    removeSubtitlesTrans();
                } else {
                    window.localStorage.setItem('plugins-trans-state', 'on');
                    trans_coltrol_btn.innerText = tr('关闭翻译字幕');
                }
            }

            if(isEnableTranslate()){
                trans_coltrol_btn.innerText = tr('关闭翻译字幕');
            } else {
                trans_coltrol_btn.innerText = tr('开启翻译字幕');
            }
            // 屏蔽youtube强行添加的事件
            trans_coltrol_btn.addEventListener = function() {};
            coltrol_place.prepend(trans_coltrol_btn);
        }
    }

    function isEnableTranslate(){
        var transState = window.localStorage.getItem('plugins-trans-state');
        return transState == 'on';
    }

    function hasOpenVideoSettings(){
        var menu = document.querySelector('.ytp-popup.ytp-settings-menu');
        return menu && menu.style.display != 'none';
    }

    function closeVideoSettingsPlace(){
        var menuPlace = document.querySelector('.ytp-settings-menu');
        var menuPlaceBtn = document.querySelector('.ytp-settings-button');
        if(menuPlace && menuPlace.style.display != 'none') {
            menuPlaceBtn.click();
        }
    }

    function openVideoSettingsPlace(callback){
        if(!hasOpenVideoSettings()) {
            var menuPlaceBtn = document.querySelector('.ytp-settings-button');
            if(menuPlaceBtn) {
                menuPlaceBtn.click();
                callback();
            }
        } else {
            callback();
        }
    }

    function hasVideoSubtitles(){
        var dom = document.querySelector('.ytp-subtitles-button.ytp-button');
        return  dom != null && dom.style.display != 'none';
    }

    // 需要修改
    function openVideoSubtitles(){
        var settingsPlaceItems = document.querySelectorAll('.ytp-popup.ytp-settings-menu .ytp-menuitem');
        settingsPlaceItems.forEach(function(item) {
            if(item.innerText && item.innerText.indexOf(tr('字幕')) > -1 && item.innerText.indexOf(tr('添加字幕')) == -1) {
                item.click();
                return;
            }
        });

        // 内置简体字幕
        settingsPlaceItems.forEach(function(item) {
            if(item.innerText && item.innerText.indexOf(tr('简体')) > -1) {
                item.click();
                // 防止无限点击菜单
                setSubtitlesTrans('zh-Hans');
                closeVideoSettingsPlace();
                return;
            }
        });
        
        var curLnag = getSubtitlesTrans();
        if(curLnag == 'inner-Substitle') {
            // 如果没有简体字,就打开自动翻译
            settingsPlaceItems.forEach(function(item) {
                if(item.innerText && item.innerText.indexOf(tr('自动翻译')) > -1) {
                    item.click();
                    setSubtitlesTrans('inner-Substitle');
                    return;
                }
            });

        } else if(curLnag != 'zh-Hans') {
            // 如果没有就打开繁体字
            settingsPlaceItems.forEach(function(item) {
                if(item.innerText) {
                    ['繁体', '台湾', '香港', '中文'].forEach(function(langText) {
                        langText = tr(langText)
                        if(item.innerText.indexOf(langText) > -1) {
                            item.click();
                            setSubtitlesTrans('inner-Substitle');
                            closeVideoSettingsPlace();
                            return;
                        }
                    });
                }
            });

            var title = document.querySelector('.ytp-button.ytp-panel-title').innerText.trim();
            if(title.indexOf(tr('字幕')) >= -1) {
                // 没有中文相关字幕,就随便选一个字幕,然后才自动翻译
                settingsPlaceItems.forEach(function(item) {
                    if(item.innerText) {
                        var langText = item.innerText.trim();
                        if(langText.indexOf(tr('添加字幕')) == -1 && langText.indexOf(tr('关闭')) == -1) {
                            setSubtitlesTrans('inner-Substitle');
                            closeVideoSettingsPlace();
                            return;
                        }
                    }
                });

                settingsPlaceItems.forEach(function(item) {
                    if(item.innerText && item.innerText.indexOf(tr('自动生成')) > -1) {
                        item.click();
                        setSubtitlesTrans('inner-Substitle');
                        closeVideoSettingsPlace();
                        return;
                    }
                });
            }
        }
    }

    function displaySubtitles() {
        var subtitle = document.querySelector('.ytp-subtitles-button.ytp-button[aria-pressed="false"]');
        if(subtitle) {
            subtitle.click();
        }
    }

    function isSubtitlesTrans(){
        // curLang == 'zh-Hant'
        // 统一所有语言设置翻译为简体中文
        // en-UK: en-gb
        // en-US:  en
        // zh-CN zh-Hans zh-Hant
        return getSubtitlesTrans() == 'zh-Hans';
    }

    function removeSubtitlesTrans() {
        try {
            document.querySelector('.ytp-player-content').removeAttribute('translate-zh-hans');
        }catch(err) {

        }
    }

    function getSubtitlesTrans(){
        try {
            return document.querySelector('.ytp-player-content').getAttribute('translate-zh-hans');
        }catch(err) {
            return lang;
        }
    }

    function setSubtitlesTrans(lang) {
        document.querySelector('.ytp-player-content').setAttribute('translate-zh-hans', lang);
    }

    function openSubtitles(){
        
        if(hasVideoSubtitles()) {
            displaySubtitles();

            var isTrans = isSubtitlesTrans();
            console.log(isTrans);
            if(isTrans == false) {
                // 采用callback方式打开和关闭,防止settimeout导致的问题
                openVideoSettingsPlace(function() {
                    // 切换字幕
                    openVideoSubtitles();
                });
            }
        } else {
            try {
                // 防止切换视频过程,打开字幕,不关闭
                var title = document.querySelector('.ytp-button.ytp-panel-title').innerText.trim();
                if(title.indexOf(tr('字幕')) >= -1) {
                    closeVideoSettingsPlace();
                }
            }catch(err) {

            }
        }
    }

    function updateColtrolButtonState() {
        var transState = window.localStorage.getItem('plugins-trans-state');
        var transBtn = document.querySelector('.plugins-trans-btn')
        if(transBtn) {
            if(transState == 'on' && transBtn.innerText != tr('关闭翻译字幕')) {
                transBtn.innerText = tr('关闭翻译字幕');
            } else if(transState == 'off' && transBtn.innerText != tr('开启翻译字幕')) {
                transBtn.innerText = tr('开启翻译字幕');
            }
        }
    }

    function hidePageAds()
    {
        ['.video-ads', '#player-ads'].forEach(function(selector) {
            document.querySelectorAll(selector).forEach(function(elment){
                elment.style.display = 'none';
            });
        });
    }

    function isVideoAdsTime(){
        var ad = document.querySelector('.ad-showing');
        var skipAdButton = document.querySelector('.ytp-ad-skip-button');

        var volumeOpenState = document.querySelector("#ytp-svg-volume-animation-mask");
        var volumeButton = document.querySelector('.ytp-mute-button');
        // 判断有没有广告
        if(ad){
            // 关闭音量
            if(volumeOpenState && volumeButton)
            {
                volumeButton.click();
            }
        } else {
            // 正常视频,打开音量
            if(volumeOpenState == null && volumeButton){
                volumeButton.click();
            }
        }
        
        // 跳过广告
        if(skipAdButton)
        {
            skipAdButton.click();
        }
        return ad != null;
    }

    function main() {
        i8nInit();
        setInterval(
            function() {
                // 不显示错误信息
                try{
                    getPlayer() && (function(){
                        InitTranslateButton();
                        updateColtrolButtonState();
                        if(isEnableTranslate()){
                            hidePageAds();
                            if(!isVideoAdsTime()) {
                                openSubtitles();
                            }
                        }
                    })();
                }catch(err) {
    
                }
            },
            500
        )
    };
    main();
})();