Greasy Fork

来自缓存

Greasy Fork is available in English.

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

QQ音乐网页播放器歌词获取器,直接在播放器内获取lrc

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

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