Greasy Fork is available in English.
此脚本为《PotPlayer播放云盘视频》姊妹篇,需配合MediaPlayParse - PanVideo.as脚本使用。在potplayer中选择画质、字幕,迅雷云盘增加原画,阿里云盘增加时长。
// ==UserScript== // @name PotPlayer云盘-专供版 // @namespace https://github.com/Bleu404/PotplayerPanVideoSV // @version 1.1.0 // @description 此脚本为《PotPlayer播放云盘视频》姊妹篇,需配合MediaPlayParse - PanVideo.as脚本使用。在potplayer中选择画质、字幕,迅雷云盘增加原画,阿里云盘增加时长。 // @author bleu // @compatible edge Tampermonkey // @compatible chrome Tampermonkey // @compatible firefox Tampermonkey // @license MIT // @match https://pan.xunlei.com/* // @match https://www.aliyundrive.com/* // @icon https://fastly.jsdelivr.net/gh/Bleu404/PRPO@latest/png/ppvsv.png // @grant GM_setValue // @grant GM_getValue // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant unsafeWindow // @connect * // @connect xunlei.com // @connect aliyundrive.com // @connect jianguoyun.com // @connect teracloud.jp // @require https://fastly.jsdelivr.net/npm/[email protected]/dist/sweetalert2.all.min.js // @require https://fastly.jsdelivr.net/npm/[email protected]/bleutools.min.js // ==/UserScript== (function () { 'use strict'; const ORGXHRSRH = XMLHttpRequest.prototype.setRequestHeader; let bleuc,contextMenu, itemsInfo, arryIndex, Option, observer,cloud; const flieTypeStr = ".wmv,.rmvb,.avi,.mp4,.mkv,.flv,.swf.mpeg4,.mpeg2,.3gp,.mpga,.qt,.rm,.wmz,.wmd,.wvx,.wmx,.wm,.mpg,.mpeg,mov,.asf,.m4v,"; const tools = { getCloudName() { switch (document.domain) { case 'xunlei.com': cloud = xunlei; break; case 'pan.xunlei.com': cloud = xunlei; break; case 'www.aliyundrive.com': cloud = aliyun; this.hookXHRHeader(); break; } }, checkFileType(name) { let type = name.toLowerCase().substring(name.lastIndexOf('.')) || "bleu" return flieTypeStr.indexOf(`${type},`) >= 0 ? true : false }, async putFileInWebdav(name, info) { let header = { "authorization": `Basic ${btoa(`${bleuc.cun}:${bleuc.cpw}`)}` } let url = `https://${bleuc.cip}/PanPlaylist`; let method = bleuc.cip.indexOf('teracloud')>0?'GET':'PROPFIND'; await bleu.XHR(method, url, undefined, header, undefined).then( () => {} ,async()=>{await bleu.XHR('MKCOL', url, undefined, header, undefined)}) url = `https://${bleuc.cip}/PanPlaylist/${name}`; await bleu.XHR('PUT',url , info, header, 'xml').then(() => { bleu.swalInfo(`✅${name}`, 3000, 'center'); }, () => bleu.swalInfo(`❌${name}`, 3000, 'center')) }, checkConfig() { bleuc = JSON.parse(GM_getValue('bleuc') || null) || {cip: '',cun: '',cpw: ''}; if (!(bleuc.cip != '' && bleuc.cun != '' && bleuc.cpw != '')) { bleu.swalInfo(`❗请先设置WEBDAV`, '', 'center') return false } return true }, saveConfig() { let temp = document.querySelector('#cip').value.trim() temp = temp.charAt(temp.length - 1) === '/' ? temp.substring(0, temp.length - 1) : temp temp = temp.indexOf('https://') < 0 ? temp : temp.replace('https://', '') GM_setValue("bleuc", JSON.stringify({ 'cip': temp, 'cun': document.querySelector('#cun').value.trim(), 'cpw': document.querySelector('#cpw').value.trim(), })); }, configHtml() { bleuc = JSON.parse(GM_getValue('bleuc') || null) || {cip: '',cun: '',cpw: ''}; let html = ` <div class="bleuc_config_item"><p> <div><label>主机:</label><input type="text" class="bleuc_inp" id="cip" value="${bleuc.cip}"/></div> <div><label>用户:</label><input type="text" class="bleuc_inp" id="cun" value="${bleuc.cun}"/></div> <div><label>密码:</label><input type="text" class="bleuc_inp" id="cpw" value="${bleuc.cpw}"/></div></p></div> `; return html; }, hookXHRHeader() { XMLHttpRequest.prototype.setRequestHeader = function(header, value) { if(header == "x-signature"){ aliyun._signature=value; } return ORGXHRSRH.apply(this, arguments); } }, cssStyle: ` .bleuc_config_item{border-radius: 10px;font-size: 20px;margin: 12px 50px;color: #fff;background: linear-gradient(45deg,#12c2e9, #c471ed, #f64f59);box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);} .bleuc_config_item label{font-size: 15px} .bleuc_config_item input.bleuc_inp{margin: 0px 10px;font-size: 15px;background: linear-gradient(45deg,#12c2e9, #c471ed, #f64f59);border-style:none;color:black;width:200px} .bleuc_config_item p{text-align: left;margin: 0px 20px;}`, } const xunlei = { addTag() { if (contextMenu.innerText.match(/PotPlayer/)) return let ul = document.createElement('ul'); ul.innerHTML = `<a id="bleuReSave" class="pan-dropdown-menu-item">PotPlayer打开</a>`; contextMenu.firstChild.prepend(ul.firstChild); main.addClickEvent(); }, getselectFilesInfo() { let temp = document.querySelectorAll('li.SourceListItem__item--XxpOC.SourceListItem__active--4U0f4'); temp.forEach((item) => { this._pushItem(item.__vue__.info); }) }, async updateFile(item) { Option["list"].push({ "title": item.name, "url": `https://api-pan.xunlei.com/drive/v1/files/${item.id}` }); }, async openNextDir(item) { let url = `https://api-pan.xunlei.com/drive/v1/files?limit=100&parent_id=${item.id}&filters={"phase":{"eq":"PHASE_TYPE_COMPLETE"},"trashed":{"eq":false}}&with_audit=true`; await bleu.XHR('GET', url, undefined, Option.header).then((res) => { arryIndex++; res.files.forEach((item) => { xunlei._pushItem(item); }) },()=>{ bleu.swalInfo("❗进出目录之后重新转存", '', 'center'); throw "PPVSV:迅雷-超时,重新转存"; }) }, findContext(node) { if (node.className === 'pan-content') { node = node.querySelector('div.pan-dropdown-menu.context-menu'); if (!node) return; contextMenu = node; xunlei.addTag(); } }, closeMenu() {}, _pushItem(temp) { if (!itemsInfo[arryIndex]) itemsInfo[arryIndex] = []; if (temp.kind === 'drive#file' && !tools.checkFileType(temp.name)) return let itemInfo = { 'id': temp.id, 'isdir': temp.kind === 'drive#file' ? false : true, 'name': temp.name, }; itemsInfo[arryIndex].push(itemInfo); }, getHeaderInfo() { Option.header = {}; Option.header.withCredentials = false; Option.header['content-type'] = 'application/json'; for (let key in localStorage) { let temp = localStorage.getItem(key) if (key.indexOf('credentials') === 0) { Option.header["Authorization"] = JSON.parse(temp).token_type + ' ' + JSON.parse(temp).access_token; Option.header["token_type"] = JSON.parse(temp).token_type; Option.header["access_token"] = JSON.parse(temp).access_token; Option.header["refresh_token"] = JSON.parse(temp).refresh_token; Option["clientid"] = key.substring(key.indexOf('_') + 1); } if (key.indexOf('captcha') === 0) Option.header['x-captcha-token'] = JSON.parse(temp).token if (key === 'deviceid') Option.header['x-device-id'] = temp.substring(temp.indexOf('.') + 1, 32 + temp.indexOf('.') + 1) } }, async finallyFunc() { Option.header["clientid"] = Option["clientid"]; await tools.putFileInWebdav('panvideo.txt', JSON.stringify(Option)); unsafeWindow.location.href = `potplayer://panvideo##xunlei##https://${bleuc.cip}/PanPlaylist/panvideo.txt##${bleuc.cun}##${bleuc.cpw}`; } } const aliyun = { addTag() { if (contextMenu.innerText.match(/PotPlayer|新建/)) return let ul = document.createElement('ul'); ul.innerHTML = `<li id="bleuReSave" class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child" role="menuitem"><div class="outer-menu--ihDUR"><div data-confirm="false" class="menu-wrapper--1ZYh_" data-spm-anchor-id="aliyundrive.drive.0.i11.40516c75ahPUGN"><div class="menu-name--1F5vk" data-spm-anchor-id="aliyundrive.drive.0.i12.40516c75ahPUGN">PotPlayer打开</div></div></div></li>`; contextMenu.prepend(ul.firstChild); main.addClickEvent(); }, getselectFilesInfo() { let temp = document.querySelectorAll('div[data-index]') let attrName; for(let attr in temp[0]){ if(attr.indexOf('__reactFiber')==0){ attrName = attr; break; } } temp.forEach((item)=>{ if(item.querySelector('input')&&item.querySelector('input').checked){ let value = item[attrName].return.pendingProps; aliyun._pushItem(value.data[value.index]||value.data[value.rowIndex][value.columnIndex]); } }) }, async updateFile(item) { Option["list"].push({ "title": item.name, "url": "https://"+item.id }); }, async openNextDir(item) { let url = `https://api.aliyundrive.com/adrive/v3/file/list?jsonmask=next_marker%2Citems(name%2Cfile_id%2Cdrive_id%2Ctype%2Csize%2Ccreated_at%2Cupdated_at%2Ccategory%2Cfile_extension%2Cparent_file_id%2Cmime_type%2Cstarred%2Cthumbnail%2Curl%2Cstreams_info%2Ccontent_hash%2Cuser_tags%2Ctrashed%2Cvideo_media_metadata%2Cvideo_preview_metadata)`, token = JSON.parse(localStorage.getItem('token')), data = { 'drive_id': token.default_drive_id, 'parent_file_id': item.id, 'limit': 100, }, header = { 'x-canary': 'client=web,app=adrive,version=v2.4.0', 'x-device-id': document.cookie.match(/cna=([^;]*)/)[1], authorization: `${token.token_type} ${token.access_token}`, 'x-signature':this._signature }; await bleu.XHR('POST', url, JSON.stringify(data),header).then((res) => { arryIndex++; res.items.forEach((item)=>{ aliyun._pushItem(item); },()=>{ bleu.swalInfo("🔴💬刷新页面,重新获取", '', 'center'); throw "PPVSV:阿里-超时,重新转存"; }) }) }, _signature:'', findContext(node) { node = document.querySelector('ul.ant-dropdown-menu'); if (!node) return; //observer.disconnect(); contextMenu = node; aliyun.addTag(); }, closeMenu(){ contextMenu.parentNode.className='ant-dropdown dropdown-menu--1KRbu ant-dropdown-placement-bottomLeft ant-dropdown-hidden'; contextMenu.parentNode.style.left='-578px'; contextMenu.parentNode.style.top='-646px'; }, _pushItem(temp) { if(!itemsInfo[arryIndex]) itemsInfo[arryIndex]= []; if (temp.type==='file'&&temp.category!="video") return let itemInfo = { 'id': temp.fileId||temp.file_id, 'isdir': temp.type === 'file' ? false : true, 'name': temp.name, }; itemsInfo[arryIndex].push(itemInfo); }, getHeaderInfo() { Option.header ={}; let token = JSON.parse(localStorage.getItem('token')); Option.header["authorization"] =`${token.token_type} ${token.access_token}`; Option.header["drive_id"] =token.default_drive_id; Option.header["x-signature"]=this._signature; Option.header["x-device-id"]=document.cookie.match(/cna=([^;]*)/)[1];//decodeURIComponent(localStorage.getItem('APLUS_CNA').substring(9)) }, async finallyFunc(){ await tools.putFileInWebdav('panvideo.txt', JSON.stringify(Option)); unsafeWindow.location.href = `potplayer://panvideo##aliyun##https://${bleuc.cip}/PanPlaylist/panvideo.txt##${bleuc.cun}##${bleuc.cpw}`; } } const main = { init() { observer = new MutationObserver(function (mutations) { for (let mutation of mutations) { if (mutation.type === 'childList') { cloud.findContext(mutation.target); } } }); observer.observe(document, { 'childList': true, 'subtree': true }); }, addClickEvent() { let bleuButton = document.getElementById('bleuReSave'); bleuButton.addEventListener('click', async function () { itemsInfo = []; arryIndex = 0; Option = {}, Option["list"] = []; if(!tools.checkConfig())return; cloud.closeMenu(); cloud.getselectFilesInfo(); cloud.getHeaderInfo(); if (!itemsInfo[arryIndex]||itemsInfo[arryIndex].length === 0) { bleu.swalInfo(`❌未选择文件转存!`, 3000, 'center') return; } try { await main.updateAllFiles(itemsInfo[arryIndex]); } catch (e) { console.log(e); return; } Option["list"].length!=0&&cloud.finallyFunc(); }) }, async updateAllFiles(loopArry) { for (let index = 0; index < loopArry.length; index++) { if (!loopArry[index].isdir) { await cloud.updateFile(loopArry[index]); } else { await cloud.openNextDir(loopArry[index]); await main.updateAllFiles(itemsInfo[arryIndex]); } bleu.sleep(800); } }, }; tools.getCloudName(); //tools.checkConfig(); bleu.addCssStyle(tools.cssStyle); GM_registerMenuCommand('配置WEBDAV', () => { bleu.swalUI('WEBDAV', tools.configHtml(), '400px').then(tools.saveConfig) }, 'w') main.init(); })();