Spaces:
Paused
Paused
| <html lang="zh-Hant"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>音訊下載器 (YouTube & TikTok)</title> | |
| <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet" /> | |
| <style> | |
| *, *::before, *::after { | |
| box-sizing: border-box; | |
| } | |
| body { | |
| margin: 0; | |
| font-family: 'Poppins', sans-serif; | |
| background: linear-gradient(135deg, #007f7f, #00c2c7); | |
| color: #e0f7f7; | |
| min-height: 100vh; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| padding: 3rem 2rem; | |
| } | |
| .container { | |
| background: rgba(15, 40, 45, 0.95); | |
| border-radius: 30px; | |
| padding: 3rem 4rem; | |
| max-width: 640px; | |
| width: 100%; | |
| box-shadow: | |
| 6px 6px 15px rgba(0, 160, 160, 0.25), | |
| -6px -6px 15px rgba(0, 255, 255, 0.25); | |
| text-align: center; | |
| backdrop-filter: blur(15px); | |
| border: 1.5px solid rgba(0, 220, 220, 0.3); | |
| transition: box-shadow 0.3s ease; | |
| } | |
| .container:hover { | |
| box-shadow: | |
| 10px 10px 25px rgba(0, 220, 220, 0.5), | |
| -10px -10px 25px rgba(0, 255, 255, 0.5); | |
| } | |
| h1 { | |
| font-weight: 700; | |
| font-size: 3rem; | |
| margin-bottom: 1rem; | |
| color: #64fff9; | |
| text-shadow: 0 0 20px #64fff9cc; | |
| letter-spacing: 1.2px; | |
| } | |
| p { | |
| margin-bottom: 2rem; | |
| font-size: 1.3rem; | |
| color: #a9f0f0; | |
| letter-spacing: 0.5px; | |
| } | |
| input, select { | |
| width: 100%; | |
| padding: 1.2rem 1.5rem; | |
| margin-bottom: 1.8rem; | |
| border-radius: 18px; | |
| border: none; | |
| font-size: 1.25rem; | |
| background: #004d4d; | |
| color: #ccffff; | |
| box-shadow: | |
| inset 6px 6px 10px #003535, | |
| inset -6px -6px 10px #006767; | |
| transition: | |
| background-color 0.3s ease, | |
| box-shadow 0.3s ease, | |
| color 0.3s ease; | |
| } | |
| input::placeholder { | |
| color: #7fd9d9; | |
| font-style: italic; | |
| } | |
| input:focus, select:focus { | |
| background: #007373; | |
| outline: none; | |
| box-shadow: | |
| 0 0 12px 3px #00fff7aa, | |
| inset 6px 6px 12px #005959, | |
| inset -6px -6px 12px #009999; | |
| color: #e0f7f7; | |
| } | |
| button { | |
| width: 100%; | |
| background: linear-gradient(90deg, #00f3ff, #009e9e); | |
| border: none; | |
| padding: 1.3rem; | |
| border-radius: 25px; | |
| font-weight: 700; | |
| font-size: 1.5rem; | |
| color: #003636; | |
| cursor: pointer; | |
| box-shadow: | |
| 0 0 20px #00f3ffaa, | |
| inset 0 -6px 12px #006767aa; | |
| transition: | |
| background 0.3s ease, | |
| box-shadow 0.3s ease, | |
| color 0.3s ease; | |
| } | |
| button:hover:not(:disabled) { | |
| background: linear-gradient(90deg, #00fff7, #007d7d); | |
| color: #e0f7f7; | |
| box-shadow: | |
| 0 0 30px #00fff7cc, | |
| inset 0 -6px 15px #008080cc; | |
| } | |
| button:disabled { | |
| background: #004d4d; | |
| color: #7fbfbf; | |
| cursor: not-allowed; | |
| box-shadow: none; | |
| } | |
| .result { | |
| margin-top: 2.8rem; | |
| font-size: 1.2rem; | |
| color: #64fff9; | |
| min-height: 4em; | |
| word-break: break-word; | |
| text-align: left; | |
| } | |
| ul { | |
| list-style: none; | |
| padding-left: 0; | |
| margin-top: 1.4rem; | |
| } | |
| li { | |
| margin: 0.6rem 0; | |
| } | |
| a { | |
| color: #40e0d0; | |
| font-weight: 600; | |
| text-decoration: none; | |
| transition: color 0.3s ease; | |
| font-size: 1.15rem; | |
| } | |
| a:hover { | |
| color: #b2ffff; | |
| text-decoration: underline; | |
| } | |
| @media (max-width: 700px) { | |
| .container { | |
| padding: 2rem 2.5rem; | |
| max-width: 100%; | |
| } | |
| h1 { | |
| font-size: 2.4rem; | |
| } | |
| p, input, select, button { | |
| font-size: 1.1rem; | |
| } | |
| a { | |
| font-size: 1rem; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>🎧 YouTube & TikTok 音訊下載器</h1> | |
| <p>貼上 YouTube 或 TikTok 連結,選擇格式與品質即可下載</p> | |
| <input id="video-url" type="text" placeholder="例如:https://www.youtube.com/watch?v=xxxx 或 https://www.tiktok.com/@user/video/xxxx" /> | |
| <select id="format"> | |
| <option value="mp3">MP3 音訊</option> | |
| <option value="m4a">M4A 音訊</option> | |
| </select> | |
| <select id="audio-quality"> | |
| <option value="128">128 kbps</option> | |
| <option value="192" selected>192 kbps</option> | |
| <option value="256">256 kbps</option> | |
| <option value="320">320 kbps</option> | |
| </select> | |
| <button id="submitBtn" onclick="submitURL()">開始下載</button> | |
| <div class="result" id="result"></div> | |
| </div> | |
| <script> | |
| async function submitURL() { | |
| const url = document.getElementById("video-url").value.trim(); | |
| const format = document.getElementById("format").value; | |
| const button = document.getElementById("submitBtn"); | |
| const result = document.getElementById("result"); | |
| const audioQuality = document.getElementById("audio-quality").value; | |
| if (!url) { | |
| result.innerHTML = `<p style="color:#ff6b6b;">請先輸入有效的影片連結!</p>`; | |
| return; | |
| } | |
| // Basic URL validation for YouTube or TikTok | |
| if (!url.match(/(youtube\.com|youtu\.be|tiktok\.com)/)) { | |
| result.innerHTML = `<p style="color:#ff6b6b;">目前只支援 YouTube 和 TikTok 影片連結!</p>`; | |
| return; | |
| } | |
| result.textContent = "⏳ 處理中..."; | |
| button.disabled = true; | |
| try { | |
| const res = await fetch("/service", { | |
| method: "POST", | |
| headers: { "Content-Type": "application/json" }, | |
| body: JSON.stringify({ | |
| input: url, | |
| format: format, | |
| quality: audioQuality, | |
| }), | |
| }); | |
| const data = await res.json(); | |
| button.disabled = false; | |
| if (data.status === "success") { | |
| let links = ""; | |
| for (const key in data.download_links) { | |
| links += `<li><a href="${data.download_links[key]}" download>📥 下載 ${key.toUpperCase()}</a></li>`; | |
| } | |
| result.innerHTML = `<p style="color:#a0ffe8;">✅ ${data.message}</p><ul>${links}</ul>`; | |
| } else { | |
| result.innerHTML = `<p style="color:#ff6b6b;">❌ ${data.message}</p>`; | |
| } | |
| } catch (error) { | |
| console.error(error); | |
| button.disabled = false; | |
| result.innerHTML = `<p style="color:#ff6b6b;">🚨 發生錯誤,請稍後再試。</p>`; | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |