// ==UserScript==
// @name 百度网盘在线视频播放器
// @namespace https://example.com/
// @version 3.00
// @description 百度网盘视频在线播放,支持倍速调节(0.25x-4x)、画质切换(360P-1080P),记忆播放进度,新标签页打开
// @match https://pan.baidu.com/s/*
// @grant unsafeWindow
// @run-at document-end
// @icon https://nd-static.bdstatic.com/m-static/wp-brand/favicon.ico
// @license MIT
// ==/UserScript==
(function() {
'use strict';
var PROGRESS_EXPIRY_DAYS = 7;
var EXPIRY_MS = PROGRESS_EXPIRY_DAYS * 24 * 3600 * 1000;
function isTouchDevice() {
return ('ontouchstart' in window) || (navigator.maxTouchPoints > 0);
}
function isTablet() {
return isTouchDevice() && window.innerWidth >= 600;
}
function formatDuration(seconds) {
if (!seconds || seconds <= 0) return '';
var s = Math.floor(seconds);
var h = Math.floor(s / 3600);
var m = Math.floor((s % 3600) / 60);
var sec = s % 60;
return h > 0 ? h + ':' + String(m).padStart(2, '0') + ':' + String(sec).padStart(2, '0') : m + ':' + String(sec).padStart(2, '0');
}
function getFileName(file) {
return file.server_filename || file.filename || file.name || file.title || '未知文件';
}
function getFolderName() {
var hash = location.hash;
var match = hash.match(/path=([^&]+)/);
if (match) {
var path = decodeURIComponent(match[1]);
var idx = path.indexOf('sharelink');
if (idx >= 0) {
var sub = path.substring(idx);
var parts = sub.split('/');
if (parts.length > 1) parts.shift();
return parts.join('/') || '根目录';
}
return path || '根目录';
}
return '根目录';
}
function getSurId() {
return (location.pathname.match(/\/s\/(\w+)/) || [])[1] || '';
}
function getCurrentList() {
try {
var ctx = unsafeWindow.require('system-core:context/context.js');
var list = ctx.instanceForSystem.list.getCurrentList();
if (list && list.length) {
sessionStorage.setItem(getSurId(), JSON.stringify(list));
return list;
}
} catch (e) {}
try {
if (unsafeWindow.__LIST__ && unsafeWindow.__LIST__.length) {
sessionStorage.setItem(getSurId(), JSON.stringify(unsafeWindow.__LIST__));
return unsafeWindow.__LIST__;
}
} catch (e) {}
var scripts = document.querySelectorAll('script');
for (var i = 0; i < scripts.length; i++) {
var text = scripts[i].textContent;
if (text && text.indexOf('"list":[') !== -1 && text.indexOf('"category"') !== -1) {
try {
var match = text.match(/"list":(\[.*?\]),/) || text.match(/"list":(\[.*?\])/);
if (match) {
var list = JSON.parse(match[1]);
if (list && list.length) {
sessionStorage.setItem(getSurId(), JSON.stringify(list));
return list;
}
}
} catch (e) {}
}
}
var cached = sessionStorage.getItem(getSurId());
if (cached) {
try { return JSON.parse(cached); } catch (e) {}
}
return [];
}
function filterVideos(list) {
if (!list || !list.length) return [];
return list.filter(function(i) {
if (i.hasOwnProperty('category')) return i.category === 1;
var name = getFileName(i).toLowerCase();
return /\.(mp4|mkv|webm|avi|mov|flv|wmv|ts|m3u8)$/i.test(name);
});
}
function getCachedVideoList(surId) {
var key = 'bd_video_cache_' + surId;
var cached = localStorage.getItem(key);
if (cached) {
try { return JSON.parse(cached); } catch (e) {}
}
return null;
}
function safeJsonStringify(obj) {
return JSON.stringify(obj).replace(/<\/script>/gi, '<\\/script>');
}
function cleanExpiredProgress() {
var now = Date.now();
var keysToRemove = [];
for (var i = 0; i < localStorage.length; i++) {
var key = localStorage.key(i);
if (key && (key.indexOf('bd_play_progress_') === 0 || key.indexOf('bd_last_path_') === 0)) {
try {
var data = JSON.parse(localStorage.getItem(key));
if (data && data.time) {
var age = now - data.time;
if (age > EXPIRY_MS) {
keysToRemove.push(key);
}
}
} catch (e) {}
}
}
keysToRemove.forEach(function(key) {
localStorage.removeItem(key);
});
}
// ============ 构建完整播放器页面 ============
function buildPlayerPage(videoList, shareInfo, folderName) {
if (!videoList || !videoList.length) {
var surId = getSurId();
var cachedList = getCachedVideoList(surId);
if (cachedList && cachedList.length) {
videoList = cachedList;
} else {
return '
百度网盘视频播放器';
}
}
var surId = getSurId();
var isTabletDevice = isTablet();
var enhancedVideos = [];
videoList.forEach(function(v, idx) {
var name = getFileName(v);
var fid = v.fs_id || v.fid || v.id || ('fid_' + idx);
if (name && fid) {
enhancedVideos.push({
id: idx,
name: name,
fid: fid,
duration: 0,
fullPath: surId + '|' + folderName + '/' + name
});
}
});
enhancedVideos.sort(function(a, b) {
return a.name.localeCompare(b.name, 'zh-CN', { numeric: true });
});
enhancedVideos.forEach(function(v, i) { v.id = i; });
var videoDataLiteral = safeJsonStringify(enhancedVideos);
var shareDataLiteral = safeJsonStringify(shareInfo);
var folderLiteral = safeJsonStringify(folderName);
var dirKey = surId + '|' + folderName;
var hlsCdn1 = 'https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.6.6/hls.min.js';
var hlsCdn2 = 'https://unpkg.com/hls.js@1.6.6/dist/hls.min.js';
var hlsCdn3 = 'https://cdn.jsdelivr.net/npm/hls.js@1.6.6/dist/hls.min.js';
// ========== 先构建 JS 代码 ==========
var jsCode = [];
jsCode.push('(function(){');
jsCode.push('var vd = ' + videoDataLiteral + ';');
jsCode.push('var sd = ' + shareDataLiteral + ';');
jsCode.push('var folder = ' + folderLiteral + ';');
jsCode.push('var dirKey = ' + safeJsonStringify(dirKey) + ';');
jsCode.push('var EXPIRY_MS = ' + EXPIRY_MS + ';');
jsCode.push('function $(id){return document.getElementById(id)}');
jsCode.push('var ve=$("video"),ov=$("ovl"),ib=$("info-text"),pb=$("pbar"),pf=$("pfill"),tl=$("tlabel"),vl=$("vlist"),sx=$("search"),spd=$("speed-select"),qsel=$("quality-select"),vsl=$("vol-slider"),pa=$("p-area"),ovt=$("ovl-text"),cpb=$("copy-btn"),toast=$("toast");');
jsCode.push('var sb=$("sidebar"),rs=$("resizer"),foldBtn=$("fold-sidebar-btn"),unfoldBtn=$("unfold-sidebar"),toggleSidebarBtn=$("toggle-sidebar-btn"),pipBtn=$("pip-btn"),fullscreenBtn=$("fullscreen-btn"),mainEl=$("main");');
jsCode.push('var volIcon=$("vol-icon");');
jsCode.push('var ci=-1,cq=1080,hs=null,drg=false,curUrl="",curSpeed=1,sideVisible=true,saveTimer=null,endedFlag=false,_lastTimeUpdate=-1;');
jsCode.push('var fullscreenHideTimer=null,isFullscreen=false,controlsVisible=true;');
jsCode.push('function fmtDur(s){if(!s||s<=0)return"";s=Math.floor(s);var h=Math.floor(s/3600),m=Math.floor((s%3600)/60),sec=s%60;return h>0?h+":"+String(m).padStart(2,"0")+":"+String(sec).padStart(2,"0"):m+":"+String(sec).padStart(2,"0")}');
jsCode.push('function ft(t){if(isNaN(t)||t===Infinity||t<0)return"0:00";var h=Math.floor(t/3600),m=Math.floor((t%3600)/60),s=Math.floor(t%60);return h>0?h+":"+String(m).padStart(2,"0")+":"+String(s).padStart(2,"0"):m+":"+String(s).padStart(2,"0")}');
jsCode.push('function saveProgress(){if(ve.ended||endedFlag)return;if(ci>=0&&vd[ci]&&vd[ci].fid&&ve.currentTime>0){var data={time:Date.now(),progress:ve.currentTime};localStorage.setItem("bd_play_progress_"+vd[ci].fid,JSON.stringify(data))}}');
jsCode.push('function getProgress(fid){var key="bd_play_progress_"+fid,st=localStorage.getItem(key);if(!st)return 0;try{var d=JSON.parse(st);if(d&&d.time&&d.progress){if(Date.now()-d.time>EXPIRY_MS){localStorage.removeItem(key);return 0}return d.progress}}catch(e){}return 0}');
jsCode.push('function saveLastVideoPath(v){if(!v||!v.fullPath)return;localStorage.setItem("bd_last_path_"+dirKey,JSON.stringify({time:Date.now(),fullPath:v.fullPath}))}');
jsCode.push('function getLastVideoIndex(){var st=localStorage.getItem("bd_last_path_"+dirKey);if(!st)return-1;try{var d=JSON.parse(st);if(d&&d.time&&d.fullPath&&Date.now()-d.time<=EXPIRY_MS){for(var i=0;i=0&&vd[ci]&&vd[ci].fid)localStorage.removeItem("bd_play_progress_"+vd[ci].fid)}');
jsCode.push('function resetEnded(){endedFlag=false;ve.dataset.endedProcessed="false";ov.style.display="none";ovt.textContent=""}');
jsCode.push('function checkEnded(){if(endedFlag)return;var d=ve.duration;if(d&&isFinite(d)&&d>0&&!ve.paused&&ve.currentTime>=d-0.2)handleEnded()}');
jsCode.push('function userSeek(t){if(endedFlag)resetEnded();ve.currentTime=t;pf.style.width=(t/ve.duration*100)+"%";if(!drg)tl.textContent=ft(t)+" / "+ft(ve.duration);if(ve.paused&&t暂无视频\';return}');
jsCode.push('var hasFilter = filter && filter.trim().length > 0;');
jsCode.push('var filtered = vd;');
jsCode.push('if(hasFilter){');
jsCode.push('filtered = vd.filter(function(v){return v.name.toLowerCase().indexOf(filter.toLowerCase())>=0});');
jsCode.push('}');
jsCode.push('if(filtered.length===0){vl.innerHTML=\'未找到匹配的视频
\';return}');
jsCode.push('filtered.forEach(function(v,i){');
jsCode.push('var d=document.createElement("div");d.className="v-item"+(v.id===ci?" cur":"");');
jsCode.push('var durStr=fmtDur(v.duration);');
jsCode.push('d.innerHTML=\'\'+(i+1)+\'.\'+v.name+\'\'+durStr+\'\';');
jsCode.push('d.dataset.idx=v.id;');
jsCode.push('d.addEventListener("click",function(e){e.stopPropagation();loadVideo(v.id,false);});');
jsCode.push('vl.appendChild(d);');
jsCode.push('});');
jsCode.push('}');
jsCode.push('function updateDuration(idx){');
jsCode.push('if(idx<0||idx>=vd.length)return;');
jsCode.push('if(vd[idx].duration>0)return;');
jsCode.push('if(ve.duration&&isFinite(ve.duration)&&ve.duration>0){');
jsCode.push('vd[idx].duration=ve.duration;');
jsCode.push('var items=vl.querySelectorAll(".v-item");');
jsCode.push('for(var i=0;i=vd.length)return;');
jsCode.push('if(!ve.ended&&!endedFlag&&ci>=0&&vd[ci]&&vd[ci].fid&&ve.currentTime>0){');
jsCode.push('localStorage.setItem("bd_play_progress_"+vd[ci].fid,JSON.stringify({time:Date.now(),progress:ve.currentTime}));');
jsCode.push('}');
jsCode.push('ci=idx;var v=vd[idx];');
jsCode.push('document.getElementById("folder-title").textContent="📁 "+folder;');
jsCode.push('ib.textContent=v.name;document.title=v.name+" - 百度网盘视频播放器";');
jsCode.push('saveLastVideoPath(v);');
jsCode.push('resetEnded();');
jsCode.push('ov.style.display="flex";ovt.textContent="加载中...";');
jsCode.push('ve.pause();ve.removeAttribute("src");ve.load();');
jsCode.push('if(hs){hs.destroy();hs=null}');
jsCode.push('var url=bu(v.fid,cq);curUrl=url;');
jsCode.push('var saved=getProgress(v.fid);');
jsCode.push('var target=0;');
jsCode.push('if(keepTime===true&&ve.currentTime>1)target=ve.currentTime;');
jsCode.push('else if(saved>1)target=saved;');
jsCode.push('function handleTarget(dur){if(dur>0&&target>=dur-0.5)target=0;if(target>0)ve.currentTime=target}');
jsCode.push('if(window.Hls&&Hls.isSupported()){');
jsCode.push('hs=new Hls({enableWorker:false,maxBufferLength:15,maxMaxBufferLength:30,lowLatencyMode:false,startFragPrefetch:true,fragLoadingMaxRetry:3});');
jsCode.push('hs.loadSource(url);hs.attachMedia(ve);');
jsCode.push('hs.on(Hls.Events.MANIFEST_PARSED,function(){');
jsCode.push('handleTarget(ve.duration);');
jsCode.push('ve.playbackRate=curSpeed;spd.value=curSpeed.toString();');
jsCode.push('ve.play().then(function(){ov.style.display="none";}).catch(function(){ovt.textContent="点击播放";ov.style.display="flex";});');
jsCode.push('ve.addEventListener("loadedmetadata",function(){updateDuration(ci);},{once:true});');
jsCode.push('if(ve.duration&&isFinite(ve.duration))updateDuration(ci);');
jsCode.push('});');
jsCode.push('hs.on(Hls.Events.ERROR,function(e,d){if(d.fatal)hs.startLoad()});');
jsCode.push('}else if(ve.canPlayType("application/vnd.apple.mpegurl")){');
jsCode.push('ve.src=url;');
jsCode.push('ve.addEventListener("loadedmetadata",function(){');
jsCode.push('handleTarget(ve.duration);');
jsCode.push('ve.playbackRate=curSpeed;spd.value=curSpeed.toString();');
jsCode.push('updateDuration(ci);');
jsCode.push('ve.play().then(function(){ov.style.display="none";}).catch(function(){ovt.textContent="点击播放";ov.style.display="flex";});');
jsCode.push('},{once:true});');
jsCode.push('}else{');
jsCode.push('ovt.textContent="当前浏览器不支持播放";ov.style.display="flex";');
jsCode.push('}');
jsCode.push('renderList(sx.value);');
jsCode.push('var prevBtn=$("bprev"),nextBtn=$("bnext");');
jsCode.push('if(prevBtn)prevBtn.style.opacity=idx===0?"0.3":"1";');
jsCode.push('if(nextBtn)nextBtn.style.opacity=idx===vd.length-1?"0.3":"1";');
jsCode.push('setTimeout(function(){');
jsCode.push('var items=vl.querySelectorAll(".v-item");');
jsCode.push('for(var i=0;i0&&!ve.ended&&!endedFlag)saveProgress()},5000);');
jsCode.push('window.addEventListener("beforeunload",function(){if(ci>=0&&vd[ci]&&vd[ci].fid&&ve.currentTime>0&&!ve.ended&&!endedFlag){localStorage.setItem("bd_play_progress_"+vd[ci].fid,JSON.stringify({time:Date.now(),progress:ve.currentTime}))}});');
jsCode.push('updateVolumeIcon();');
jsCode.push('initFullscreenAutoHide();');
jsCode.push('}');
jsCode.push('ve.addEventListener("timeupdate",function(){');
jsCode.push('if(ve.duration&&isFinite(ve.duration)){');
jsCode.push('var ct=ve.currentTime;');
jsCode.push('if(ct===_lastTimeUpdate)return;');
jsCode.push('_lastTimeUpdate=ct;');
jsCode.push('pf.style.width=(ct/ve.duration*100)+"%";');
jsCode.push('if(!drg)tl.textContent=ft(ct)+" / "+ft(ve.duration);');
jsCode.push('checkEnded();');
jsCode.push('}');
jsCode.push('});');
jsCode.push('ve.addEventListener("play",function(){resetEnded();});');
jsCode.push('spd.addEventListener("change",function(){curSpeed=parseFloat(spd.value);ve.playbackRate=curSpeed});');
jsCode.push('qsel.addEventListener("change",function(){var q=parseInt(qsel.value);if(q===cq)return;cq=q;if(ci>=0)loadVideo(ci,true)});');
jsCode.push('vsl.addEventListener("input",function(){ve.volume=vsl.value/100;if(ve.volume>0)ve.muted=false;updateVolumeIcon();});');
jsCode.push('volIcon.addEventListener("click",function(e){e.stopPropagation();toggleMute();});');
jsCode.push('document.getElementById("vol-row").addEventListener("click",function(e){if(e.target!==volIcon&&e.target!==vsl){toggleMute();}});');
jsCode.push('cpb.addEventListener("click",function(e){e.stopPropagation();if(curUrl)navigator.clipboard.writeText(curUrl).then(function(){showToast("✅ 已复制")}).catch(function(){showToast("❌ 复制失败")})});');
jsCode.push('function showToast(msg){toast.textContent=msg;toast.style.opacity="1";clearTimeout(toast._t);toast._t=setTimeout(function(){toast.style.opacity="0"},2000)}');
jsCode.push('sx.addEventListener("input",function(){renderList(sx.value)});');
jsCode.push('ov.addEventListener("click",function(e){e.stopPropagation();if(endedFlag||ve.ended){ve.currentTime=0;resetEnded()}ve.play().then(function(){ov.style.display="none";}).catch(function(){})});');
jsCode.push('pa.addEventListener("click",function(e){if(e.target===pa||e.target===ve){if(endedFlag||ve.ended){ve.currentTime=0;resetEnded()}ve.paused?ve.play().catch(function(){}):ve.pause()}});');
jsCode.push('ve.addEventListener("pause",function(){if(!ve.ended&&!endedFlag){ov.style.display="flex";ovt.textContent=""}});');
jsCode.push('ve.addEventListener("ended",function(){ov.style.display="flex";if(ci=ve.duration-0.2){handleEnded();return}userSeek(nt);break;');
jsCode.push('case"arrowup":e.preventDefault();ve.volume=Math.min(1,ve.volume+0.1);vsl.value=ve.volume*100;updateVolumeIcon();break;');
jsCode.push('case"arrowdown":e.preventDefault();ve.volume=Math.max(0,ve.volume-0.1);vsl.value=ve.volume*100;updateVolumeIcon();break;');
jsCode.push('case"f":e.preventDefault();toggleFullscreen();break;');
jsCode.push('case"n":e.preventDefault();loadVideo(ci+1,false);break;');
jsCode.push('case"p":e.preventDefault();loadVideo(ci-1,false);break;');
jsCode.push('case"m":e.preventDefault();toggleMute();break;');
jsCode.push('}');
jsCode.push('});');
jsCode.push('initPlayer();');
jsCode.push('})();');
var jsString = jsCode.join('\n');
// ========== 构建 CSS 样式 ==========
var cssParts = [];
cssParts.push('*{margin:0;padding:0;box-sizing:border-box}html,body{width:100%;height:100%;overflow:hidden}');
cssParts.push('body{background:#0a0a0a;color:#ccc;font-family:"Microsoft YaHei",Arial,sans-serif;display:flex;height:100vh;overflow:hidden}');
cssParts.push('#resizer{width:4px;cursor:col-resize;background:#2a2a2a;flex-shrink:0}#resizer:hover{background:#1890ff}');
cssParts.push('#sidebar{width:380px;min-width:280px;max-width:600px;background:#151515;display:flex;flex-direction:column;border-right:1px solid #2a2a2a;flex-shrink:0}');
cssParts.push('#side-hd{padding:14px;background:#0d0d0d;border-bottom:1px solid #2a2a2a;flex-shrink:0;display:flex;align-items:center;gap:8px}');
cssParts.push('#side-hd h2{font-size:15px;color:#fff;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}');
cssParts.push('#fold-sidebar-btn{background:transparent;border:none;color:#888;font-size:16px;cursor:pointer;padding:2px 4px}#fold-sidebar-btn:hover{color:#1890ff}');
cssParts.push('#search{width:100%;padding:8px 12px;margin-top:10px;background:#1a1a1a;border:1px solid #333;border-radius:4px;color:#eee;font-size:12px;outline:none}#search:focus{border-color:#1890ff}');
cssParts.push('#vlist{flex:1;overflow-y:auto;overflow-x:hidden;padding:4px 0}');
cssParts.push('.v-item{padding:8px 14px;cursor:pointer;font-size:12px;border-bottom:1px solid #1a1a1a;display:flex;align-items:center;gap:8px;color:#aaa;transition:all 0.15s;-webkit-tap-highlight-color:transparent;user-select:none}');
cssParts.push('.v-item:hover{background:#1e1e1e;color:#fff}');
cssParts.push('.v-item.cur{background:#0d2b45;color:#1890ff;border-left:3px solid #1890ff;padding-left:11px}');
cssParts.push('.v-item .num{color:#555;min-width:30px;font-size:10px;flex-shrink:0}');
cssParts.push('.v-item .name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}');
cssParts.push('.v-item .duration{color:#555;font-size:10px;flex-shrink:0;min-width:40px;text-align:right}');
cssParts.push('#main{flex:1;display:flex;flex-direction:column;background:#000;min-width:0}');
cssParts.push('#info-bar{width:100%;height:40px;background:#141414;border-bottom:1px solid #2a2a2a;display:flex;align-items:center;padding:0 12px;flex-shrink:0;z-index:10}');
cssParts.push('#info-text{flex:1;color:#fff;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}');
cssParts.push('#copy-btn{padding:4px 8px;border-radius:4px;border:1px solid #444;background:#1e1e1e;color:#ccc;cursor:pointer;font-size:11px;flex-shrink:0}#copy-btn:hover{background:#2a2a2a;border-color:#1890ff;color:#fff}');
cssParts.push('#p-area{flex:1;position:relative;display:flex;align-items:center;justify-content:center;background:#000;min-height:200px;cursor:pointer}');
cssParts.push('video{width:100%;height:100%;object-fit:contain}');
cssParts.push('#ovl{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,0.3);cursor:pointer;z-index:10}');
cssParts.push('#ovl .pb{width:80px;height:80px;background:rgba(24,144,255,0.85);border-radius:50%;display:flex;align-items:center;justify-content:center;margin:0 auto}#ovl .pb:hover{transform:scale(1.08)}');
cssParts.push('#ovl .pb span{color:#fff;font-size:36px;margin-left:4px}#ovl p{color:#bbb;margin-top:10px;font-size:14px}');
cssParts.push('#ctrls{display:flex;align-items:center;gap:6px;padding:6px 12px;background:#141414;border-top:1px solid #222;flex-shrink:0;flex-wrap:wrap}');
cssParts.push('#ctrls button{padding:5px 10px;border-radius:4px;border:1px solid #444;background:#1e1e1e;color:#ccc;cursor:pointer;font-size:11px;white-space:nowrap}#ctrls button:hover{background:#2a2a2a;border-color:#1890ff;color:#fff}#ctrls button.on{background:#1890ff;border-color:#1890ff;color:#fff}');
cssParts.push('#ctrls select{padding:4px 8px;border-radius:4px;border:1px solid #444;background:#1e1e1e;color:#ccc;font-size:11px;cursor:pointer;outline:none}#ctrls select:hover{border-color:#1890ff}');
cssParts.push('#ctrls .spacer{flex:1}');
cssParts.push('#speed-select{padding:4px 6px;border-radius:4px;border:1px solid #444;background:#1e1e1e;color:#ccc;font-size:11px;cursor:pointer;outline:none}#speed-select:hover{border-color:#1890ff}');
cssParts.push('#quality-select{padding:4px 6px;border-radius:4px;border:1px solid #444;background:#1e1e1e;color:#ccc;font-size:11px;cursor:pointer;outline:none}#quality-select:hover{border-color:#1890ff}');
cssParts.push('#pwrap{display:flex;align-items:center;gap:10px;padding:4px 12px;background:#141414;flex-shrink:0}');
cssParts.push('#pbar{flex:1;height:5px;background:#2a2a2a;border-radius:3px;cursor:pointer;position:relative;min-height:18px}');
cssParts.push('#pfill{height:100%;background:#1890ff;border-radius:3px;width:0;pointer-events:none}');
cssParts.push('#tlabel{color:#777;font-size:11px;min-width:95px;text-align:center;flex-shrink:0}');
cssParts.push('#vol-row{display:flex;align-items:center;gap:4px;cursor:pointer;padding:2px 4px;border-radius:4px;}');
cssParts.push('#vol-row:hover{background:#2a2a2a;}');
cssParts.push('#vol-icon{cursor:pointer;font-size:14px;user-select:none;}');
cssParts.push('#vol-slider{width:60px;height:3px;background:#2a2a2a;border-radius:2px;cursor:pointer;outline:none;-webkit-appearance:none;appearance:none}');
cssParts.push('#vol-slider::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;background:#1890ff;border-radius:50%;cursor:pointer}');
cssParts.push('#unfold-sidebar{display:none;position:fixed;left:0;top:50%;transform:translateY(-50%);background:#1890ff;color:#fff;border:none;padding:8px 4px;border-radius:0 4px 4px 0;cursor:pointer;z-index:1000;font-size:12px}#unfold-sidebar:hover{background:#40a9ff}');
cssParts.push('#toast{position:fixed;top:20px;left:50%;transform:translateX(-50%);background:#1890ff;color:#fff;padding:8px 16px;border-radius:6px;font-size:13px;z-index:99999;pointer-events:none;opacity:0;transition:opacity 0.3s}');
// 全屏样式 - 控制栏自动隐藏
cssParts.push('#main:fullscreen #info-bar { display: flex !important; transition: opacity 0.3s ease; }');
cssParts.push('#main:fullscreen #pwrap { display: flex !important; transition: opacity 0.3s ease; }');
cssParts.push('#main:fullscreen #ctrls { display: flex !important; transition: opacity 0.3s ease; }');
cssParts.push('#main:fullscreen #sidebar { display: none !important; }');
cssParts.push('#main:fullscreen #resizer { display: none !important; }');
cssParts.push('#main:fullscreen .fullscreen-hidden { opacity: 0 !important; pointer-events: none !important; }');
cssParts.push('#main:fullscreen .fullscreen-visible { opacity: 1 !important; pointer-events: auto !important; }');
cssParts.push('#main:fullscreen.hide-cursor * { cursor: none !important; }');
cssParts.push('#main:-webkit-full-screen #info-bar { display: flex !important; transition: opacity 0.3s ease; }');
cssParts.push('#main:-webkit-full-screen #pwrap { display: flex !important; transition: opacity 0.3s ease; }');
cssParts.push('#main:-webkit-full-screen #ctrls { display: flex !important; transition: opacity 0.3s ease; }');
cssParts.push('#main:-webkit-full-screen #sidebar { display: none !important; }');
cssParts.push('#main:-webkit-full-screen #resizer { display: none !important; }');
cssParts.push('#main:-webkit-full-screen .fullscreen-hidden { opacity: 0 !important; pointer-events: none !important; }');
cssParts.push('#main:-webkit-full-screen .fullscreen-visible { opacity: 1 !important; pointer-events: auto !important; }');
cssParts.push('#main:-webkit-full-screen.hide-cursor * { cursor: none !important; }');
cssParts.push('#main:fullscreen #info-bar { background: rgba(20,20,20,0.85) !important; }');
cssParts.push('#main:fullscreen #pwrap { background: rgba(20,20,20,0.85) !important; }');
cssParts.push('#main:fullscreen #ctrls { background: rgba(20,20,20,0.85) !important; border-top-color: rgba(255,255,255,0.1) !important; }');
cssParts.push('#main:-webkit-full-screen #info-bar { background: rgba(20,20,20,0.85) !important; }');
cssParts.push('#main:-webkit-full-screen #pwrap { background: rgba(20,20,20,0.85) !important; }');
cssParts.push('#main:-webkit-full-screen #ctrls { background: rgba(20,20,20,0.85) !important; border-top-color: rgba(255,255,255,0.1) !important; }');
// 平板/手机适配
if (isTabletDevice) {
cssParts.push('#sidebar { width: 340px !important; min-width: 280px !important; max-width: 500px !important; }');
cssParts.push('#ctrls { padding: 12px 16px !important; gap: 12px !important; flex-wrap: wrap !important; }');
cssParts.push('#ctrls button { padding: 12px 20px !important; font-size: 16px !important; min-height: 52px !important; min-width: 52px !important; }');
cssParts.push('#ctrls select { padding: 12px 16px !important; font-size: 16px !important; min-height: 52px !important; }');
cssParts.push('#speed-select, #quality-select { padding: 12px 16px !important; font-size: 16px !important; min-height: 52px !important; }');
cssParts.push('#vol-slider { width: 100px !important; height: 6px !important; }');
cssParts.push('#vol-slider::-webkit-slider-thumb { width: 24px !important; height: 24px !important; }');
cssParts.push('#pbar { height: 8px !important; min-height: 28px !important; }');
cssParts.push('#pwrap { padding: 10px 20px !important; }');
cssParts.push('#tlabel { font-size: 16px !important; min-width: 130px !important; }');
cssParts.push('.v-item { padding: 16px 20px !important; font-size: 17px !important; min-height: 58px !important; }');
cssParts.push('#search { padding: 14px 18px !important; font-size: 17px !important; min-height: 54px !important; }');
cssParts.push('#side-hd { padding: 18px !important; }');
cssParts.push('#side-hd h2 { font-size: 19px !important; }');
cssParts.push('#info-text { font-size: 17px !important; }');
cssParts.push('#copy-btn { padding: 10px 18px !important; font-size: 15px !important; min-height: 46px !important; }');
cssParts.push('#fold-sidebar-btn { font-size: 24px !important; padding: 8px 14px !important; }');
cssParts.push('.v-item .num { min-width: 44px !important; font-size: 15px !important; }');
cssParts.push('.v-item .duration { min-width: 60px !important; font-size: 15px !important; }');
cssParts.push('#ovl .pb { width: 110px !important; height: 110px !important; }');
cssParts.push('#ovl .pb span { font-size: 52px !important; }');
cssParts.push('#info-bar { height: 56px !important; padding: 0 18px !important; }');
cssParts.push('#resizer { width: 6px !important; }');
}
if (window.innerWidth < 600 && !isTabletDevice) {
cssParts.push('#sidebar { width: 260px !important; min-width: 200px !important; }');
cssParts.push('#ctrls { gap: 4px !important; padding: 6px 8px !important; flex-wrap: wrap !important; }');
cssParts.push('#ctrls button { padding: 6px 10px !important; font-size: 11px !important; min-height: 38px !important; }');
cssParts.push('#ctrls select { padding: 4px 8px !important; font-size: 11px !important; min-height: 34px !important; }');
cssParts.push('#vol-slider { width: 50px !important; }');
cssParts.push('#pbar { height: 5px !important; min-height: 20px !important; }');
cssParts.push('#pwrap { padding: 4px 10px !important; }');
cssParts.push('#tlabel { font-size: 11px !important; min-width: 85px !important; }');
cssParts.push('.v-item { padding: 8px 12px !important; font-size: 12px !important; min-height: 42px !important; }');
cssParts.push('#search { padding: 8px 12px !important; font-size: 13px !important; min-height: 40px !important; }');
cssParts.push('#side-hd { padding: 10px !important; }');
cssParts.push('#info-bar { height: 38px !important; padding: 0 8px !important; }');
cssParts.push('#ovl .pb { width: 65px !important; height: 65px !important; }');
cssParts.push('#ovl .pb span { font-size: 30px !important; }');
}
var cssString = cssParts.join('');
// ========== 构建 HTML 主体 ==========
var htmlParts = [];
htmlParts.push('百度网盘视频播放器');
htmlParts.push('