// ==UserScript== // @name 阿里云盘播速 // @namespace http://tampermonkey.net/ // @version 0.3.1 // @description 键盘控制播速,鼠标控制播速和全屏和播放,播速1秒显示,外挂字幕大小三级调节,点击自动搜索字幕(可下载) // @author tfsn20 // @match https://www.aliyundrive.com/* // @run-at document-idle // @icon https://gw.alicdn.com/imgextra/i3/O1CN01aj9rdD1GS0E8io11t_!!6000000000620-73-tps-16-16.ico // @grant GM_addStyle // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @connect cn.bing.com // @connect movie.douban.com // @connect zimuku.org // ==/UserScript== (function () { //'use strict'; //最近在看油猴教程:https://bbs.tampermonkey.net.cn/thread-184-1-1.html //思路来源:https://bbs.tampermonkey.net.cn/thread-176-1-1.html文章及评论 //速度0.1控制 //键盘c,x,z,d分别是加速,减速,恢复1倍速和恢复之前倍速,d长按3倍速松开恢复长按之前的倍速, //鼠标滚轮上滑、下滑、右键单击分别对应键盘c,x,z键功能 //鼠标左键单击、左键双击分别是视频暂停或播放,全屏或退出全屏,点击区域为视频区域 //若想把c,x,z,d改为其他键,则修改源码中的keydown(e)函数中的四个e.keyCode==后的值,自行百度 //代码没优化很烂,UI很丑,完全自学边学边百度 //新增 //滚轮区域判定 //字幕大小还是通过原生播放器的字幕尺寸调节实现,发现大小写不合适可以修改源码中的changeSubtitle函数的实参 //新增 //点击自动搜索字幕(可下载) //hook console.log setTimeout(() => { let hookLog = unsafeWindow.console.log; unsafeWindow.console.log = (VideoPreviewerSetFile, name) => { if (name) { //.error(name.match(/(.*)\./)); let nameTemp = name.match(/(.*)\./)[1] if (nameTemp != GM_getValue('movieName')) { GM_setValue('movieName', nameTemp); console.error(GM_getValue('movieName')) }; return hookLog(VideoPreviewerSetFile, ...name) //console.error(name) }else{ return hookLog(VideoPreviewerSetFile) } } console.log('coding', "==="); }, 0) //调节字幕位置和大小,增大bottom可向上移动,mediumSize是标准字幕大小,changeUnit是调节单位大小 function changeSubtitle(bottom, mediumSize, changeUnit) { setTimeout(function () { var style = document.createElement('style'); style.innerHTML = ` .subtitle--1Ou09 { bottom: ${bottom}% } .subtitle--1Ou09 .cue--sviQg.cue-small--26YAf { font-size: ${mediumSize - changeUnit}% } .subtitle--1Ou09 .cue--sviQg.cue-medium--2z-Pf { font-size: ${mediumSize}% } .subtitle--1Ou09 .cue--sviQg.cue-large--1cmde { font-size: ${mediumSize + changeUnit}% } ` document.querySelector('head').append(style); }, 5000) } changeSubtitle(3, 5.5, 1.5) //主函数, function main() { var presentSpeed = 1; var div = 0; function display() { div.classList.remove('displaynone'); div.classList.add('display') div.innerHTML = `${presentSpeed}`; }; function displayNone() { div.classList.remove('display'); div.classList.add('displaynone') }; document.addEventListener('DOMNodeInserted', listenVideo, false) function listenVideo() { if (document.querySelector("video[class^='video--']") == null) { //console.log('no') } else { document.removeEventListener('DOMNodeInserted', listenVideo, false) console.log("is"); changeSpeed(); div = document.createElement("div"); div.setAttribute('id', 'displayspeed') div.innerHTML = `${presentSpeed}`;//innerText也可以,区别是innerText不会解析html document.querySelector("video[class^='video--']").parentNode.append(div); GM_addStyle("div#displayspeed { background-color:white; width:30px; height:25px; position:fixed; top:0px; left:0px; }"); GM_addStyle(".display { display:block }"); GM_addStyle(".displaynone { display:none }"); div.classList.add('displaynone'); console.log('display has append'); let subtitleBtn = null; setTimeout(function () { subtitleBtn = document.querySelectorAll('div.action--mAI5b')[2]; searchSubtitle() }, 500); //字幕搜索相关函数 function searchSubtitle() { //通过bing site获取电影豆瓣ID和名称 function getMovieIDByDouban() { return new Promise((res, rej) => { GM_xmlhttpRequest({ url: `https://cn.bing.com/search?q=site:movie.douban.com/subject ${GM_getValue('movieName')}`, method: "get", headers: { "Sec-Fetch-Site": "none", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", 'Host': 'cn.bing.com', 'Cache-Control': ' max-age=0', 'Upgrade-Insecure-Requests': ' 1', }, onload: function (xhr) { //console.log(xhr.response); res(xhr.response.match(/https:\/\/movie\.douban\.com\/subject\/(\d*).{0,20}<\/cite>/)) } }) }) }; function getMovieNameByID(moviesID) { return new Promise((res, rej) => { GM_xmlhttpRequest({ url: `https://movie.douban.com/subject/${moviesID}/`, method: "get", headers: { "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-User": "?1", "Sec-Fetch-Dest": "document", 'Host': 'movie.douban.com', 'sec-gpc': 1, 'Upgrade-Insecure-Requests': ' 1', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Referer': ' https://movie.douban.com/', }, onload: function (xhr) { res(xhr.response.match(/

