Greasy Fork is available in English.

QQ音乐网页播放器歌词lrc获取器

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);
            }
        }
    });
});