您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
QQ音乐网页播放器歌词获取器,直接在播放器内获取lrc
// ==UserScript== // @name QQ音乐网页播放器歌词lrc获取器 // @namespace AnnAngela // @match https://y.qq.com/n/ryqq/player* // @grant unsafeWindow // @grant GM_setClipboard // @version 1.0 // @author AnnAngela // @description QQ音乐网页播放器歌词获取器,直接在播放器内获取lrc // @run-at document-start // ==/UserScript== "use strict"; const base65Charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; const decodeQMStupidEncodedText = function (encodedText) { const filteredText = encodedText.replace(/[^A-Za-z0-9+/=]/g, ""); let transferedText = ""; for (let i = 0; i < encodedText.length; void 0) { const i1 = i++; const i2 = i++; const i3 = i++; const i4 = i++; const transferedCode1 = base65Charset.indexOf(filteredText.charAt(i2)); const charCode = base65Charset.indexOf(filteredText.charAt(i1)) << 2 | transferedCode1 >> 4; const transferedCode2 = base65Charset.indexOf(filteredText.charAt(i3)); const transferedCode3 = (15 & transferedCode1) << 4 | transferedCode2 >> 2; const transferedCode4 = base65Charset.indexOf(filteredText.charAt(i4)); const transferedCode5 = (3 & transferedCode2) << 6 | transferedCode4; transferedText += String.fromCharCode(charCode); if (transferedCode2 !== 64) { transferedText += String.fromCharCode(transferedCode3); } if (transferedCode4 !== 64) { transferedText += String.fromCharCode(transferedCode5); } } let decodedText = ""; for (let j = 0; j < transferedText.length; void 0) { const charCode = transferedText.charCodeAt(j); if (charCode < 128) { decodedText += String.fromCharCode(charCode); j++; } else if (charCode > 191 && charCode < 224) { const charCode2 = transferedText.charCodeAt(j + 1); decodedText += String.fromCharCode((31 & charCode) << 6 | 63 & charCode2); j += 2; } else { const charCode3 = transferedText.charCodeAt(j + 1); const charCode4 = transferedText.charCodeAt(j + 2); decodedText += String.fromCharCode((15 & charCode) << 12 | (63 & charCode3) << 6 | 63 & charCode4); j += 3; } } return decodedText; }; const lyrics = {}; class XHR extends unsafeWindow.XMLHttpRequest { constructor(...args) { super(...args); this.addEventListener("readystatechange", () => { if (this.readyState === 4 && this.responseURL.startsWith("https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg")) { try { const json = JSON.parse(this.responseText); const songmid = new URL(this.responseURL).searchParams.get("songmid"); if (typeof songmid === "string" && songmid.length > 4 && json.code === 0 && json.type !== 3) { const originalLyric = decodeQMStupidEncodedText(json.lyric); const translatedLyric = decodeQMStupidEncodedText(json.trans); const playSongData = JSON.parse(localStorage.getItem("playSongData")); const title = playSongData.value.songList.filter(({ mid }) => mid === songmid)[0].title; lyrics[title] = { originalLyric, translatedLyric }; } } catch (e) { console.error("[Lyric Fetcher From QQMusic Web Player] Error:", e); } } }); } } unsafeWindow.XMLHttpRequest = XHR; window.addEventListener("load", () => { const container = document.createElement("div"); document.body.appendChild(container); container.setAttribute("style", "position:fixed;top:20%;bottom:20%;left:30%;right:30%;z-index:999999999;background:white;opacity:0;pointer-event:none;"); const button = document.createElement("div"); document.body.appendChild(button); button.setAttribute("style", "position:fixed;bottom:1em;right:1em;z-index:999999999;background:white;padding: .25rem; border-radius: .25rem;cursor:pointer;"); button.innerText = "获取歌词lrc"; let opening = false; button.addEventListener("click", () => { if (opening) { opening = false; container.style.opacity = "0"; container.style.pointerEvents = "none"; button.innerText = "获取歌词lrc"; return; } opening = true; container.style.opacity = "1"; container.style.pointerEvents = "all"; button.innerText = "关闭歌词lrc窗口"; container.innerHTML = '<h2 style="text-align: center;">获取歌词lrc</h2>'; const ul = document.createElement("ul"); ul.style.margin = "revert"; ul.style.padding = "revert"; container.appendChild(ul); for (const [name, { originalLyric, translatedLyric }] of Object.entries(lyrics)) { const li = document.createElement("li"); ul.appendChild(li); li.style.listStyle = "revert"; li.style.margin = "revert"; li.style.padding = "revert"; const span = document.createElement("span"); li.appendChild(span); span.innerText = name; if (originalLyric) { const br = document.createElement("br"); li.appendChild(br); const span = document.createElement("span"); li.appendChild(span); span.innerText = "原文歌词:"; const button = document.createElement("button"); button.innerText = "复制到剪切板"; button.addEventListener("click", () => { GM_setClipboard(originalLyric); }); li.appendChild(button); const br2 = document.createElement("br"); li.appendChild(br2); const span2 = document.createElement("span"); span2.innerText = `预览:${originalLyric.length > 100 ? `${originalLyric.slice(0, 100)}……` : originalLyric}`; li.appendChild(span2); } if (translatedLyric) { const br = document.createElement("br"); li.appendChild(br); const span = document.createElement("span"); li.appendChild(span); span.innerText = "翻译歌词:"; const button = document.createElement("button"); button.innerText = "复制到剪切板"; button.addEventListener("click", () => { GM_setClipboard(translatedLyric); }); li.appendChild(button); const br2 = document.createElement("br"); li.appendChild(br2); const span2 = document.createElement("span"); span2.innerText = `预览:${translatedLyric.length > 100 ? `${translatedLyric.slice(0, 100)}……` : translatedLyric}`; li.appendChild(span2); } } }); });