{"version":"https://jsonfeed.org/version/1.1","title":"DBD-raws","home_page_url":"https://cms.dbdraws.dpdns.org","feed_url":"https://cms.dbdraws.dpdns.org/json/","description":"<style>\n        #api-text-container {\n            font-size: 22px;\n            \n            max-width: 90%;\n            text-align: center;\n            line-height: 1.6;\n            padding: 20px;\n            border-left: 4px solid #4CAF50;\n            box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n        }\n@media (max-width: 768px) {\n            #api-text-container {\n                font-size: 18px; /* 移动端减小到18px */\n                max-width: 95%; /* 移动端宽度占比更大（减少留白） */\n                padding: 15px; /* 移动端内边距减小 */\n            }\n    </style>\n<p id=\"api-text-container\"></p>\n<script>\n  // 调用文字API（以「一言」为例，返回随机句子）\n  fetch(\"https://v1.hitokoto.cn/?c=d\") // API地址（返回JSON）\n    .then(response => response.json())\n    .then(data => {\n      // 将API返回的文字填入容器（不添加任何样式，使用网站默认文本样式）\n      document.getElementById(\"api-text-container\").textContent = data.hitokoto;\n    })\n    .catch(error => {\n      // 加载失败时显示提示（同样使用默认样式）\n      document.getElementById(\"api-text-container\").textContent = \"加载失败，请稍后刷新\";\n    });\n</script>\n\n<p>这是一款轻量级的内容管理系统（CMS），可自行托管于Cloudflare平台。通过microfeed，您能够便捷地发布多种形式的内容——包括音频、视频、照片、文档、博客文章及外部链接，并以网页、RSS订阅和JSON格式输出信息流。</p>","icon":"https://cms.dbdraws.dpdns.org/assets/default/channel-image.png","favicon":"https://cms.dbdraws.dpdns.org/assets/default/favicon.png","authors":[{"name":"DBD制作组"}],"language":"zh-cn","items":[{"id":"lkhoTm8kFvy","title":"在线音乐","url":"https://cms.dbdraws.dpdns.org/i/ceshi-lkhoTm8kFvy/","content_html":"\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>全能音乐搜索播放器</title>\n    <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css\">\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n        }\n        \n        body {\n            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);\n            color: #fff;\n            min-height: 100vh;\n            padding: 20px;\n        }\n        \n        .container {\n            max-width: 1200px;\n            margin: 0 auto;\n            display: grid;\n            grid-template-columns: 1fr 1.5fr;\n            gap: 20px;\n        }\n\n\n        /* 新增的移动端优化CSS - 不改变任何现有元素 */\n@media (max-width: 768px) {\n    body {\n        padding: 10px;\n        font-size: 13px;\n    }\n    \n    .container {\n        grid-template-columns: 1fr;\n        gap: 15px;\n    }\n    \n    h1 {\n        font-size: 1.8rem;\n        gap: 10px;\n    }\n    \n    .search-box {\nflex-direction: column;\n        max-width: 100%;\n        gap: 12px;\n\n    }\n    \n    .search-box input,\n    .search-box select,\n    .search-box button {\n        width: 100%;\n\n    }\n    \n    .panel {\n        padding: 15px;\n    }\n    \n    .album-art {\n        max-height: 80vw;\n    }\n    \n    .control-btn {\n        width: 56px;\n        height: 56px;\n        min-width: 56px;\n    }\n    \n    .quality-selector {\n        justify-content: center;\n    }\n    \n    .lyrics-container {\n        max-height: 40vh;\n        padding: 15px;\n        font-size: 1rem;\n    }\n    \n    .result-item {\n        padding: 12px;\n        gap: 12px;\n    }\n    \n    .album-thumb {\n        width: 50px;\n        height: 50px;\n    }\n    \n    /* 触摸反馈优化 */\n    button, .control-btn, .quality-btn, .result-item {\n        transition: all 0.15s ease;\n    }\n    \n    button:active, \n    .control-btn:active, \n    .quality-btn:active,\n    .result-item:active {\n        transform: scale(0.98);\n        opacity: 0.9;\n    }\n    \n    /* 文本溢出处理 */\n\n    \n    /* 移动端隐藏部分装饰性图标 */\n    .panel-title i {\n        display: none;\n    }\n\n    /* 移动端进度条更明显 */\n    .progress-container {\n        height: 6px;\n    }\n    \n    /* 禁用移动端hover效果 */\n    .result-item:hover {\n        transform: none;\n        background: rgba(255, 255, 255, 0.1);\n    }\n    \n    .control-btn:hover {\n        transform: none;\n        background: rgba(255, 255, 255, 0.1);\n    }\n}\n\n/* 更小屏幕的额外优化 */\n@media (max-width: 480px) {\n    body {\n        padding: 8px;\n    }\n    \n    .panel {\n        padding: 12px;\n    }\n    \n    .main-controls {\n        gap: 15px;\n    }\n    \n    /* 确保输入框字体大小不被缩放 */\n    input, select, button {\n        font-size: 16px !important;\n    }\n}\n\n  \n\n\n      \n        header {\n            grid-column: 1 / -1;\n            text-align: center;\n            padding: 20px;\n            background: rgba(0, 0, 0, 0.3);\n            border-radius: 15px;\n            margin-bottom: 20px;\n            backdrop-filter: blur(10px);\n            border: 1px solid rgba(255, 255, 255, 0.1);\n        }\n        \n        h1 {\n            font-size: 2.5rem;\n            margin-bottom: 10px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            gap: 15px;\n        }\n        \n        h1 i {\n            color: #FF0054;\n        }\n        \n        .search-box {\n            display: flex;\n            gap: 10px;\n            margin: 20px auto;\n            max-width: 650px;\n        }\n        \n        input, select, button {\n            padding: 12px 15px;\n            border: none;\n            border-radius: 50px;\n            font-size: 1rem;\n            outline: none;\n        }\n        \n        input {\n            flex: 1;\n            background: rgba(255, 255, 255, 0.9);\n            color: #333;\n        }\n        \n        select {\n            background: rgba(255, 255, 255, 0.85);\n            color: #333;\n            width: 140px;\n        }\n        \n        button {\n            background: linear-gradient(to right, #FF0054, #FF512F);\n            color: white;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            width: 120px;\n            font-weight: bold;\n        }\n        \n        button:hover {\n            transform: translateY(-2px);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);\n        }\n        \n        .panel {\n            grid-column: 1 / -1;\n            text-align: center;\n            padding: 20px;\n            background: rgba(0, 0, 0, 0.3);\n            border-radius: 15px;\n            margin-bottom: 20px;\n            backdrop-filter: blur(10px);\n            border: 1px solid rgba(255, 255, 255, 0.1);\n            background: rgba(0, 0, 0, 0.4);\n            border-radius: 15px;\n            padding: 20px;\n            backdrop-filter: blur(10px);\n            border: 1px solid rgba(255, 255, 255, 0.1);\n            height: fit-content;\n        }\n\n        .panel-title {\n            display: flex;\n            align-items: center;\n            gap: 10px;\n            margin-bottom: 20px;\n            padding-bottom: 10px;\n            border-bottom: 1px solid rgba(255, 255, 255, 0.2);\n        }\n        \n         .panel-title i {\n            color: #4ecca3;\n        }\n        \n        /* 搜索结果区域 */\n        .results-list {\n            max-height: 600px;\n            overflow-y: auto;\n            padding-right: 10px;\n        }\n        \n        .result-item {\n            background: rgba(255, 255, 255, 0.1);\n            padding: 15px;\n            border-radius: 10px;\n            margin-bottom: 10px;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            display: flex;\n            align-items: center;\n            gap: 15px;\n        }\n        \n        .result-item:hover {\n            background: rgba(255, 255, 255, 0.2);\n            transform: translateX(5px);\n        }\n        \n        .result-item.active {\n            background: linear-gradient(to right, rgba(255, 0, 84, 0.4), rgba(78, 204, 163, 0.4));\n            border-left: 4px solid #FF0054;\n        }\n        \n        .album-thumb {\n            width: 60px;\n            height: 60px;\n            border-radius: 8px;\n            background: rgba(255, 255, 255, 0.1);\n            overflow: hidden;\n            flex-shrink: 0;\n        }\n        \n        .album-thumb img {\n            width: 100%;\n            height: 100%;\n            object-fit: cover;\n        }\n        \n        .song-info h3 {\n            font-size: 1rem;\n            margin-bottom: 5px;\n        }\n        \n        .song-info p {\n            font-size: 0.8rem;\n            color: #ddd;\n        }\n        \n        /* 播放器区域 */\n        .player-container {\n            display: flex;\n            flex-direction: column;\n            gap: 20px;\n        }\n        .player-lyrics {\n            display: flex;\n            flex-direction: column;\n            gap: 20px;\n        }\n        .album-art {\n            width: 100%;\n            aspect-ratio: 1/1;\n            border-radius: 15px;\n            background: rgba(0, 0, 0, 0.3);\n            overflow: hidden;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n        }\n        \n        .album-art img {\n            width: 100%;\n            height: 100%;\n            object-fit: cover;\n        }\n        \n        .album-art i {\n            font-size: 5rem;\n            color: rgba(255, 255, 255, 0.1);\n        }\n        \n        .player-controls {\n            display: flex;\n            flex-direction: column;\n            gap: 15px;\n        }\n        \n        .quality-selector {\n            display: flex;\n            gap: 10px;\n            flex-wrap: wrap;\n            padding: 10px 0;\n        }\n        \n        .quality-btn {\n            padding: 8px 15px;\n            background: rgba(255, 255, 255, 0.15);\n            border-radius: 20px;\n            cursor: pointer;\n            transition: all 0.3s ease;\n        }\n        \n        .quality-btn.active {\n            background: #FF0054;\n        }\n        \n        .controls {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            padding: 10px 0;\n        }\n        \n        .main-controls {\n            display: flex;\n            gap: 20px;\n            align-items: center;\n        }\n        \n        .control-btn {\n            width: 50px;\n            height: 50px;\n            border-radius: 50%;\n            background: rgba(255, 255, 255, 0.1);\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            cursor: pointer;\n            transition: all 0.3s ease;\n        }\n        \n        .control-btn:hover {\n            background: rgba(255, 255, 255, 0.2);\n            transform: scale(1.05);\n        }\n        \n        .control-btn.play {\n            background: #FF0054;\n        }\n        \n        .control-btn.play:hover {\n            background: #ff336d;\n        }\n        \n        .progress-container {\n            width: 100%;\n            height: 5px;\n            background: rgba(255, 255, 255, 0.2);\n            border-radius: 5px;\n            cursor: pointer;\n            margin: 15px 0;\n        }\n        \n        .progress-bar {\n            height: 100%;\n            background: #FF0054;\n            border-radius: 5px;\n            width: 0%;\n            transition: width 0.1s linear;\n        }\n        \n        .time-info {\n            display: flex;\n            justify-content: space-between;\n            font-size: 0.9rem;\n            color: #ddd;\n        }\n        \n        /* 歌词区域 */\n        .lyrics-container {\n            background: rgba(0, 0, 0, 0.3);\n            border-radius: 10px;\n            padding: 20px;\n            margin-top: 20px;\n            max-height: 503.16px;\n            overflow-y: auto;\n            font-size: 1.1rem;\n            line-height: 2;\n        }\n        \n        .lyrics-container p {\n            margin-bottom: 15px;\n            transition: all 0.3s ease;\n            opacity: 0.7;\n        }\n        \n        .lyrics-container p.active {\n            color: #FF0054;\n            font-weight: bold;\n            opacity: 1;\n            transform: scale(1.05);\n        }\n        \n        .empty-state {\n            text-align: center;\n            padding: 40px 20px;\n            color: rgba(255, 255, 255, 0.7);\n        }\n        \n        .empty-state i {\n            font-size: 5rem;\n            margin-bottom: 20px;\n            opacity: 0.3;\n        }\n        \n        .empty-state h3 {\n            font-size: 1.5rem;\n            margin-bottom: 10px;\n        }\n        \n        .empty-state p {\n            font-size: 1rem;\n        }\n        \n        /* 滚动条样式 */\n        ::-webkit-scrollbar {\n            width: 8px;\n        }\n        \n        ::-webkit-scrollbar-track {\n            background: rgba(0, 0, 0, 0.2);\n            border-radius: 10px;\n        }\n        \n        ::-webkit-scrollbar-thumb {\n            background: rgba(255, 0, 84, 0.5);\n            border-radius: 10px;\n        }\n        \n        ::-webkit-scrollbar-thumb:hover {\n            background: rgba(255, 0, 84, 0.8);\n        }\n        \n        /* 分页控件样式 */\n        .pagination {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            gap: 10px;\n            margin-top: 20px;\n            padding: 10px 0;\n            flex-wrap: wrap;\n        }\n        \n        .pagination-btn {\n            background: rgba(255, 255, 255, 0.1);\n            color: white;\n            border: none;\n            border-radius: 50%;\n            width: 40px;\n            height: 40px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            cursor: pointer;\n            transition: all 0.3s ease;\n            font-size: 0.9rem;\n        }\n        \n        .pagination-btn:hover:not(.disabled) {\n            background: rgba(255, 0, 84, 0.7);\n        }\n        \n        .pagination-btn.disabled {\n            opacity: 0.3;\n            cursor: not-allowed;\n        }\n        \n        .pagination-btn.active {\n            background: #FF0054;\n            transform: scale(1.1);\n        }\n        \n        .page-info {\n            font-size: 0.9rem;\n            color: #ddd;\n            padding: 0 15px;\n        }\n        \n        .page-input {\n            background: rgba(255, 255, 255, 0.1);\n            border: none;\n            border-radius: 20px;\n            padding: 8px 15px;\n            color: white;\n            width: 80px;\n            text-align: center;\n            margin: 0 5px;\n        }\n        \n        .page-input:focus {\n            outline: 1px solid #FF0054;\n        }\n        \n        .page-jump-btn {\n            background: rgba(255, 255, 255, 0.2);\n            color: white;\n            border: none;\n            border-radius: 20px;\n            padding: 8px 15px;\n            cursor: pointer;\n            transition: all 0.3s ease;\n        }\n        \n        .page-jump-btn:hover {\n            background: rgba(255, 0, 84, 0.7);\n        }\n        \n        footer {\n            grid-column: 1 / -1;\n            text-align: center;\n            padding: 20px;\n            margin-top: 20px;\n            font-size: 0.9rem;\n            color: rgba(255, 255, 255, 0.7);\n        }\n    </style>\n</head>\n<br>\n\n    <div class=\"container\">\n        <header>\n            <h1><i class=\"fas fa-music\"></i> 无损音乐搜索播放器</h1>\n            <p>支持多个音乐源，高音质播放，歌词显示和专辑封面浏览</p>\n            \n            <div class=\"search-box\">\n                <input type=\"text\" id=\"search-input\" placeholder=\"输入歌曲名称、歌手或专辑...\">\n                <select id=\"source-select\">\n                    <option value=\"netease\">网易云音乐✔</option>\n                    <option value=\"joox\">JOOX音乐✔</option>\n                    <option value=\"kuwo\">酷我音乐✔</option>\n                    <option value=\"bilibili\">B站(不稳定)✔</option>\n                    <option value=\"tidal\">Tidal✔</option>\n                    <option value=\"apple\">Apple Music(中转)✔</option>\n                    <option value=\"tencent\">QQ音乐✘</option>\n                    <option value=\"spotify\">Spotify✘</option>\n                    <option value=\"kugou\">酷狗音乐✘</option>\n                </select>\n                <button id=\"search-btn\"><i class=\"fas fa-search\"></i> 搜索</button>\n            </div>\n        </header>\n        \n        <div class=\"panel\">\n            <div class=\"panel-title\">\n                <i class=\"fas fa-list\"></i>\n                <h2>搜索结果</h2>\n            </div>\n            \n            <div class=\"results-list\" id=\"results-container\">\n                <div class=\"empty-state\">\n                    <i class=\"fas fa-search\"></i>\n                    <h3>搜索音乐</h3>\n                    <p>输入关键词并选择音乐源后点击搜索按钮</p>\n                </div>\n            </div>\n            \n            <!-- 分页控件 -->\n            <div class=\"pagination\" id=\"pagination-container\">\n                <!-- 动态生成分页按钮 -->\n            </div>\n        </div>\n        \n        <div class=\"player-container\">\n            <div class=\"panel\">\n                <div class=\"panel-title\">\n                    <i class=\"fas fa-compact-disc\"></i>\n                    <h2>专辑封面</h2>\n                </div>\n                \n                <div class=\"album-art\">\n                    <i class=\"fas fa-music\"></i>\n                </div>\n                \n                <div class=\"player-controls\">\n                    <div class=\"quality-selector\">\n                        <div class=\"quality-btn\" data-quality=\"999\">无损音质</div>\n                        <div class=\"quality-btn active\" data-quality=\"320\">高品质</div>\n                        <div class=\"quality-btn\" data-quality=\"192\">中等音质</div>\n                        <div class=\"quality-btn\" data-quality=\"128\">普通音质</div>\n                    </div>\n                    \n                    <div class=\"controls\">\n                        <div class=\"main-controls\">\n                            <div class=\"control-btn\">\n                                <i class=\"fas fa-step-backward\"></i>\n                            </div>\n                            <div class=\"control-btn play\">\n                                <i class=\"fas fa-play\"></i>\n                            </div>\n                            <div class=\"control-btn\">\n                                <i class=\"fas fa-step-forward\"></i>\n                            </div>\n                        </div>\n                        \n                        <div class=\"volume\">\n                            <i class=\"fas fa-volume-up\"></i>\n                        </div>\n                    </div>\n                    \n                    <div class=\"progress-container\">\n                        <div class=\"progress-bar\" id=\"progress-bar\"></div>\n                    </div>\n                    \n                    <div class=\"time-info\">\n                        <span id=\"current-time\">0:00</span>\n                        <span id=\"total-time\">0:00</span>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <div class=\"player-lyrics\">\n            <div class=\"panel\">\n                <div class=\"panel-title\">\n                    <i class=\"fas fa-file-alt\"></i>\n                    <h2>歌词</h2>\n                </div>\n          \n                <div class=\"lyrics-container\" id=\"lyrics-container\">\n                    <div class=\"empty-state\">\n                        <i class=\"fas fa-file-alt\"></i>\n                        <h3>歌词显示区域</h3>\n                        <p>选择歌曲后，歌词将显示在这里</p>\n                    </div>\n                </div>\n        </div>\n    </div>    \n        \n        <footer>\n            <p>© 2025 无损音乐播放器 | 基于GDStudio音乐API | 仅供学习使用</p>\n        </footer>\n    \n\n    <script>\n        // 全局变量\n        let currentTrack = null;\n        let audioPlayer = new Audio();\n        let searchResults = [];\n        let currentPlayingIndex = -1;\n        let lyrics = [];\n        let currentLyricIndex = -1;\n        \n        // 分页相关变量\n        let currentPage = 1;\n        let totalPages = 1;\n        const resultsPerPage = 10;\n        \n        // DOM元素\n        const searchInput = document.getElementById('search-input');\n        const sourceSelect = document.getElementById('source-select');\n        const searchBtn = document.getElementById('search-btn');\n        const resultsContainer = document.getElementById('results-container');\n        const paginationContainer = document.getElementById('pagination-container');\n        const lyricsContainer = document.getElementById('lyrics-container');\n        const progressBar = document.getElementById('progress-bar');\n        const currentTimeDisplay = document.getElementById('current-time');\n        const totalTimeDisplay = document.getElementById('total-time');\n        const playBtn = document.querySelector('.control-btn.play');\n        const albumArt = document.querySelector('.album-art');\n        const qualityButtons = document.querySelectorAll('.quality-btn');\n        \n        // 简单缓存，避免重复请求\n        const picUrlCache = new Map();\n\n        /**\n         * 解析真实图片 URL\n         * @param {string} source 源（netease/qq/...）\n         * @param {string|number} picId 图片ID\n         * @param {number} size 目标尺寸（300/500）\n         * @returns {Promise<string|null>} 真实图片地址或 null\n         */\n        async function getRealPicUrl(source, picId, size) {\n          if (!source || !picId) return null;\n          const cacheKey = `${source}:${picId}:${size}`;\n          if (picUrlCache.has(cacheKey)) return picUrlCache.get(cacheKey);\n\n          const api = `https://music-api.gdstudio.xyz/api.php?types=pic&source=${encodeURIComponent(source)}&id=${encodeURIComponent(picId)}&size=${encodeURIComponent(size)}`;\n\n          try {\n            const res = await fetch(api);\n            if (!res.ok) throw new Error(`图片API错误: ${res.status}`);\n            const data = await res.json();\n            const url = typeof data === 'string' ? data : data?.url;\n            if (url) {\n              picUrlCache.set(cacheKey, url);\n              return url;\n            }\n            return null;\n          } catch (e) {\n            console.error('解析图片URL失败:', e);\n            return null;\n          }\n        }\n\n        /**\n         * 将容器里的占位符替换为真实图片\n         * @param {HTMLElement} container .album-thumb 或 .album-art 容器\n         * @param {string|null} url 真实图片URL\n         * @param {string} alt alt 文本\n         * @param {'thumb'|'art'} kind 用于判断兜底展示\n         */\n        function setImageInto(container, url, alt, kind) {\n          if (!url) {\n            container.innerHTML = kind === 'thumb'\n              ? '<i class=\"fas fa-music\"></i>'\n              : '<i class=\"fas fa-compact-disc\"></i>';\n            return;\n          }\n          const img = document.createElement('img');\n          img.src = url;\n          img.alt = alt || '';\n          img.referrerPolicy = 'no-referrer'; // 避免某些CDN拒绝\n          container.innerHTML = '';\n          container.appendChild(img);\n        }\n\n        // 事件监听器\n        searchBtn.addEventListener('click', performSearch);\n        searchInput.addEventListener('keypress', (e) => {\n            if (e.key === 'Enter') performSearch();\n        });\n        \n        playBtn.addEventListener('click', togglePlay);\n        audioPlayer.addEventListener('timeupdate', updateProgress);\n        audioPlayer.addEventListener('loadedmetadata', () => {\n            totalTimeDisplay.textContent = formatTime(audioPlayer.duration);\n        });\n        audioPlayer.addEventListener('ended', playNext);\n        \n        progressBar.parentElement.addEventListener('click', (e) => {\n            const progressWidth = progressBar.parentElement.clientWidth;\n            const clickPosition = e.offsetX;\n            const duration = audioPlayer.duration;\n            \n            audioPlayer.currentTime = (clickPosition / progressWidth) * duration;\n        });\n        \n        // 搜索功能\n        async function performSearch() {\n            const keyword = searchInput.value.trim();\n            const source = sourceSelect.value;\n            \n            if (!keyword) {\n                alert('请输入搜索关键词');\n                return;\n            }\n            \n            // 重置分页\n            currentPage = 1;\n            totalPages = 1;\n            \n            // 显示加载状态\n            resultsContainer.innerHTML = `\n                <div class=\"empty-state\">\n                    <i class=\"fas fa-spinner fa-spin\"></i>\n                    <h3>正在搜索...</h3>\n                    <p>请稍候</p>\n                </div>\n            `;\n            paginationContainer.innerHTML = '';\n            \n            try {\n                const response = await fetch(`https://music-api.gdstudio.xyz/api.php?types=search&source=${source}&name=${encodeURIComponent(keyword)}&count=100`);\n                \n                if (!response.ok) {\n                    throw new Error(`API响应错误: ${response.status}`);\n                }\n                \n                const results = await response.json();\n                searchResults = results;\n                \n                if (results.length === 0) {\n                    resultsContainer.innerHTML = `\n                        <div class=\"empty-state\">\n                            <i class=\"fas fa-exclamation-circle\"></i>\n                            <h3>未找到结果</h3>\n                            <p>请尝试其他关键词或更换音乐源</p>\n                        </div>\n                    `;\n                    return;\n                }\n                \n                // 计算总页数\n                totalPages = Math.ceil(results.length / resultsPerPage);\n                \n                // 显示搜索结果\n                displayResults();\n                \n                // 生成分页控件\n                generatePagination();\n                \n            } catch (error) {\n                console.error('搜索时出错:', error);\n                resultsContainer.innerHTML = `\n                    <div class=\"empty-state\">\n                        <i class=\"fas fa-exclamation-triangle\"></i>\n                        <h3>搜索失败</h3>\n                        <p>${error.message || '请稍后再试'}</p>\n                    </div>\n                `;\n            }\n        }\n\n        // 显示搜索结果\n        function displayResults() {\n            resultsContainer.innerHTML = '';\n            \n            // 计算当前页的开始和结束索引\n            const startIndex = (currentPage - 1) * resultsPerPage;\n            const endIndex = Math.min(startIndex + resultsPerPage, searchResults.length);\n            \n            // 获取当前页的结果\n            const pageResults = searchResults.slice(startIndex, endIndex);\n            \n            pageResults.forEach((track, index) => {\n                const resultItem = document.createElement('div');\n                resultItem.className = 'result-item';\n                resultItem.dataset.index = startIndex + index;\n                \n                resultItem.innerHTML = `\n                  <div class=\"album-thumb\">\n                    ${track.pic_id ? `<i class=\"fas fa-spinner fa-spin\"></i>` : `<i class=\"fas fa-music\"></i>`}\n                  </div>\n                  <div class=\"song-info\">\n                    <h3>${track.name}</h3>\n                    <p>${track.artist} - ${track.album}</p>\n                  </div>\n                `;\n\n                // 异步解析真实图片URL并注入\n                if (track.pic_id) {\n                  const thumbContainer = resultItem.querySelector('.album-thumb');\n                  getRealPicUrl(sourceSelect.value, track.pic_id, 300)\n                    .then((url) => setImageInto(thumbContainer, url, track.album, 'thumb'));\n                }\n                \n                resultItem.addEventListener('click', () => {\n                    // 移除之前活跃项的样式\n                    document.querySelectorAll('.result-item').forEach(item => {\n                        item.classList.remove('active');\n                    });\n                    \n                    // 添加当前活跃项的样式\n                    resultItem.classList.add('active');\n                    \n                    // 加载并播放选中的歌曲\n                    loadAndPlayTrack(track, startIndex + index);\n                });\n                \n                resultsContainer.appendChild(resultItem);\n            });\n            \n            // 如果没有结果，显示空状态\n            if (pageResults.length === 0) {\n                resultsContainer.innerHTML = `\n                    <div class=\"empty-state\">\n                        <i class=\"fas fa-exclamation-circle\"></i>\n                        <h3>未找到结果</h3>\n                        <p>请尝试其他关键词或更换音乐源</p>\n                    </div>\n                `;\n            }\n        }\n        \n        // 生成分页控件\n        function generatePagination() {\n            if (totalPages <= 1) {\n                paginationContainer.innerHTML = '';\n                return;\n            }\n            \n            let paginationHTML = '';\n            \n            // 上一页按钮\n            const prevDisabled = currentPage === 1 ? 'disabled' : '';\n            paginationHTML += `\n                <button class=\"pagination-btn ${prevDisabled}\" id=\"prev-page\">\n                    <i class=\"fas fa-chevron-left\"></i>\n                </button>\n            `;\n            \n            // 显示当前页和总页数\n            paginationHTML += `\n                <div class=\"page-info\">\n                    第 <input type=\"number\" min=\"1\" max=\"${totalPages}\" value=\"${currentPage}\" class=\"page-input\" id=\"page-input\"> / ${totalPages} 页\n                </div>\n            `;\n            \n            // 下一页按钮\n            const nextDisabled = currentPage === totalPages ? 'disabled' : '';\n            paginationHTML += `\n                <button class=\"pagination-btn ${nextDisabled}\" id=\"next-page\">\n                    <i class=\"fas fa-chevron-right\"></i>\n                </button>\n            `;\n            \n            // 添加跳转按钮\n            paginationHTML += `\n                <button class=\"page-jump-btn\" id=\"jump-btn\">跳转</button>\n            `;\n            \n            paginationContainer.innerHTML = paginationHTML;\n            \n            // 添加事件监听器\n            document.getElementById('prev-page').addEventListener('click', goToPrevPage);\n            document.getElementById('next-page').addEventListener('click', goToNextPage);\n            document.getElementById('jump-btn').addEventListener('click', jumpToPage);\n            document.getElementById('page-input').addEventListener('keypress', (e) => {\n                if (e.key === 'Enter') jumpToPage();\n            });\n        }\n        \n        // 上一页\n        function goToPrevPage() {\n            if (currentPage > 1) {\n                currentPage--;\n                displayResults();\n                generatePagination();\n                scrollToTop();\n            }\n        }\n        \n        // 下一页\n        function goToNextPage() {\n            if (currentPage < totalPages) {\n                currentPage++;\n                displayResults();\n                generatePagination();\n                scrollToTop();\n            }\n        }\n        \n        // 跳转到指定页\n        function jumpToPage() {\n            const pageInput = document.getElementById('page-input');\n            let pageNum = parseInt(pageInput.value);\n            \n            if (isNaN(pageNum)) {\n                pageNum = 1;\n            }\n            \n            if (pageNum < 1) {\n                pageNum = 1;\n            } else if (pageNum > totalPages) {\n                pageNum = totalPages;\n            }\n            \n            currentPage = pageNum;\n            displayResults();\n            generatePagination();\n            scrollToTop();\n        }\n        \n        // 滚动到顶部\n        function scrollToTop() {\n            resultsContainer.scrollTo({\n                top: 0,\n                behavior: 'smooth'\n            });\n        }\n\n        // 加载并播放歌曲\n        async function loadAndPlayTrack(track, index) {\n            currentPlayingIndex = index;\n            currentTrack = track;\n            \n            // 更新专辑封面\n            albumArt.innerHTML = `<div class=\"empty-state\"><i class=\"fas fa-spinner fa-spin\"></i></div>`;\n\n            if (track.pic_id) {\n              const url = await getRealPicUrl(sourceSelect.value, track.pic_id, 500);\n              setImageInto(albumArt, url, track.album, 'art');\n            } else {\n              setImageInto(albumArt, null, track.album, 'art');\n            }\n            \n            // 显示加载状态\n            lyricsContainer.innerHTML = `\n                <div class=\"empty-state\">\n                    <i class=\"fas fa-spinner fa-spin\"></i>\n                    <h3>加载中...</h3>\n                    <p>正在获取歌曲和歌词</p>\n                </div>\n            `;\n            \n            try {\n                // 获取歌曲URL\n                const quality = document.querySelector('.quality-btn.active').dataset.quality;\n                const urlResponse = await fetch(`https://music-api.gdstudio.xyz/api.php?types=url&source=${sourceSelect.value}&id=${track.id}&br=${quality}`);\n                \n                if (!urlResponse.ok) {\n                    throw new Error('获取歌曲URL失败');\n                }\n                \n                const urlData = await urlResponse.json();\n                \n                // 获取歌词\n                const lyricId = track.lyric_id || track.id;\n                const lyricResponse = await fetch(`https://music-api.gdstudio.xyz/api.php?types=lyric&source=${sourceSelect.value}&id=${lyricId}`);\n                \n                if (!lyricResponse.ok) {\n                    throw new Error('获取歌词失败');\n                }\n                \n                const lyricData = await lyricResponse.json();\n                \n                // 设置音频源\n                audioPlayer.src = urlData.url;\n                audioPlayer.load();\n                \n                // 播放音频\n                playBtn.querySelector('i').className = 'fas fa-pause';\n                audioPlayer.play().catch(error => {\n                    console.error('播放失败:', error);\n                    alert('播放失败，可能是当前音源无效');\n                });\n                \n                // 处理歌词\n                processLyrics(lyricData);\n                \n            } catch (error) {\n                console.error('加载歌曲时出错:', error);\n                lyricsContainer.innerHTML = `\n                    <div class=\"empty-state\">\n                        <i class=\"fas fa-exclamation-triangle\"></i>\n                        <h3>加载失败</h3>\n                        <p>${error.message || '请稍后再试'}</p>\n                    </div>\n                `;\n            }\n        }\n        \n        // 处理歌词\n        function processLyrics(lyricData) {\n            lyrics = [];\n            currentLyricIndex = -1;\n            \n            // 使用原文歌词或翻译歌词\n            const rawLyrics = lyricData.tlyric || lyricData.lyric || '';\n            \n            // 解析LRC歌词\n            const lines = rawLyrics.split('\\n');\n            lines.forEach(line => {\n                const timeMatch = line.match(/\\[(\\d+):(\\d+(?:\\.\\d+)?)\\]/);\n                if (timeMatch) {\n                    const minutes = parseInt(timeMatch[1]);\n                    const seconds = parseFloat(timeMatch[2]);\n                    const time = minutes * 60 + seconds;\n                    \n                    const text = line.replace(timeMatch[0], '').trim();\n                    if (text) {\n                        lyrics.push({ time, text });\n                    }\n                }\n            });\n            \n            // 按时间排序\n            lyrics.sort((a, b) => a.time - b.time);\n            \n            // 显示歌词\n            displayLyrics();\n        }\n        \n        // 显示歌词\n        function displayLyrics() {\n            if (lyrics.length === 0) {\n                lyricsContainer.innerHTML = '<p>暂无歌词</p>';\n                return;\n            }\n            \n            lyricsContainer.innerHTML = '';\n            lyrics.forEach((line, index) => {\n                const p = document.createElement('p');\n                p.dataset.index = index;\n                p.textContent = line.text;\n                lyricsContainer.appendChild(p);\n            });\n        }\n        \n        // 更新歌词高亮\n        function updateLyricsHighlight(time) {\n            // 清除之前的高亮\n            document.querySelectorAll('#lyrics-container p').forEach(p => {\n                p.classList.remove('active');\n            });\n            \n            // 找到当前时间对应的歌词行\n            let activeIndex = -1;\n            for (let i = 0; i < lyrics.length; i++) {\n                if (time >= lyrics[i].time) {\n                    activeIndex = i;\n                } else {\n                    break;\n                }\n            }\n            \n            if (activeIndex !== -1 && activeIndex !== currentLyricIndex) {\n                currentLyricIndex = activeIndex;\n                const activeLine = document.querySelector(`#lyrics-container p[data-index=\"${activeIndex}\"]`);\n                \n                if (activeLine) {\n                    activeLine.classList.add('active');\n                    \n                    // 滚动到当前歌词行\n                    activeLine.scrollIntoView({\n                        behavior: 'smooth',\n                        block: 'center'\n                    });\n                }\n            }\n        }\n        \n        // 播放/暂停切换\n        function togglePlay() {\n            if (audioPlayer.paused || audioPlayer.ended) {\n                if (audioPlayer.src) {\n                    audioPlayer.play().catch(error => {\n                        console.error('播放失败:', error);\n                        alert('播放失败，可能是当前音源无效');\n                    });\n                    playBtn.querySelector('i').className = 'fas fa-pause';\n                } else if (searchResults.length > 0) {\n                    // 如果没有正在播放的歌曲，但搜索结果存在，播放第一首\n                    document.querySelector('.result-item').click();\n                }\n            } else {\n                audioPlayer.pause();\n                playBtn.querySelector('i').className = 'fas fa-play';\n            }\n        }\n        \n        // 播放下一首\n        function playNext() {\n            if (searchResults.length === 0) return;\n            \n            currentPlayingIndex = (currentPlayingIndex + 1) % searchResults.length;\n            const nextItem = document.querySelector(`.result-item[data-index=\"${currentPlayingIndex}\"]`);\n            \n            if (nextItem) {\n                nextItem.click();\n            }\n        }\n        \n        // 更新进度条\n        function updateProgress() {\n            const currentTime = audioPlayer.currentTime;\n            const duration = audioPlayer.duration || 1; // 避免NaN\n            \n            const progressPercent = (currentTime / duration) * 100;\n            progressBar.style.width = `${progressPercent}%`;\n            \n            currentTimeDisplay.textContent = formatTime(currentTime);\n            \n            // 更新歌词\n            updateLyricsHighlight(currentTime);\n        }\n        \n        // 格式化时间 (秒 -> mm:ss)\n        function formatTime(seconds) {\n            if (isNaN(seconds)) return '0:00';\n            \n            const mins = Math.floor(seconds / 60);\n            const secs = Math.floor(seconds % 60);\n            return `${mins}:${secs < 10 ? '0' : ''}${secs}`;\n        }\n        \n        // 音质选择\n        qualityButtons.forEach(button => {\n            button.addEventListener('click', () => {\n                // 更新UI\n                qualityButtons.forEach(btn => btn.classList.remove('active'));\n                button.classList.add('active');\n                \n                // 如果当前有歌曲在播放，重新加载该歌曲\n                if (currentTrack && !audioPlayer.paused) {\n                    loadAndPlayTrack(currentTrack, currentPlayingIndex);\n                }\n            });\n        });\n        \n        // 默认加载一些热门歌曲\n        window.addEventListener('DOMContentLoaded', () => {\n            searchInput.value = '庄心妍';\n            setTimeout(performSearch, 500);\n        });\n    </script>\n","content_text":"全能音乐搜索播放器\n\n\n\n无损音乐搜索播放器\n\n支持多个音乐源，高音质播放，歌词显示和专辑封面浏览\n\n网易云音乐✔ JOOX音乐✔ 酷我音乐✔ B站(不稳定)✔ Tidal✔ Apple Music(中转)✔ QQ音乐✘ Spotify✘ 酷狗音乐✘ 搜索\n\n\n搜索结果\n\n\n搜索音乐\n\n输入关键词并选择音乐源后点击搜索按钮\n\n\n\n\n专辑封面\n\n\n无损音质\n高品质\n中等音质\n普通音质\n\n\n0:00 0:00\n\n\n歌词\n\n\n歌词显示区域\n\n选择歌曲后，歌词将显示在这里\n\n© 2025 无损音乐播放器 | 基于GDStudio音乐API | 仅供学习使用","date_published":"2025-08-09T13:34:36.843Z","_microfeed":{"web_url":"https://cms.dbdraws.dpdns.org/i/在线音乐-lkhoTm8kFvy/","json_url":"https://cms.dbdraws.dpdns.org/i/lkhoTm8kFvy/json/","rss_url":"https://cms.dbdraws.dpdns.org/i/lkhoTm8kFvy/rss/","guid":"lkhoTm8kFvy","status":"published","itunes:episodeType":"full","date_published_short":"Sat Aug 09 2025","date_published_ms":1754746476843}}],"_microfeed":{"microfeed_version":"0.1.5","base_url":"https://cms.dbdraws.dpdns.org","categories":[],"subscribe_methods":[{"name":"JSON","type":"json","url":"https://cms.dbdraws.dpdns.org/json/","image":"https://cms.dbdraws.dpdns.org/assets/brands/subscribe/json.png","enabled":true,"editable":false,"id":"p0wHIR3D42R"},{"name":"友情链接","type":"google podcasts","url":"https://blog.dbdraws.dpdns.org/friends","image":"https://cms.dbdraws.dpdns.org/assets/brands/subscribe/google.png","enabled":true,"editable":true,"id":"BRWdIXxcFlR"}],"description_text":"这是一款轻量级的内容管理系统（CMS），可自行托管于Cloudflare平台。通过microfeed，您能够便捷地发布多种形式的内容——包括音频、视频、照片、文档、博客文章及外部链接，并以网页、RSS订阅和JSON格式输出信息流。","copyright":"Copyright © DBD制作组.2026","itunes:type":"episodic","items_sort_order":"newest_first"}}