汽水音乐歌词下载

下载汽水音乐歌词(LRC逐字格式)

// ==UserScript==
// @name         汽水音乐歌词下载
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  下载汽水音乐歌词(LRC逐字格式)
// @author       Yanice537
// @match        https://music.douyin.com/qishui/share/track*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 创建下载按钮
    function createDownloadButton() {
        const btn = document.createElement('button');
        btn.innerHTML = '下载LRC歌词';
        btn.style.position = 'fixed';
        btn.style.bottom = '20px';
        btn.style.right = '20px';
        btn.style.zIndex = '9999';
        btn.style.padding = '12px 24px';
        btn.style.background = 'linear-gradient(45deg, #ff2a55, #ff8a00)';
        btn.style.color = 'white';
        btn.style.border = 'none';
        btn.style.borderRadius = '30px';
        btn.style.fontWeight = 'bold';
        btn.style.fontSize = '16px';
        btn.style.cursor = 'pointer';
        btn.style.boxShadow = '0 4px 15px rgba(255, 42, 85, 0.4)';
        btn.style.transition = 'all 0.3s ease';

        btn.onmouseover = () => {
            btn.style.transform = 'translateY(-3px)';
            btn.style.boxShadow = '0 6px 20px rgba(255, 42, 85, 0.6)';
        };

        btn.onmouseout = () => {
            btn.style.transform = 'translateY(0)';
            btn.style.boxShadow = '0 4px 15px rgba(255, 42, 85, 0.4)';
        };

        btn.onclick = downloadLyrics;

        document.body.appendChild(btn);
        return btn;
    }

    // 下载歌词
    async function downloadLyrics() {
        const btn = this;
        const originalText = btn.innerHTML;
        btn.innerHTML = '获取歌词中...';
        btn.disabled = true;

        try {
            // 获取当前页面URL参数
            const urlParams = new URLSearchParams(window.location.search);
            const track_id = urlParams.get('track_id');

            if (!track_id) {
                throw new Error('无法获取歌曲ID');
            }

            // 构建API请求URL
            const apiUrl = `https://music.douyin.com/qishui/share/track?${urlParams.toString()}`;

            // 发送请求获取歌词数据
            const response = await fetch(apiUrl);
            const responseText = await response.text();

            // 获取歌曲元数据
            const { artistName, songTitle, composer, lyricist } = extractMetadata(responseText);

            // 创建文件名
            const filename = `${artistName}-${songTitle}.lrc`.replace(/[\\/:*?"<>|]/g, '');

            // 解析歌词
            let lrcContent = parseLyrics(responseText);

            // 添加元数据到歌词开头
            lrcContent = addMetadataToLyrics(lrcContent, composer, lyricist);

            // 下载文件
            downloadFile(lrcContent, filename);

            btn.innerHTML = '下载成功!';
            setTimeout(() => {
                btn.innerHTML = originalText;
                btn.disabled = false;
            }, 2000);
        } catch (error) {
            console.error('歌词下载失败:', error);
            btn.innerHTML = '失败,点击重试';
            btn.disabled = false;

            // 显示错误提示
            showErrorToast(`歌词下载失败: ${error.message}`);
        }
    }

    // 提取歌曲元数据
    function extractMetadata(responseText) {
        // 歌曲名
        const songTitleMatch = responseText.match(/"trackName":"(.*?)"/);
        const songTitle = songTitleMatch ? songTitleMatch[1] : '未知歌曲';

        // 歌手名
        const artistNameMatch = responseText.match(/"artistName":"(.*?)"/);
        const artistName = artistNameMatch ? artistNameMatch[1] : '未知歌手';

        // 作曲
        const composerMatch = responseText.match(/"text":"作曲:(.*?)","startMs":(\d+),"endMs":(\d+)/);
        const composer = composerMatch ? composerMatch[1] : '未知作曲';

        // 作词
        const lyricistMatch = responseText.match(/"text":"作词:(.*?)","startMs":(\d+),"endMs":(\d+)/);
        const lyricist = lyricistMatch ? lyricistMatch[1] : '未知作词';

        return {
            songTitle,
            artistName,
            composer,
            lyricist
        };
    }

    // 添加元数据到歌词开头
    function addMetadataToLyrics(lyrics, composer, lyricist) {
        return `[ar:${composer}]\n` +
            `[ti:${lyricist}]\n\n` +
            lyrics;
    }

    // 解析歌词
    function parseLyrics(responseText) {
        // 使用正则表达式提取逐行歌词
        const lineLyrics = [];
        const lineRegex = /{"text":"(.*?)","startMs":(\d+),"endMs":(\d+)(?=,"words":)/g;
        let lineMatch;

        while ((lineMatch = lineRegex.exec(responseText)) !== null) {
            lineLyrics.push({
                text: lineMatch[1],
                startMs: parseInt(lineMatch[2]),
                endMs: parseInt(lineMatch[3])
            });
        }

        // 提取逐字歌词信息
        const wordLyrics = [];
        const wordRegex = /{"startMs":(\d+),"endMs":(\d+),"text":"(.*?)"}/g;
        let wordMatch;

        while ((wordMatch = wordRegex.exec(responseText)) !== null) {
            wordLyrics.push({
                startMs: parseInt(wordMatch[1]),
                endMs: parseInt(wordMatch[2]),
                text: wordMatch[3]
            });
        }

        // 准备LRC内容
        const lrcContent = [];

        // 处理每一行歌词
        for (const line of lineLyrics) {
            const lineStartMs = line.startMs;
            const lineEndMs = line.endMs;
            const lineText = line.text;

            // 收集属于当前行的逐字歌词
            const lineWords = [];
            for (const word of wordLyrics) {
                if (word.startMs >= lineStartMs && word.startMs <= lineEndMs) {
                    lineWords.push({
                        startMs: word.startMs,
                        text: word.text
                    });
                }
            }

            // 如果没有逐字歌词,使用整行文本
            if (lineWords.length === 0) {
                const timeTag = formatTime(lineStartMs);
                lrcContent.push(`${timeTag}${lineText}`);
            } else {
                // 按时间排序逐字歌词
                lineWords.sort((a, b) => a.startMs - b.startMs);

                // 生成逐字LRC行
                let lineStr = '';
                for (const word of lineWords) {
                    const timeTag = formatTime(word.startMs);
                    lineStr += `${timeTag}${word.text}`;
                }
                lrcContent.push(lineStr);
            }
        }

        return lrcContent.join('\n');
    }

    // 格式化时间标签
    function formatTime(ms) {
        const minutes = Math.floor(ms / 60000);
        const seconds = Math.floor((ms % 60000) / 1000);
        const centiseconds = Math.floor((ms % 1000) / 10);
        return `[${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}.${centiseconds.toString().padStart(2, '0')}]`;
    }

    // 下载文件
    function downloadFile(content, filename) {
        const blob = new Blob([content], { type: 'text/plain' });
        const url = URL.createObjectURL(blob);

        const a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();

        // 清理
        setTimeout(() => {
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }, 100);
    }

    // 显示错误提示
    function showErrorToast(message) {
        let toast = document.getElementById('lyrics-error-toast');

        if (!toast) {
            toast = document.createElement('div');
            toast.id = 'lyrics-error-toast';
            toast.style.position = 'fixed';
            toast.style.top = '20px';
            toast.style.left = '50%';
            toast.style.transform = 'translateX(-50%)';
            toast.style.backgroundColor = '#ff2a55';
            toast.style.color = 'white';
            toast.style.padding = '15px 25px';
            toast.style.borderRadius = '8px';
            toast.style.zIndex = '10000';
            toast.style.fontWeight = 'bold';
            toast.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.3)';
            toast.style.transition = 'opacity 0.3s';
            document.body.appendChild(toast);
        }

        toast.textContent = message;
        toast.style.opacity = '1';

        setTimeout(() => {
            toast.style.opacity = '0';
        }, 3000);
    }

    // 初始化
    window.addEventListener('load', () => {
        createDownloadButton();
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址