From 3ae05f27da554efa1a78b8cfd48fc4183c3f34cb Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Sun, 23 Nov 2025 01:20:31 +0800 Subject: [PATCH] [+] Step-by-step buttons --- src/lib/server/songs.ts | 18 ++++++++-------- src/routes/song/[id]/+page.svelte | 34 ++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/lib/server/songs.ts b/src/lib/server/songs.ts index d41124c..fbc00de 100644 --- a/src/lib/server/songs.ts +++ b/src/lib/server/songs.ts @@ -140,7 +140,7 @@ export const getSongUrl = async (id: number | string) => { // ///////////////////////////////////////////////////////////////////////////// // API for Song Preparation -export interface ProgressItem { task: string, progress: number } +export interface ProgressItem { id: string, task: string, progress: number } export interface SongProcessState { items: ProgressItem[], status: 'running' | 'done' | 'error' } const songProcessingStatus = new Map() @@ -152,20 +152,20 @@ export const prepareSong = async (songId: number) => { const state: SongProcessState = { items: [], status: 'running' } songProcessingStatus.set(songId, state) - const addTask = (task: string) => ({ task, progress: 0 }).also(it => state.items.push(it)) + const addTask = (id: string, task: string) => ({ id, task, progress: 0 }).also(it => state.items.push(it)) try { // 1. Get Lyrics - const taskLyrics = addTask('从网易云获取歌词') + const taskLyrics = addTask('lyrics', '从网易云获取歌词') const raw = await getLyricsRaw(songId) taskLyrics.progress = 1 if (raw.lang !== 'jpn') { - addTask('错误: 不是日语歌曲').progress = -1 + addTask('error', '错误: 不是日语歌曲').progress = -1 return state.status = 'error' } // 2. AI Process - const taskAI = addTask('AI 标注歌词读音') + const taskAI = addTask('ai', 'AI 标注歌词读音') // Check cache if (await checkLyricsProcessed(songId)) taskAI.progress = 1 @@ -176,12 +176,12 @@ export const prepareSong = async (songId: number) => { } // 3. Audio - const taskAudio = addTask('从网易云获取音乐') + const taskAudio = addTask('music', '从网易云获取音乐') await getSongUrl(songId) taskAudio.progress = 1 // 4. Source Separation - const taskSeparation = addTask('AI 人声分离') + const taskSeparation = addTask('separation', 'AI 人声分离') const inputPath = path.join(CACHE_DIR, `${songId}/exhigh.mp3`) const outputDir = path.join(CACHE_DIR, `${songId}`) @@ -189,14 +189,14 @@ export const prepareSong = async (songId: number) => { await separateSong(inputPath, outputDir) taskSeparation.progress = 1 } catch (e: any) { - addTask(`错误: ${e.message}`).progress = -1 + addTask('error', `错误: ${e.message}`).progress = -1 // Don't fail the whole process, just this step } state.status = 'done' } catch (e) { - addTask(`错误: ${eToString(e)}`).progress = -1 + addTask('error', `错误: ${eToString(e)}`).progress = -1 state.status = 'error' } } diff --git a/src/routes/song/[id]/+page.svelte b/src/routes/song/[id]/+page.svelte index 9ad45f0..be9b7ed 100644 --- a/src/routes/song/[id]/+page.svelte +++ b/src/routes/song/[id]/+page.svelte @@ -11,10 +11,17 @@ const t = getI18n().song.mode let { data } = $props() + let taskStatus = $state({ + lyrics: false, + ai: false, + music: false, + separation: false + }) + let modes = $derived([ - { icon: "i-material-symbols:keyboard-rounded", label: t.typing, url: `/song/${data.song.id}/play` }, - { icon: "i-material-symbols:music-note-rounded", label: t.music, url: `/song/${data.song.id}/play?music=true` }, - { icon: "i-material-symbols:mic-rounded", label: t.karaoke, url: `/song/${data.song.id}/karaoke` }, + { icon: "i-material-symbols:keyboard-rounded", label: t.typing, url: `/song/${data.song.id}/play`, disabled: !taskStatus.lyrics || !taskStatus.ai }, + { icon: "i-material-symbols:music-note-rounded", label: t.music, url: `/song/${data.song.id}/play?music=true`, disabled: !taskStatus.music }, + { icon: "i-material-symbols:mic-rounded", label: t.karaoke, url: `/song/${data.song.id}/karaoke`, disabled: !taskStatus.separation }, ]) let loadStatus = $state<"idle" | "loading" | "done">("idle") @@ -33,6 +40,15 @@ const state = res.status if (state && state.items) { + // Update task status + for (const item of state.items) { + if (item.progress !== 1) continue + if (item.id === 'lyrics') taskStatus.lyrics = true + if (item.id === 'ai') taskStatus.ai = true + if (item.id === 'music') taskStatus.music = true + if (item.id === 'separation') taskStatus.separation = true + } + progressItems = state.items.map((item: any) => ({ title: item.task + (item.progress > 0 && item.progress < 1 ? ` (${Math.round(item.progress * 100)}%)` : ''), icon: item.progress === 1 ? 'i-material-symbols:check text-green-500' : @@ -59,10 +75,8 @@ -{#if loadStatus === "done"} -
- {#each modes as mode} - - {/each} -
-{/if} +
+ {#each modes as mode} + + {/each} +