// ==UserScript== // @name 哔哩哔哩视频页面常驻显示AV/BV号[已完全重构,支持显示分P标题] // @namespace ckylin-bilibili-display-video-id // @version 1.0 // @description 始终在哔哩哔哩视频页面标题下方显示当前视频号,默认显示AV号,右键切换为BV号,单击弹窗可复制链接 // @author CKylinMC // @match https://www.bilibili.com/video* // @grant unsafeWindow // @connect api.bilibili.com // @license GPLv3 License // @downloadURL none // ==/UserScript== (function(){ const wait = (t)=>{return new Promise(r=>setTimeout(r,t));} const log = (...m)=>console.log('[ShowAV]',...m); const getAPI = (bvid)=>fetch('https://api.bilibili.com/x/web-interface/view?bvid='+bvid).then(raw=>raw.json()); const infos = {}; async function getPageInfo(){ let i = 10 while(--i>=0 && !('playerInfo' in unsafeWindow)) await wait(100); return unsafeWindow.playerInfo } async function playerReady(){ let i=50; while(--i>=0){ await wait(100); if(!('player' in unsafeWindow)) continue; if(!('isInitialized' in unsafeWindow.player)) continue; if(!unsafeWindow.player.isInitialized()) continue; return true; } return false; } async function waitForDom(q){ let i=50; let dom; while(--i>=0){ if(dom = document.querySelector(q)) break; await wait(100); } return dom; } function getUrlParam(key){ return (new URL(location.href)).searchParams.get(key); } function getOrNew(id,parent){ let target = document.querySelector("#"+id); if(!target) { target = document.createElement("span"); target.id = id; target.style.marginLeft = "16px"; parent.appendChild(target); } return target; } async function tryInject(){ if(!(await playerReady())) return log('Can not load player in time.'); let pageInfo = await getPageInfo(); if(!pageInfo) return log('Can not load information in time.'); infos.aid = pageInfo.aid; infos.bvid = pageInfo.bvid; infos.cid = pageInfo.cid; infos.page = getUrlParam("p")||1; const av_root = await waitForDom(".video-data"); if (!av_root) return log('Can not load info-bar in time.'); const av_span = getOrNew("bilibiliShowAV",av_root); av_span.innerText = 'av'+infos.aid; av_span.oncontextmenu = e => { if(e.target.innerText.startsWith('av')) e.target.innerText = infos.bvid; else av_span.innerText = 'av'+infos.aid; e.preventDefault(); } av_span.onclick = e => prompt("当前视频地址:", "https://www.bilibili.com/video/"+e.target.innerText); const json = await getAPI(infos.bvid); if(!json || json.code!=0) return; let part = {part:'P'+infos.page} try{ part = json.data.pages[infos.page-1]; }catch(e){ part = json.data.pages[0]; } const pn_span = getOrNew("bilibiliShowPN",av_root); pn_span.innerText = `第 ${infos.page}/${json.data.videos} P 《${part.part}》`; } tryInject(); })()