// ==UserScript== // @name 百度网盘视频播放增强-🚀4K高清🚀 // @version 1.2.7 // @description 一款百度网盘视频播放增强插件,支持4K高清播放,流畅不卡顿! // @antifeature ads // @author You // @license MIT // @icon https://nd-static.bdstatic.com/m-static/v20-main/home/img/icon-home-new.b4083345.png // @match *://pan.baidu.com/* // @match *://yun.baidu.com/* // @match *://pan.baidu.com/disk/home* // @match *://yun.baidu.com/disk/home* // @match *://pan.baidu.com/disk/main // @match *://yun.baidu.com/disk/main* // @match *://pan.baidu.com/s/* // @match *://yun.baidu.com/s/* // @match *://pan.baidu.com/share/* // @match *://yun.baidu.com/share/* // @connect baidu.com // @connect d.pcs.baidu.com // @connect vv1.ainsource.com // @grant GM_cookie // @grant GM_addStyle // @grant GM_getResourceText // @grant GM_xmlhttpRequest // @require https://cdnjs.cloudflare.com/ajax/libs/layui/2.9.14/layui.min.js // @require https://unpkg.com/sweetalert/dist/sweetalert.min.js // @resource layuiCSS https://cdnjs.cloudflare.com/ajax/libs/layui/2.9.14/css/layui.css // ==/UserScript== (function () { 'use strict'; const layuicss = GM_getResourceText('layuiCSS'); GM_addStyle(layuicss); const config = { main_url: 'https://vv1.ainsource.com', bd_password: '1234', title_name: '播放', player: null, }; // 平台识别(与 index.vue 一致):决定弹窗展示哪个播放器图标 const ua = navigator.userAgent.toLowerCase(); const IS_WINDOWS = /windows|win32|win64|wow64/i.test(ua); const IS_MAC = /macintosh|mac os x|macintel|macppc/i.test(ua) && !/iphone|ipad|ipod/i.test(ua); const IS_IOS = /iphone|ipad|ipod/i.test(ua); const IS_ANDROID = /android/i.test(ua); layui.use(['layer'], async function () { var layer = layui.layer, $ = layui.$; var form = layui.form; if (location.href.startsWith('https://pan.baidu.com/s/')) { $('.x-button-box').prepend( '', ); } else { if ($('.tcuLAu').is('*')) { $('.tcuLAu').prepend( '', ); } else { $('.wp-s-agile-tool-bar__header.is-header-tool').prepend( '
', ); } } $('#downbtn_share').click(function () { swal({ title: '提示', text: '请先保存到自己的网盘后,从网盘里解析!', icon: 'warning', }); return false; }); $('#downbtn_main').click(async function () { let select = selectList(); let selected = Object.keys(select); if (selected.length == 0) { swal({ text: '请先选择一个文件', icon: 'warning', }); return false; } else if (selected.length > 1) { swal({ text: '目前仅支持单个文件解析', icon: 'warning', }); return false; } else if (select[selected[0]].isdir == 1) { swal({ text: '目前不支持文件夹解析', icon: 'warning', }); return false; } let fileName = select[selected[0]].server_filename; let index = fileName.lastIndexOf('.'); let fileType = [ 'wmv', 'rmvb', 'mpeg4', 'mpeg2', 'flv', 'avi', '3gp', 'mpga', 'qt', 'rm', 'wmz', 'wmd', 'wvx', 'wmx', 'wm', 'mpg', 'mp4', 'mkv', 'mpeg', 'mov', 'asf', 'm4v', 'm3u8', 'swf', ]; let name = fileName.substring(index + 1); name = name.toLowerCase(); if (!fileType.includes(name)) { swal({ text: '只支持播放视频格式文件!', icon: 'error', }); return false; } // 动态获取验证码:参照 index.vue 的 /quark/getDownType,每次打开弹窗拉取最新二维码 const codeInfo = await getCodeInfo(); config.downType = codeInfo.type; // 记录 getDownType 返回的 type,供 /wp/addVideo 使用 // 按平台渲染播放器图标(macOS/iOS→Infuse,Windows→PotPlayer,Android→MX Player) let playersHtml = ''; if (IS_IOS || IS_MAC) { playersHtml += '正在解析中请稍后...
'); const inputValue = document.getElementById('wpCode').value; config.code = inputValue; // 记录用户输入的验证码,供 /wp/addVideo 使用 if (inputValue) { share_one_baidu(openLayer); } else { layer.close(openLayer); swal({ text: '请输入验证码', icon: 'error', }); } }); }, }); }); }); // 生成设备指纹(与 index.vue src/utils/fingerprint.js 一致) function generateDeviceFingerprint() { const components = []; components.push(`screen:${screen.width}x${screen.height}`); components.push(`platform:${navigator.platform || 'unknown'}`); components.push(`tz:${Intl.DateTimeFormat().resolvedOptions().timeZone}`); const raw = components.join('|'); let hash = 0; for (let i = 0; i < raw.length; i++) { const chr = raw.charCodeAt(i); hash = (hash << 5) - hash + chr; hash |= 0; } return ( Math.abs(hash).toString(16).padStart(8, '0') + raw.length.toString(16).padStart(4, '0') ); } // 跨域 GET(优先 GM_xmlhttpRequest 绕过 CORS,兜底 fetch) function gmGet(url) { return new Promise((resolve, reject) => { if (typeof GM_xmlhttpRequest === 'function') { GM_xmlhttpRequest({ method: 'GET', url: url, timeout: 15000, onload: (res) => { try { resolve(JSON.parse(res.responseText)); } catch (e) { reject(e); } }, onerror: reject, ontimeout: reject, }); } else { fetch(url) .then((r) => r.json()) .then(resolve) .catch(reject); } }); } // 动态获取验证码二维码(参照 index.vue 的 /quark/getDownType) async function getCodeInfo() { try { const token = generateDeviceFingerprint(); const res = await gmGet( config.main_url + '/quark/getDownType?token=' + token, ); if (res.code === 200 && res.data) { return { url: res.data.qrCodeUrl || 'https://v.gssource.com/uc1.png', title: res.data.qrTitle || '扫码获取验证码', type: res.data.type, }; } } catch (e) {} // 接口异常时回退默认图,保证弹窗可用 return { url: 'https://v.gssource.com/uc1.png', title: '扫码获取验证码' }; } function selectName() { var select = {}; var option = []; try { option = require('system-core:context/context.js').instanceForSystem.list.getSelected(); } catch (e) { option = document.querySelector('.wp-s-core-pan').__vue__.selectedList; } option.forEach((element) => { select[element.server_filename] = element; }); return select; } function selectList() { var select = {}; var option = []; try { option = require('system-core:context/context.js').instanceForSystem.list.getSelected(); } catch (e) { option = document.querySelector('.wp-s-core-pan').__vue__.selectedList; } option.forEach((element) => { select[element.fs_id] = element; }); return select; } function share_one_baidu(openLayer) { let select = Object.keys(selectList()); let bdstoken = ''; let data_json = {}; try { data_json = $('html') .html() .match(/(?<=locals\.mset\()(.*?)(?=\);)/)[0]; data_json = JSON.parse(data_json); config.username = data_json.username; bdstoken = data_json.bdstoken; } catch (e) { data_json = $('html') .html() .match(/(?<=window\.locals\s=\s)(.*?)(?=;)/)[0]; data_json = JSON.parse(data_json); config.username = data_json.userInfo.username; bdstoken = data_json.userInfo.bdstoken; } config.data_json = data_json; const param = { bdstoken: bdstoken, period: 1, pwd: config.bd_password, eflag_disable: true, channel_list: '%5B%5D', schannel: 4, fid_list: JSON.stringify(select), }; $.ajax({ type: 'GET', url: 'https://pan.baidu.com/share/set', async: true, data: { bdstoken: bdstoken, period: 1, pwd: config.bd_password, eflag_disable: true, channel_list: '%5B%5D', schannel: 4, fid_list: JSON.stringify(select), }, dataType: 'json', success: function (res) { if (res.show_msg.indexOf('禁止') > -1) { swal({ text: '该文件禁止分享', icon: 'error', }); return false; } else { let shorturl = ''; try { shorturl = res.link.split('/').pop(); } catch (error) { swal({ text: '初始化准备失败', icon: 'error', }); return false; } get_down_list(shorturl, config.bd_password, openLayer, res.data); } }, error: function (res) { swal({ text: '初始化准备请求访问失败', icon: 'error', }); }, }); } async function get_down_list(shorturl, password, openLayer, pwd) { let ajax_data = { shorturl: shorturl, pwd: password, dir: 1, root: 1, userKey: 'main', }; fetch(config.main_url + '/wp/parseCopyLink', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(ajax_data), }) .then((resp) => resp.json()) .then((res) => { if (res.code == 200) { const requestData = { fsId: res.data.data.list[0].fs_id, shareid: res.data.data.shareid, uk: res.data.data.uk, sekey: res.data.data.seckey, randsk: res.data.data.seckey, fs_ids: [res.data.data.list[0].fs_id], path: res.data.data.list[0].server_filename, fileName: res.data.data.list[0].server_filename, size: res.data.data.list[0].size, surl: shorturl, url: `https://pan.baidu.com/s/${shorturl}`, userKey: 'main', pwd: password, dir: '/', token: generateDeviceFingerprint(), type: config.downType, code: config.code, }; GM_xmlhttpRequest({ method: 'POST', url: config.main_url + '/wp/addVideo', headers: { 'Content-Type': 'application/json', }, data: JSON.stringify(requestData), onload: function (response) { const responseData = JSON.parse(response.responseText); if (responseData.code !== 200) { layer.close(openLayer); swal({ text: responseData.msg, icon: 'warning', }); } else { $('#parse').html('解析
'); layer.alert('解析成功,请点击播放器按钮播放视频!', { title: '提示', }); let playPath = 'https://play.gssource.com/d/' + encodeURI('百度网盘/我的资源/' + responseData.data.fileName); // 按平台设置播放器唤起链接 if (document.getElementById('infuse')) { document.getElementById('infuse').href = 'infuse://x-callback-url/play?url=' + playPath; } if (document.getElementById('potplayer')) { document.getElementById('potplayer').href = 'potplayer://' + playPath; } if (document.getElementById('mxplayer')) { document.getElementById('mxplayer').href = 'intent:' + playPath + '#Intent;package=com.mxtech.videoplayer.ad;S.title=' + responseData.data.fileName + ';end'; } } }, onerror: function (response) { layer.close(openLayer); const errorMessage = JSON.parse(response.responseText).message || '网络错误'; swal({ text: '解析遇到问题了,请刷新重试即可!!', icon: 'warning', }); }, }); } else { layer.close(openLayer); $('#parse').html('解析
'); swal({ text: '解析遇到问题了,请升级插件刷新重试即可!', icon: 'warning', }); } }); } // Your code here... })();