文章详情

返回首页

CF搭建mp3音乐都放

分享文章 作者: Ws01 创建时间: 2025-11-24 📝 字数: 24,263 字 👁️ 阅读: 12 次
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { const url = new URL(request.url); // 登录逻辑 if (url.pathname === '/login' && request.method === 'POST') { const formData = await request.formData(); const password = formData.get('password'); if (password === ADMIN_PASSWORD) { // 登录成功,设置 Cookie return new Response('', { status: 302, headers: { 'Set-Cookie': `auth=1; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=86400`, 'Location': '/' } }); } else { return new Response(renderLoginPage('密码错误,请重试!'), { headers: { 'Content-Type': 'text/html;charset=utf-8' } }); } } // 退出逻辑 if (url.pathname === '/logout') { return new Response('', { status: 302, headers: { 'Set-Cookie': `auth=; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=0`, 'Location': '/' } }); } // 检查是否已登录 const cookie = request.headers.get('Cookie') || ''; if (!cookie.includes('auth=1')) { return new Response(renderLoginPage(), { headers: { 'Content-Type': 'text/html;charset=utf-8' } }); } // 已登录 -> 播放页面 const videoList1 = await fetch('https://img.boke.us.to/config/9527qita/mp3-list1.txt'); const videoList2 = await fetch('https://img.boke.us.to/config/9527qita/mp3-list2.txt'); const videoList3 = await fetch('https://img.boke.us.to/config/9527qita/mp3-list3.txt'); const videoList4 = await fetch('https://img.boke.us.to/config/9527qita/mp3-list4.txt'); const links1 = (await videoList1.text()).split('\n').filter(line => line.trim() !== ''); const links2 = (await videoList2.text()).split('\n').filter(line => line.trim() !== ''); const links3 = (await videoList3.text()).split('\n').filter(line => line.trim() !== ''); const links4 = (await videoList4.text()).split('\n').filter(line => line.trim() !== ''); const links = [...links1, ...links2, ...links3, ...links4]; if (links.length === 0) { return new Response('链接文件为空或未找到!', { status: 500 }); } const randomLink = links[0]; const htmlContent = ` <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>自动随机播放 MP3 音频</title> <style> * { box-sizing: border-box; } body { text-align: center; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif; background:#f0f0f0; margin:0; padding: 0; min-height: 100vh; } .sites { width:620px; background:#EBEBEB; border:1px solid rgba(0,0,0,.06); margin:15px auto; padding:0px; color: white; border-radius: 8px; /* 四角弧度,一般高为5,50为圆*/ } .sites01 { width:820px; background:; border:2px solid auto; margin:15px auto; padding:0px; } .sites dl { height:36px; line-height:36px; display:block; margin:0; } .sites dl.alt { background:#c5dff6; border-top:1px solid #ffffff; border-bottom:1px solid #ffffff; } .sites dl.alt2 { background:#dcecfa; border-top:1px solid #ffffff; border-bottom:1px solid #ffffff; } .sites dt,.sites dd { text-align:center; display:block; float:left; } .sites dt { width:60px; } .sites dd { width:90px; margin:0; } header { display:flex; justify-content:space-between; align-items:center; background:#222; color:#fff; padding: 8px 15px; position: sticky; top: 0; z-index: 100; height: 80px; } header h2 { margin:0; font-size: 18px; font-weight: 500; } header a { color:#fff; text-decoration:none; background:#c00; padding: 6px 10px; border-radius:4px; font-size: 16px; white-space: nowrap; } header a:hover { background:#900; } .main-container { padding: 15px; max-width: 100%; } .audio-container { background:#DEDEDE; width: 100%; max-width: 610px; height: 65px; margin: 15px auto; border:1px solid #D4D4D4; border-radius:4px; display: flex; align-items: center; justify-content: center; } .audio-container audio { width: 100%; height: 100%; } .controls { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 15px 0; } .control-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 8px 0; } button { margin: 0; padding: 12px 16px; border-radius: 8px; border:none; background:black; color:white; cursor:pointer; font-size: 16px; min-width: 75px; min-height: 45px; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; } button:hover { background:#333; } button.active { background:#4a90e2; } button.active:hover { background:#357ABD; } .playlist { display:none; max-height: 282px; overflow-y:auto; width: 100%; max-width: 610px; margin: 15px auto; background:#F2F2F2; border:1px solid #ebebeb; border-radius:8px; list-style:none; padding:0; text-align:left; color:#404040; } .playlist li { padding: 12px 15px; cursor:pointer; text-decoration:underline; border-bottom: 1px solid #ddd; font-size: 16px; line-height: 1.4; min-height: 44px; display: flex; align-items: center; } .playlist li:last-child { border-bottom: none; } .playlist li.playing { color:red; font-weight:bold; background: #fff3cd; } @media (max-width: 480px) { .sites { width:390px; } .audio-container { width: 100%; max-width: 385px; } .playlist { max-height: 262px; width: 100%; max-width: 385px; } header { padding: 6px 10px; } header h2 { font-size: 16px; } header a { padding: 4px 8px; font-size: 14px; } .main-container { padding: 10px; } .audio-container { height: 50px; margin: 10px auto; } button { padding: 10px 12px; font-size: 15px; min-width: 55px; min-height: 42px; } .playlist li { padding: 10px 12px; font-size: 13px; min-height: 40px; } } </style> </head> <body> </div> <div class="sites"> <header> <h2>自动随机播放 MP3 音频</h2> <a href="/logout">退出</a> </header> <div class="main-container"> <div class="audio-container"> <audio id="audioPlayer" controls> <source src="${randomLink}" type="audio/mpeg"> </audio> </div> <div class="controls"> <div class="control-row"> <button id="prevBtn" title="上一首">&#10074;&#9664;</button> <button id="playPauseBtn" title="播放/暂停">▶</button> <button id="nextBtn" title="下一首">&#9654;&#10074;</button> </div> <div class="control-row"> <button id="shuffleBtn" title="随机播放">🔀</button> <button id="repeatBtn" title="单曲循环">🔁</button> </div> </div> <div class="control-row"> <button id="list1Btn">列表1</button> <button id="list2Btn">列表2</button> <button id="list3Btn">列表3</button> <button id="list4Btn">列表4</button> <button id="togglePlaylistBtn">综合列表</button> </div> </div> <ul class="playlist" id="playlist"> ${links.map((line, i) => { const [url, title] = line.split('|'); return `<li data-src="${url}">${i+1}. ${title}</li>`; }).join('')} </ul> </div> <script> const audioLinks1 = ${JSON.stringify(links1)}; const audioLinks2 = ${JSON.stringify(links2)}; const audioLinks3 = ${JSON.stringify(links3)}; const audioLinks4 = ${JSON.stringify(links4)}; const audioLinks = ${JSON.stringify(links)}; const audioPlayer = document.getElementById('audioPlayer'); const playPauseBtn = document.getElementById('playPauseBtn'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const playlist = document.getElementById('playlist'); const list1Btn = document.getElementById('list1Btn'); const list2Btn = document.getElementById('list2Btn'); const list3Btn = document.getElementById('list3Btn'); const list4Btn = document.getElementById('list4Btn'); const togglePlaylistBtn = document.getElementById('togglePlaylistBtn'); const shuffleBtn = document.getElementById('shuffleBtn'); const repeatBtn = document.getElementById('repeatBtn'); let currentPlaylist = 'combined'; // 'list1', 'list2', 'list3', 'list4', 'combined' let currentAudioIndex = 0; let playedIndexes = []; let playMode = 'normal'; // 'normal', 'shuffle', 'repeat' function getCurrentPlaylist() { switch(currentPlaylist) { case 'list1': return audioLinks1; case 'list2': return audioLinks2; case 'list3': return audioLinks3; case 'list4': return audioLinks4; case 'combined': return audioLinks; default: return audioLinks; } } function updatePlaylistDisplay() { const currentLinks = getCurrentPlaylist(); playlist.innerHTML = currentLinks.map((line, i) => { const [url, title] = line.split('|'); return '<li data-src="' + url + '">' + (i+1) + '. ' + title + '</li>'; }).join(''); updatePlaylistStyle(currentAudioIndex); } function updatePlaylistStyle(i){ document.querySelectorAll('#playlist li').forEach((el, idx)=>{ el.classList.toggle('playing', idx===i); }); } function updateButtonStates() { shuffleBtn.classList.toggle('active', playMode === 'shuffle'); repeatBtn.classList.toggle('active', playMode === 'repeat'); list1Btn.classList.toggle('active', currentPlaylist === 'list1'); list2Btn.classList.toggle('active', currentPlaylist === 'list2'); list3Btn.classList.toggle('active', currentPlaylist === 'list3'); list4Btn.classList.toggle('active', currentPlaylist === 'list4'); togglePlaylistBtn.classList.toggle('active', currentPlaylist === 'combined'); } function getNextIndex() { const currentLinks = getCurrentPlaylist(); if (playMode === 'shuffle') { const unplayed = currentLinks.map((_, i) => i).filter(i => !playedIndexes.includes(i)); if (unplayed.length === 0) { playedIndexes = []; return Math.floor(Math.random() * currentLinks.length); } return unplayed[Math.floor(Math.random() * unplayed.length)]; } else if (playMode === 'repeat') { return currentAudioIndex; // 单曲循环,返回当前索引 } else { return (currentAudioIndex + 1) % currentLinks.length; // 正常顺序播放 } } function getPrevIndex() { const currentLinks = getCurrentPlaylist(); if (playMode === 'shuffle') { const unplayed = currentLinks.map((_, i) => i).filter(i => !playedIndexes.includes(i)); if (unplayed.length === 0) { playedIndexes = []; return Math.floor(Math.random() * currentLinks.length); } return unplayed[Math.floor(Math.random() * unplayed.length)]; } else if (playMode === 'repeat') { return currentAudioIndex; // 单曲循环,返回当前索引 } else { return (currentAudioIndex - 1 + currentLinks.length) % currentLinks.length; // 正常顺序播放 } } function playAudio(i){ const currentLinks = getCurrentPlaylist(); const [url] = currentLinks[i].split('|'); audioPlayer.src = url; audioPlayer.play(); currentAudioIndex = i; updatePlaylistStyle(i); if (playMode === 'shuffle' && !playedIndexes.includes(i)) { playedIndexes.push(i); } } document.addEventListener('DOMContentLoaded', ()=>{ updatePlaylistDisplay(); playAudio(0); updateButtonStates(); }); playPauseBtn.onclick=()=>{ if(audioPlayer.paused){ audioPlayer.play(); playPauseBtn.textContent='⏸'; } else { audioPlayer.pause(); playPauseBtn.textContent='▶'; } }; prevBtn.onclick=()=>{ const prevIndex = getPrevIndex(); playAudio(prevIndex); }; nextBtn.onclick=()=>{ const nextIndex = getNextIndex(); playAudio(nextIndex); }; audioPlayer.addEventListener('ended', ()=>{ if (playMode === 'repeat') { // 单曲循环模式,重新播放当前歌曲 playAudio(currentAudioIndex); } else { // 正常播放或随机播放模式 const nextIndex = getNextIndex(); playAudio(nextIndex); } }); function switchPlaylist(playlistType) { currentPlaylist = playlistType; currentAudioIndex = 0; playedIndexes = []; updatePlaylistDisplay(); updateButtonStates(); playAudio(0); // 重置所有播放列表按钮的文本 list1Btn.textContent = '列表1'; list2Btn.textContent = '列表2'; list3Btn.textContent = '列表3'; list4Btn.textContent = '列表4'; togglePlaylistBtn.textContent = '综合列表'; } list1Btn.onclick=()=>{ if (currentPlaylist === 'list1') { playlist.style.display= playlist.style.display==='none' ? 'block':'none'; list1Btn.textContent= playlist.style.display==='none' ? '列表1':'隐藏列表'; } else { switchPlaylist('list1'); playlist.style.display = 'block'; list1Btn.textContent = '隐藏列表'; } }; list2Btn.onclick=()=>{ if (currentPlaylist === 'list2') { playlist.style.display= playlist.style.display==='none' ? 'block':'none'; list2Btn.textContent= playlist.style.display==='none' ? '列表2':'隐藏列表'; } else { switchPlaylist('list2'); playlist.style.display = 'block'; list2Btn.textContent = '隐藏列表'; } }; list3Btn.onclick=()=>{ if (currentPlaylist === 'list3') { playlist.style.display= playlist.style.display==='none' ? 'block':'none'; list3Btn.textContent= playlist.style.display==='none' ? '列表3':'隐藏列表'; } else { switchPlaylist('list3'); playlist.style.display = 'block'; list3Btn.textContent = '隐藏列表'; } }; list4Btn.onclick=()=>{ if (currentPlaylist === 'list4') { playlist.style.display= playlist.style.display==='none' ? 'block':'none'; list4Btn.textContent= playlist.style.display==='none' ? '列表4':'隐藏列表'; } else { switchPlaylist('list4'); playlist.style.display = 'block'; list4Btn.textContent = '隐藏列表'; } }; togglePlaylistBtn.onclick=()=>{ if (currentPlaylist === 'combined') { playlist.style.display= playlist.style.display==='none' ? 'block':'none'; togglePlaylistBtn.textContent= playlist.style.display==='none' ? '综合列表':'隐藏列表'; } else { switchPlaylist('combined'); } }; shuffleBtn.onclick=()=>{ if (playMode === 'shuffle') { playMode = 'normal'; } else { playMode = 'shuffle'; playedIndexes = [currentAudioIndex]; // 将当前歌曲标记为已播放 } updateButtonStates(); }; repeatBtn.onclick=()=>{ if (playMode === 'repeat') { playMode = 'normal'; } else { playMode = 'repeat'; } updateButtonStates(); }; playlist.onclick=(e)=>{ if(e.target.tagName==='LI'){ const url=e.target.dataset.src; const currentLinks = getCurrentPlaylist(); const newIndex = currentLinks.findIndex(l=>l.split('|')[0]===url); playAudio(newIndex); } }; </script> </body> </html>`; return new Response(htmlContent, { headers: { 'Content-Type': 'text/html' } }); } // 登录页面 function renderLoginPage(msg='') { return ` <!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>登录</title> <style> * { box-sizing: border-box; } body { display:flex; justify-content:center; align-items:center; min-height:100vh; margin:0; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif; background: linear-gradient(135deg, #74ebd5 0%, #9face6 100%); } .login-box { background:#fff; padding: 30px 25px; border-radius:12px; box-shadow:0 8px 20px rgba(0,0,0,.2); width: 100%; max-width: 350px; text-align:center; animation: fadeIn 0.6s ease; } .login-box h2 { margin-bottom:20px; color:#333; font-size:20px; font-weight: 500; } .msg { color:red; margin-bottom:15px; font-size:14px; line-height: 1.4; } .password-wrapper { position: relative; width: 100%; margin-bottom: 20px; } .password-wrapper input { width:100%; padding: 14px 45px 14px 14px; border:1px solid #ccc; border-radius:8px; font-size:16px; transition: all 0.3s ease; box-sizing: border-box; background: #fafafa; } .password-wrapper input:focus { border-color:#4a90e2; outline:none; box-shadow:0 0 6px rgba(74,144,226,.5); background: #fff; } .toggle-password { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); cursor: pointer; font-size: 20px; color: #666; user-select: none; padding: 4px; min-width: 32px; min-height: 32px; display: flex; align-items: center; justify-content: center; } button { width:100%; padding: 14px; border:none; border-radius:8px; font-size:16px; background:linear-gradient(135deg, #4a90e2, #357ABD); color:white; cursor:pointer; transition: all 0.3s ease; font-weight: 500; min-height: 48px; } button:hover { background:linear-gradient(135deg, #357ABD, #2E5C9A); transform: translateY(-1px); } button:active { transform: translateY(0); } @keyframes fadeIn { from { opacity:0; transform:translateY(-20px); } to { opacity:1; transform:translateY(0); } } @media (max-width: 480px) { body { padding: 15px; } .login-box { padding: 25px 20px; max-width: 100%; } .login-box h2 { font-size: 18px; margin-bottom: 15px; } .password-wrapper input { padding: 12px 40px 12px 12px; font-size: 16px; } .toggle-password { font-size: 18px; right: 10px; } button { padding: 12px; font-size: 15px; } } </style> </head><body> <div class="login-box"> <h2>🔒 请输入密码</h2> ${msg ? `<div class="msg">${msg}</div>` : ''} <form method="POST" action="/login"> <div class="password-wrapper"> <input type="password" id="password" name="password" placeholder="输入登录密码" autocomplete="current-password"> <span class="toggle-password" onclick="togglePassword()">👁️</span> </div> <button type="submit">登录</button> </form> </div> <script> function togglePassword() { const pwd = document.getElementById('password'); const toggle = document.querySelector('.toggle-password'); if (pwd.type === 'password') { pwd.type = 'text'; toggle.textContent = '🙈'; } else { pwd.type = 'password'; toggle.textContent = '👁️'; } } // 自动聚焦到密码输入框 document.addEventListener('DOMContentLoaded', function() { document.getElementById('password').focus(); }); </script> </body></html>`; }