\n.*(.*)<\/span>\n.*(.*)<\/span>\n.*<\/h1>/)); } }) }) }; let movieDetail = null; let movieNameDouban = null; let movieID = null; let movieNameYear = null; //点击字幕按钮则获取电影信息 GM_addValueChangeListener('movieName', function (name, old_value, new_value, remote) { getMovieDetails() }) subtitleBtn.addEventListener('click', getMovieDetails, false); async function getMovieDetails() { subtitleBtn.removeEventListener('click', getMovieDetails, false); movieDetail = await getMovieIDByDouban(); if (movieDetail) { movieID = movieDetail[1] movieNameDouban = await getMovieNameByID(movieID); let asciiFlag = movieNameDouban[1].match(/.*&#(\d*);.*/); if (asciiFlag) { movieNameDouban[1] = movieNameDouban[1].replace(/&#\d*;/, String.fromCharCode(asciiFlag[1])) //console.log(movieNameDouban[1]) } movieNameYear = movieNameDouban[1] + movieNameDouban[2]; }; //console.log('movie name:', movieNameDouban); console.log('movie id:', movieID + '\n', 'movie name (year):', movieNameYear) } GM_setValue('movieName', document.querySelector('span.text--2KGvI').innerHTML.match(/(.*)\./)[1]) // movieName = document.querySelector('span.text--2KGvI').innerHTML; // movieName = movieName.match(/(.*)\./)[1]; //console.log(movieNameYear) addDownloadSubtitle(); //添加div function addDownloadSubtitle() { var divDownloadSubtitle = null; console.log(GM_getValue('movieName')); divDownloadSubtitle = document.createElement("div"); divDownloadSubtitle.setAttribute('class', 'drawer-label--1ph93'); divDownloadSubtitle.innerHTML = `下载字幕`; document.querySelector("div[class='subtitle-fontsize-list--mjtuN']").parentNode.append(divDownloadSubtitle); var divDownloadSubtitleChoice = null; divDownloadSubtitleChoice = document.createElement("div"); divDownloadSubtitleChoice.setAttribute('class', 'subtitle-fontsize-list--mjtuN'); divDownloadSubtitleChoice.innerHTML = `
SubHD
点点
4k-m
射手网(伪)
字幕库
`; document.querySelector("div[class='subtitle-fontsize-list--mjtuN']").parentNode.append(divDownloadSubtitleChoice); let downloadBtnLength = divDownloadSubtitleChoice.children.length //为增加的div绑定事件 for (let i = 0; i < downloadBtnLength; i++) { divDownloadSubtitleChoice.children[i].addEventListener('click', function () { for (let j = 0; j < downloadBtnLength; j++) { divDownloadSubtitleChoice.children[j].classList.remove('selected--DHMNk'); //console.log(divDownloadSubtitleChoice.children[j].classList) }; divDownloadSubtitleChoice.children[i].classList.add('selected--DHMNk') //打开新标签 setTimeout(async () => { if (i == 0) { window.open(`https://subhd.tv/d/${movieID}?o=down`, '_blank') } else if (i == 1) { window.open(`http://www.ddzimu.com/download/${movieID}.html`, '_blank') } else if (i == 2) { window.open(`https://4k-m.com/zimu/?a=2&s=${movieID}`, '_blank') } else if (i == 3) { window.open(`http://assrt.net/sub/?searchword=${movieNameYear}`, '_blank') } else if (i == 4) { GM_xmlhttpRequest({ url: 'http://zimuku.org/', method: "get", headers: { // "Sec-Fetch-Site": "same-origin", // "Sec-Fetch-Mode": "navigate", // "Sec-Fetch-User": "?1", // "Sec-Fetch-Dest": "document", 'Cache-Control': 'max-age=0', 'sec-gpc': 1, 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Host': 'zimuku.org', 'Upgrade-Insecure-Requests': ' 1', 'Referer': ' http://zimuku.org/', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,ja;q=0.5' }, onload: function (xhr) { //console.log(xhr.response); let vertoken = xhr.response.match(/name="vertoken"\svalue="(.*)"/); if (vertoken) { console.log('vertoken', vertoken[1]); window.open(`http://zimuku.org/search?q=${movieNameYear}&vertoken=${vertoken[1]}`, '_blank') } else { GM_xmlhttpRequest({ url: 'http://zimuku.org/?security_verify_data=313336362c373638', method: "get", headers: { // "Sec-Fetch-Site": "same-origin", // "Sec-Fetch-Mode": "navigate", // "Sec-Fetch-User": "?1", // "Sec-Fetch-Dest": "document", 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'sec-gpc': 1, 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,ja;q=0.5', 'Upgrade-Insecure-Requests': ' 1', //'Cache-Control': ' max-age=0', 'Host': 'zimuku.org', 'Referer': 'http://zimuku.org/', }, onload: function (xhr) { //console.log(xhr.response); vertoken = xhr.response.match(/name="vertoken"\svalue="(.*)"/); if (vertoken) { console.log('vertoken', vertoken[1]); window.open(`http://zimuku.org/search?q=${movieNameYear}&vertoken=${vertoken[1]}`, '_blank') } } }) } } }) } }, 0); }) } } } } } function changeSpeed() { console.log(presentSpeed); var temp = 0; var close = document.querySelectorAll('span[data-icon-type="PDSClose"]')[1]; var playBtn = document.querySelector('div[class^=action-bar--]').children[0].children[0]; var fullBtn = 0; setTimeout(function () { fullBtn = document.querySelectorAll('div[data-disabled="false"][class^="action"]')[6] }, 500) //console.log(close, fullBtn); close.addEventListener('click', function () { console.log('has close'); //垃圾回收和清除window事件 div.remove(); if (temp) { clearInterval(temp); console.log('has clear') }; window.removeEventListener('keydown', keydown, false); window.removeEventListener('keyup', keyup, false); window.removeEventListener('wheel', wheel, false); window.removeEventListener('click', click, false); window.removeEventListener('dblclick', click, false); window.removeEventListener('mousedown', mousedown, false) setTimeout(function () { main(); }, 1000) console.log('clear finish'); }) //属性选择器,选择class名开头为video--的video元素 var video = document.querySelector("video[class^='video--']"); if (video != null) { function st(speed, time) { if (temp) { clearInterval(temp); console.log('has clear interval') } temp = setInterval(function () { setVideoPlaySpeed(speed) }, time); function setVideoPlaySpeed(speed) { video.playbackRate = speed.toFixed(1) - 0 } presentSpeed = speed; displaySpeed() return presentSpeed } var flag = false; var dTemp = 0; window.addEventListener('keydown', keydown, false); function keydown(e) { //e.keyCode if (e.keyCode == 90) { if (video.playbackRate == 1) { var cTemp = video.playbackRate = presentSpeed.toFixed(1) - 0; console.log('z', video.playbackRate, st(cTemp.toFixed(1) - 0, 5000)) } else { if (temp) { clearInterval(temp); console.log('has clear') } video.playbackRate = 1; display(); div.innerHTML = `1`; setTimeout(function () { displayNone() }, 1000) console.log('z', video.playbackRate) } return } if (e.keyCode == 88) { var bTemp = video.playbackRate = video.playbackRate.toFixed(1) - 0.1; console.log('x', video.playbackRate, st(bTemp.toFixed(1) - 0, 5000)) return } if (e.keyCode == 67) { var aTemp = video.playbackRate = video.playbackRate.toFixed(1) - 0 + 0.1; console.log('c', video.playbackRate, st(aTemp.toFixed(1) - 0, 5000), e.key); return } if (e.keyCode == 68) { if (flag) { return } else { dTemp = video.playbackRate; video.playbackRate = 3; flag = true; } } }; function keyup(e) { if (e.key == 'd') { console.log(video.playbackRate, dTemp); video.playbackRate = dTemp; console.log(video.playbackRate, dTemp); flag = false; } }; function wheel(e) { //console.log(e); let evt = e || window.event; //考虑兼容性 //evt.preventDefault(); if (e.target.tagName == 'IMG' || e.target.tagName == 'VIDEO') { if (evt.deltaY > 0) { //在火狐中 向下滚动是3 谷歌是125 console.log("向下滚动"); var bTemp = video.playbackRate = video.playbackRate.toFixed(1) - 0.1; console.log('x', video.playbackRate, st(bTemp.toFixed(1) - 0, 5000)) } else { //在火狐中 向上滚动是-3 谷歌是-125 console.log("向上滚动"); var aTemp = video.playbackRate = video.playbackRate.toFixed(1) - 0 + 0.1; console.log('c', video.playbackRate, st(aTemp.toFixed(1) - 0, 5000)); } } }; var timeOutTemp = 0; //鼠标点击 function click(e) { if (e.target.tagName == 'IMG' || e.target.tagName == 'VIDEO') { if (e.type == 'click') { if (timeOutTemp) { clearTimeout(timeOutTemp) } timeOutTemp = setTimeout(function () { if (video.paused) { playBtn.click() //video.play() } else { video.pause() } console.log('单击') }, 250) } else { if (timeOutTemp) { clearTimeout(timeOutTemp) } console.log('双击'); fullBtn.click(); } } }; function mousedown(e) { if (e.target.tagName == 'IMG' || e.target.tagName == 'VIDEO' && e.button == 2) { if (video.playbackRate == 1) { var cTemp = video.playbackRate = presentSpeed.toFixed(1) - 0; console.log('z', video.playbackRate, st(cTemp.toFixed(1) - 0, 5000)) } else { if (temp) { clearInterval(temp); console.log('has clear') } video.playbackRate = 1; display(); div.innerHTML = `1`; setTimeout(function () { displayNone() }, 1000) console.log('z', video.playbackRate) } console.log(e.type); return } } window.addEventListener('keyup', keyup, false); window.addEventListener('wheel', wheel, false); window.addEventListener('click', click, false); window.addEventListener('dblclick', click, false); window.addEventListener('mousedown', mousedown, false) } } function displaySpeed() { display(); setTimeout(function () { displayNone() }, 1000) } } main() // Your code here... })();