// ==UserScript== // @name BilibiliCover - 获取并显示B站视频封面 // @version 3.5.0 // @description 获取并显示B站视频封面 // @author AnnAngela // @namespace https://greasyfork.org/users/129402 // @mainpage https://greasyfork.org/zh-CN/scripts/33411-bilibilicover // @supportURL https://greasyfork.org/zh-CN/scripts/33411-bilibilicover/feedback // @license GNU General Public License v3.0 or later // @compatible chrome 80 // @compatible firefox // @compatible opera // @compatible safari // @match *://www.bilibili.com/video/av* // @match *://www.bilibili.com/video/bv* // @match *://www.bilibili.com/video/BV* // @match *://www.bilibili.com/bangumi/play/* // @match *://live.bilibili.com/* // @run-at document-start // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_xmlhttpRequest // @noframes // @icon data:image/png;base64,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 // @icon64 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAC4jAAAuIwF4pT92AAAIVklEQVR4Xu2bWYwVRRSGzyzIBYwbAmpwFzPigqCi0ZgoJooa3GKMGBg3VMAIcY3xQREFNW5xfXAF1AiKPrhEURl3E6O4srggojCCIIIgIuIM/t+cauZ6p293j3jDZZiHL5lkpk7956/q6upTNdbY2GgNDQ1bLHbjZ0tszKc/Z6FC7CmOF0PEKHGxOEv0F9uL6gxxNpbq0Ff/0PclYrQYOsa1obEiQ5wmrGrSbKuaOCsLlWKAuFNME3PFR2KquEzsJXKiIkOs/0pF6GOv0Cd9zxDzxGtVrg2NlRliNWE2cbbZhFlpdBX7i9FiuvhW/CrqxUwxWVwpjhPdRHWGmK2lOsQ+LvQ1JfT9k1gu5oo3zDWitWuGmJkN2FecKR4Vv4h1okH8HX5eKD4QY0SNyImKDHGzUhFi1oQ+6Ks+9I2GhvDzUnONaN03Q9zMBtDx2WKCuduNBawUC8SL4mr7f2dC/sgT+4XQ10prqYNZOdFca02G2K0yYHAIHmdANBMYlffFjaK3bfxMiEa+d4hJ7IXWPAPjDJgkzhH7ZYif2YAe4lBxg/gydPRXjABG5UfzmXCVGCC6m49ia42oDm0HhFgvhthxI48WNKENjWjdKUMfmQ1ATGfzqfWy+E6ssZZCmAmIYZTeNR+1g0QnUZmhn4ho5A8MMYi1IMT+O6ZftKAJbWhEa7bHL6MBCCKBfmKk+aPwlRWfCavMR+sla54JzKK0mcDvqsLfHmvZRx4tTP1LzTVWpvTTagMiuoidxXnmbvPqSZsJ74ixoo+lzwR+lwt/Oza0TRr5P8w1oOV8c21bJ8TPZAAiWHVZeI4Wp5ovgBeIEebv2YfFZ2KxWGsthRXOhNfFeDHKfAaNKMLI8DfjQ5tiIx9B32hAyyPm2oiDVjSjnRzIhZxaml9gANOGacoI1JoLeU68J+aI+eYbD6Yd7jMycatx/kxAJEYsCW2hvgjR75eENmstfuQj6BsNaIk2ZmhEK5rRTg7kQk4tH8FgQAfzhYNF5wxxnfkzVWf+fC0Sv5sLSkp4UxMZjlY0o73OPBdyIjdyJFdy3mAAzzYLz4XmGw2mFKPA9FtjzSPRYOVtQKQvMgLt5MAOkZzIjRzJlZybDOC5YHoMNX+O2Ocvs+Spt7lBLuTEgkmO5HqwsSbIAKbCEPNX1myx2tKf7c2N/LWCHHlrYEIHDODL6SZzd1hI2tLIF4IR5Mim6Wbjq1EG1Jp/WrJwtLWRLySaCcxych6KAXeYvzLWxTRgAeG1NMN8AXlGPFXmoBGtH5trj9tHMMvZXt+OAa/qh28sfuqzEcGcW8UJ4hDzr6yaMgVtaETrLeba2UnGGfC1eAUD2DTwyoub+u+bJ3+a+dcVW9lse+xNA9rQiFZ2gWineBL3KPxsLIgyYIX56hhnwJPiGLG76Git+6LbVKARrWg+xjyHOANYB37FABaFYgWG+0OgThk6LjfQjHZyKMwLyHktBkS7pzgD7hY72uYx8oWgGe3kEGeA7xhlwPoifwB3iu0ydFauoJ0ciuXX2G7ARhrAYrOD2EccZV7FAaoyPcU25hWeNKHFqAoxeoaYUXz66hX67pjQvuQGUGToK4aZl8leCNwmBpnX5jsntE+jc4gxKMSM4tPXRaHvbgntS24A3xEk/5j5ZmppgF0WG5FTLFlgGrQdFGK9mxefvh4Pfe+f0L7kBgwUT5sfUXFe8GegXnxo/pG1d0L7NGg7NsRamBd/eeiTvgcmtC+5AdTd+E5gv53/LYHI6JTmgIT2adB2QoiVX3xdF/qk78EJ7UtuQK152amwaotATOCL66CE9mnQdnKIlW9wVPGh79qE9iU3gFL0vIT2z5tXXtISLQZtn0uIT9/nJ7RvN8BKbECt+WdlYSElmqJ8m/dJaJ8Gj8CUECv/EYgKG/Rdm9C+5AawAH1iXsMvXARZqVkED0xon0bSIrgq9H1OQvuSG3CSeNZ8MfrNml9T1OQRx6FEr4T2afQKMVjtqe6sDfFXhD6nipMT2pfcAEZ3uHjCvJzO7RE2KhRSKLVxENEjoX0aHI+fHmIRc5k1b4Q47OAYLOktU3IDEEgJijM9NiXTjDLThFl3mVeRKFN1SWifRpcQAxP4rH1NUMKj9jc89N09oX3JDciZf3NTi+MjhV0Z9bjDzYsR21rWc/p4qkOMPcQRIf7A0FdN6DuX0L7kBpQ77QZYuwHtBrQbYO0GJBvAD8XK4rzPqbuV82lQMdCMdnKIS35DWTz/vm3hH90ndrPkd225guZdzXOIM8DvC8gAPirYX8cZQN2NTQ3Xz9Lu+JULaOxgfj7Y37xeGTf6HI0tw4ComBlnwNvmV09PNN9y5qy8TYgOR/n+QPP15jnEGcCB8BwMqDO/MRF3PD5fvBkCsRWl/r+LubvlCNr4gjzSfODQTg6FeZErN2KmY8C95kfIcRck+Oz8wbwkzSnrQ+JB8UCZgjYucaKVuwFoJ4c4A8j5HgzggIHS1Rorvhi2FaIrdH+a5zwMA/ik5NSFqbLc2v4lqWhWk3M/DNjK/PLgW+ZrAe60tZkQjTwVpXnmCyOnSk3X5DiAPMy8ukJl53trezOBXBh5ZjnrA7nyimy6KMnrgyvmrKJUdurMy1vR3eD8jVKxHWO5kK8RzX4LxHNh1eetwP8UkKtfq7fmy9KUn/hXk1rzQiQFR1ZKZgT7hCy3wzc1Ubl8tbnmeeY5kAs5nWs+28mVnM1yT8yx3KTZERWiWhwqLhL3ijoxSywWK8TvYnWZgjY0LhIzxfSc50Au5ERu5LghZxv3xVIb9/mSfCrFzqKvOEEMFcPFFeIacW2Zg8bLx7lmtJMDuZATuf0rX1u/fr3xD9RbKu0GYMCWzD+zDS/KNPfarwAAAABJRU5ErkJggg== // @downloadURL none // ==/UserScript== "use strict"; unsafeWindow.addEventListener("load", () => { const LF = String.fromCharCode(10), XX = String.fromCharCode(47); let response; function getConfig() { return GM_getValue("style", "image") === "button" ? "button" : "image"; } GM_setValue("style", getConfig()); const helper = { Uri: class Uri { constructor(href = location.href) { this._url = new URL(href); this.query = Object.fromEntries(Array.from(this._url.searchParams.entries())); this.protocol = this._url.protocol.replace(/:$/, ""); this.user = this._url.username; this.password = this._url.password; this.host = this._url.hostname; this.port = this._url.port; this.path = this._url.pathname; this.fragment = this._url.hash.length > 0 ? `#${decodeURIComponent(this._url.hash).substring(1)}` : ""; } _updateUrl() { this._url.protocol = `${(this.protocol || "").replace(/:$/, "")}:`; this._url.username = this.user; this._url.password = this.password; this._url.hostname = this.host; this._url.port = this.port; this._url.pathname = this.path; this._url.hash = `#${encodeURIComponent(this.fragment.replace(/^#/, ""))}`.replace(/^#$/, ""); } getUserInfo() { this._updateUrl(); return this.user.length > 0 ? `${this.user}:${this.password}` : ""; } getHostPort() { this._updateUrl(); return this._url.host; } getAuthority() { this._updateUrl(); const userInfo = this.getUserInfo(); const hostPort = this.getHostPort(); return userInfo.length > 0 ? `${userInfo}@${hostPort}` : hostPort; } getQueryString() { this._updateUrl(); return this._url.search.substring(1); } getRelativePath() { this._updateUrl(); return this.path + this._url.search + this.fragment; } toString() { this._updateUrl(); return this._url.href; } }, coverImage: function coverImage(url) { /* 本函数来自 https://greasyfork.org/zh-CN/scripts/30714-获取哔哩哔哩视频的封面图片-get-bilibili-cover-image/code?version=202372 特此感谢*/ let coverImageBigUrl = url; // 去除url中的裁剪标识 if (url.indexOf("@") > -1) { //处理以@做裁剪标识的url coverImageBigUrl = url.split("@")[0]; } if (url.indexOf("jpg_") > -1) { //处理以_做裁剪标识的url coverImageBigUrl = `${url.split("jpg_")[0]}jpg`; } if (url.indexOf("png_") > -1) { //处理以_做裁剪标识的url coverImageBigUrl = `${url.split("png_")[0]}png`; } if (url.indexOf("/320_200/") > -1) { //有时裁剪标识是在后缀名之前的 目前主要发现的是“番剧”板块的列表里有,但尚不清楚其他地方的情况 coverImageBigUrl = url.replace("/320_200", ""); } if (coverImageBigUrl.substring(0, 2) === XX + XX) { coverImageBigUrl = `https:${coverImageBigUrl}`; } else if (coverImageBigUrl.substring(0, 5) === "http:") { coverImageBigUrl = coverImageBigUrl.replace("http:", "https:"); } return coverImageBigUrl; }, window: undefined, openWin: function (win, src) { if (this.window) { this.setImg(src); } else { const self = this, doc = win.document; const w = win.outerWidth || doc.docElement.clientWidth || doc.body.clientWidth, h = win.outerHeight || doc.docElement.clientHeight || doc.body.clientHeight; self.window = window.open("about:blank", "bilibiliCover", `location=1,scrollbars=1,channelmode=1,width=${w * 0.8},height=${h * 0.95},left=${w * 0.1},top=${h * 0.1}`); setTimeout(() => { self.window.document.title = "BilibiliCover - 封面获取窗口"; self.window.document.body.innerHTML = `
设置: 选择主站旧版视频播放页封面获取按钮样式为'; self.window.document.body.style.textAlign = "center"; self.window.document.querySelector(`[value="${getConfig()}"]`).selected = true; self.window.document.querySelector("#buttonStyle").addEventListener("change", function () { GM_setValue("style", this.value === "button" ? "button" : "image"); if (self.window.isDeclared !== true) { const span = self.window.document.createElement("span"); span.style.color = "green"; span.style.marginLeft = "1em"; span.innerText = "保存成功!请刷新源页面!"; this.after(span); self.window.isDeclared = true; } }); self.setImg(src); const t = self.window.document.querySelector("textarea"); t.addEventListener("mouseup", function (e) { if (e.which !== 1) { return; } const selection = self.window.getSelection(); if (selection.toString() !== "") { return; } this.focus(); this.select(); }); self.window.document.querySelector("#google").addEventListener("click", () => { window.open(`https://www.google.com/searchbyimage?encoded_image=&image_content=&filename=&hl=zh-CN&image_url=${encodeURIComponent(t.value)}`, "_blank").focus(); }); const link = self.window.document.querySelector("#baidu"); link.addEventListener("click", () => { link.innerText = "搜索中……"; GM_xmlhttpRequest({ url: `https://graph.baidu.com/upload?tn=pc&from=pc&image_source=PC_UPLOAD_URL&image=${encodeURIComponent(t.value)}`, method: "GET", onerror: function (detail) { self.window.alert(`百度识图搜索失败:网络故障\n${detail}`); link.innerText = "Baidu识图搜索"; }, onload: function (res) { let response; try { response = JSON.parse(res.responseText); console.info("BilibiliCover", "BaiduNetworkResponse", res, JSON.parse(res.response)); } catch (e) { response = false; console.error("BilibiliCover", "BaiduNetworkResponse", res, e); } if (!response) { self.window.alert(`百度识图搜索失败:返回数据无法识别\n${res.responseText}`); link.innerText = "Baidu识图搜索"; return; } if (!response.data || !response.data.url) { self.window.alert(`百度识图搜索失败:返回数据格式错误\n${res.responseText}`); link.innerText = "Baidu识图搜索"; return; } window.open(response.data.url, "_blank").focus(); link.innerText = "Baidu识图搜索"; }, }); }); self.window.addEventListener("beforeunload", () => { self.window = undefined; }); self.window.focus(); self.window.addEventListener("resize", () => { self.resize(); }); self.resize(); }, 0); } }, resize: function resize() { if (!this.window) { return; } const self = this; const collection = this.window.document.querySelectorAll("body > *:not(img):not(style)"); let totalHeight = 0; Array.from(collection).forEach((t) => { totalHeight += self.getRealHeight(t); }); this.window.document.querySelector("body > img").style.maxHeight = `calc(100vh - ${totalHeight}px)`; }, getRealHeight: function getRealHeight(ele) { const style = (this.window || window).getComputedStyle(ele); let realHeight = 0; ["marginTop", "paddingTop", "height", "paddingBottom", "marginBottom"].forEach((p) => { const v = style[p]; if (/^\d/.test(v)) { realHeight += parseFloat(v); } }); return realHeight; }, setImg: function setImg(src) { if (!this.window) { return; } const img = this.window.document.querySelector("img"); this.window.document.querySelector("img").src = src; this.window.document.querySelector("textarea").value = src; this.setNaturalSize(img, this.window.document.querySelector("#realsize")); this.window.focus(); }, setNaturalSize: function setNaturalSize(img, node) { const self = this; if (img.naturalWidth > 0 && img.naturalHeight > 0) { node.innerText = `(${img.naturalWidth}×${img.naturalHeight})`; } else { setTimeout(() => { self.setNaturalSize(img, node); }, 100); } }, closeWin: function focusWin() { if (this.window) { this.window.close(); } }, }; const body = unsafeWindow.document.body, html = unsafeWindow.document.documentElement; const innerWidth = unsafeWindow.innerWidth; let scrollbarWidth = 0; switch ("scroll") { case getComputedStyle(body).overflowY: scrollbarWidth = innerWidth - body.clientWidth; break; case getComputedStyle(html).overflowY: scrollbarWidth = innerWidth - html.clientWidth; break; default: { const backup = body.style.overflowY; body.style.overflowY = "scroll"; scrollbarWidth = unsafeWindow.innerWidth - body.clientWidth; body.style.overflowY = backup; } } const url = new helper.Uri(); const doc = unsafeWindow.document; if (unsafeWindow.location.host.includes("www.bilibili.com")) { (function loop() { let IS_ORIGIN_VIDEO = true; let IS_NEW_BANGUMI = false; let aid_bvid = (url.path.match(/\/video\/(av\d+|[bB][vV]1[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9})/) || [0, -1])[1]; if (aid_bvid === -1) { if ((url.path.match(/\/bangumi\/play\/(?:ep|ss)(\d+)/) || [0, -1])[1] !== -1) { IS_NEW_BANGUMI = true; } IS_ORIGIN_VIDEO = false; } const style = doc.querySelector("#bilibiliCoverStyle") || doc.createElement("style"); style.innerText = ".bilibiliCoverHidden { display: none !important }"; style.id = "bilibiliCoverStyle"; if (style.parentElement !== doc.body) { doc.body.appendChild(style); } const img = doc.createElement("img"); img.addEventListener("error", (...args) => { args.unshift("BilibiliCover"); args.unshift("NetworkError"); console.error(...args); const s = new helper.Uri(img.src); s.query.t = new Date().getTime(); img.src = s; }); try { const meta = doc.querySelector('meta[property="og:image"], meta[itemprop="image"], meta[itemprop="thumbnailUrl"]'); const metacontent = meta.getAttribute("content"); const metacontentUri = new helper.Uri(metacontent); if (metacontentUri.host.endsWith("hdslb.com") && metacontentUri.path.startsWith("/bfs/archive/")) { img.src = metacontent; } } catch{ } if (IS_ORIGIN_VIDEO || IS_NEW_BANGUMI) { const plw = doc.querySelector("#arc_toolbar_report > .ops, #toolbar_module"); if (!plw || (plw.querySelector(".coin, .coin-info span") ? plw.querySelector(".coin, .coin-info span").innerText || "--" : "--") === "--") { return setTimeout(loop, 100); } const button = doc.createElement(IS_NEW_BANGUMI ? "div" : "span"); button.title = "获取封面"; button.innerHTML = `' : 'van-icon-info_playnumber">'}${IS_NEW_BANGUMI ? '获取封面' : "获取封面"}`; if (IS_NEW_BANGUMI) { button.setAttribute("style", "display: block; float: left; height: 24px; margin-left: 12px; cursor: pointer;"); } if (plw.querySelector(".more")) { plw.insertBefore(button, plw.querySelector(".more")); } else { plw.appendChild(button); } button.addEventListener("click", () => { const src = img.src; if (src) { helper.openWin(window, src, 1); } }); style.innerText += ".video-toolbar .ops .app { margin-right: 12px; }"; img.id = "cover_img"; doc.body.appendChild(img); img.style.position = "absolute"; img.style.top = "-99999px"; img.style.left = "0"; img.style.zIndex = "99999"; img.style.border = "1px black solid"; img.style.opacity = "0"; img.style.transition = "opacity .13s linear"; img.style.display = "none"; let code = null; button.addEventListener("mouseover", () => { if (code) { clearTimeout(code); code = null; } img.style.display = "block"; let X = 0, Y = 0, W = 0; let p = button; do { X += p.offsetTop; Y += p.offsetLeft; p = p.offsetParent; } while (p !== doc.body); const style = unsafeWindow.getComputedStyle(button); X += parseInt(style.marginTop) + parseInt(style.height) + parseInt(style.marginBottom) + 10; Y += parseInt(style.marginLeft) + parseInt(style.width) + parseInt(style.marginRight) + 10; W = (unsafeWindow.innerWidth - Y - 30) / 2; if (W > img.naturalWidth) { W = img.naturalWidth; } img.style.top = `${X - W * img.naturalHeight / img.naturalWidth - 10}px`; img.style.left = `${Y}px`; img.style.width = `${W}px`; img.style.opacity = "1"; }); button.addEventListener("mouseleave", () => { if (code) { clearTimeout(code); code = null; } img.style.opacity = "0"; code = setTimeout(() => { img.style.top = "-99999px"; code = null; }, 130); }); } else { const plw = doc.querySelector(".player-box, .bangumi-player, .view-later-module .video-box-module > .bili-wrapper"), bgray = plw ? plw.querySelector(".bgray-btn-wrap") : undefined; if (!plw || !bgray) { return setTimeout(loop, 100); } const button = doc.createElement("div"); button.classList.add("bgray-btn"); button.classList.add("show"); button.style.height = "auto"; button.innerText = "获取视频封面"; button.addEventListener("click", () => { const src = img.src; if (src) { helper.openWin(window, src); } }); bgray.appendChild(button); bgray.style.zIndex = "2"; (getConfig() === "button" ? img : button).classList.add("bilibiliCoverHidden"); img.addEventListener("click", function () { const src = this.src; if (src) { helper.openWin(window, src); } }); const sbw = scrollbarWidth; img.id = "cover_img"; img.style.display = "none"; img.style.position = "absolute"; img.style.cursor = "pointer"; plw.appendChild(img); function calc() { const bsn = Array.from(plw.children).filter((ele, i) => { return plw.children[i - 1] && ele.nodeName !== "IMG" && /(?:_{2})?bofqi/i.test(plw.children[i - 1].id); })[0]; if (!bsn) { return setTimeout(() => { calc(); }, 100); } const ofs = getComputedStyle(bsn); const ofl = parseInt(ofs.width) + parseInt(ofs.marginLeft) + parseInt(ofs.paddingLeft) + parseInt(ofs.borderLeftWidth), ofb = parseInt(ofs.height) + parseInt(ofs.marginTop) + parseInt(ofs.paddingTop) + parseInt(ofs.borderTopWidth), wdt = ofs.width; const w = window.innerWidth || doc.docElement.clientWidth || doc.body.clientWidth; img.style.left = `calc(${ofl}px + 1em)`; img.style.bottom = `calc(${ofb}px + 1em)`; img.style.width = `calc(${w}px / 2 - ${wdt} / 2 - 2em - ${sbw / 2}px)`; img.style.display = "block"; } calc(); img.title = `此处是本视频封面大图!${LF}${LF}右键菜单可复制图片大图地址,${LF}左键单击可在新窗口查看大图!`; window.addEventListener("resize", () => { calc(); }); } let running = false; const err = function err(...args) { args.unshift("BilibiliCover"); args.unshift("NetworkError:"); console.error(...args); img.alt = args.map((e) => { return JSON.stringify(e); }).join("\n"); running = false; }; setInterval(() => { if (IS_ORIGIN_VIDEO) { const aidDetected = new helper.Uri().path.match(/\/video\/(av\d+|[bB][vV]1[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9})/)[1]; if ((aidDetected !== aid_bvid || !img.src) && !running) { aid_bvid = aidDetected; running = true; GM_xmlhttpRequest({ url: `https://api.bilibili.com/x/web-interface/search/type?search_type=video&keyword=${aid_bvid}`, method: "GET", onerror: err, onload: function (res) { try { response = JSON.parse(res.responseText); } catch (e) { response = false; } console.info("BilibiliCover", "NetworkResponse:", res, ", parse result:", response); if (!response) { err("Unable to parse response"); return; } const data = response.data.result; if (!Array.isArray(data)) { err(`Backend returns incompatible data(${typeof data})`); return; } let cover; data.forEach((info) => { if ((`av${info.aid}` === aid_bvid || info.bvid === aid_bvid) && info.pic) { cover = helper.coverImage(info.pic); } }); if (cover) { img.src = cover; } else { err("Unable to get the cover picture url"); } running = false; }, }); } } else { try { img.src = helper.coverImage(doc.querySelector("#bofqi .bilibili-player-watchlater-item[data-state-play=true] .bilibili-player-watchlater-cover-cell img, .bangumi-info-wrapper .info-cover img, #media_module > a > img").src); // clearInterval(loop_code); img.removeAttribute("alt"); } catch (_) { console.info("bilibiliCover:", "no img"); img.alt = "bilibiliCover: no img"; } } }, 100); })(); } else if (unsafeWindow.location.host.includes("live.bilibili.com")) { (function loop() { const link = unsafeWindow.document.createElement("div"); const error = (...args) => { const detail = args[0]; link.innerHTML = `封面获取失败=。=(+${detail})`; args.unshift("BilibiliCover"); args.unshift("NetworkError"); console.error(...args); }; const roomid = unsafeWindow.location.pathname.match(/^\/(?:blanc\/)?(\d+)/)[1]; // const userName = (((unsafeWindow.document.querySelector(".room-owner-username") || {}).href || "").match(/\d+/) || [])[0]; if (roomid) { GM_xmlhttpRequest({ url: `https://api.bilibili.com/x/web-interface/search/type?search_type=live&keyword=${roomid}`, method: "GET", onerror: error, onload: function (res) { const container = unsafeWindow.document.querySelector(".seeds-wrap"); if (!container) { return setTimeout(loop, 100); } link.style.display = "inline-block"; link.style.marginLeft = link.style.marginRight = "1em"; link.innerHTML = '查看封面'; container.insertBefore(link, container.firstChild); link.querySelector("a").addEventListener("click", () => { console.info("BilibiliCover", "NetworkResponse", res, JSON.parse(res.response)); try { response = JSON.parse(res.responseText); } catch (e) { response = false; } if (!response) { error("无法解析后端返回数据", res); } // let cover; const data = response.data && response.data.result; if (!Array.isArray(data.live_room) || !Array.isArray(data.live_user)) { error("后端返回数据格式错误", response); return; } if (data.live_room) { data.live_room.forEach((info) => { if ([info.short_id, info.roomid].indexOf(+roomid) !== -1 && info.user_cover) { cover = helper.coverImage(info.user_cover); } }); } if (cover) { helper.openWin(unsafeWindow, cover); } else { error("无法获取封面地址,请在主播开播时重试(如已开播则可能是主播未设置封面)", response); } }); }, }); } })(); } window.addEventListener("beforeunload", () => { helper.closeWin(); }); });