diff --git a/src/lib/i18n/en.ts b/src/lib/i18n/en.ts index a55e9f7..84e481d 100644 --- a/src/lib/i18n/en.ts +++ b/src/lib/i18n/en.ts @@ -103,6 +103,13 @@ export default { wrong: 'Wrong: ', remaining: 'Remaining: ' } + }, + prepare: { + lyrics: 'Fetching lyrics from NetEase', + ai: 'AI analyzing lyrics', + music: 'Fetching music from NetEase', + separation: 'AI vocal separation', + error: 'Error: ' } }, user: { @@ -159,6 +166,5 @@ export default { title: 'Error', refresh: 'Refresh to Retry' } - }, - components: {} + } } \ No newline at end of file diff --git a/src/lib/i18n/index.ts b/src/lib/i18n/index.ts index 50024eb..e7c155c 100644 --- a/src/lib/i18n/index.ts +++ b/src/lib/i18n/index.ts @@ -31,6 +31,11 @@ export const setLanguage = (lang: Lang) => { location.reload() } +export const useMsg = () => { + const i18n = getI18n() + return (key: string) => key.split('.').reduce((o, i) => (o as any)?.[i], i18n) as unknown as string +} + export {} declare global { diff --git a/src/lib/i18n/ja.ts b/src/lib/i18n/ja.ts index d5f46fd..9f3f1d3 100644 --- a/src/lib/i18n/ja.ts +++ b/src/lib/i18n/ja.ts @@ -103,6 +103,13 @@ export default { wrong: '不正解:', remaining: '残り:' } + }, + prepare: { + lyrics: 'NetEaseから歌詞を取得中', + ai: 'AIが歌詞を分析中', + music: 'NetEaseから音楽を取得中', + separation: 'AIボーカル分離', + error: 'エラー: ' } }, user: { @@ -159,6 +166,5 @@ export default { title: 'エラー', refresh: '更新して再試行' } - }, - components: {} + } } diff --git a/src/lib/i18n/zh.ts b/src/lib/i18n/zh.ts index a7f6403..4c75f1c 100644 --- a/src/lib/i18n/zh.ts +++ b/src/lib/i18n/zh.ts @@ -103,6 +103,13 @@ export default { wrong: '错误:', remaining: '剩余:' } + }, + prepare: { + lyrics: '从网易云获取歌词', + ai: 'AI 标注歌词读音', + music: '从网易云获取音乐', + separation: 'AI 人声分离', + error: '错误: ' } }, user: { @@ -159,8 +166,5 @@ export default { title: '错误', refresh: '刷新重试' } - }, - components: { - } } \ No newline at end of file diff --git a/src/lib/server/songs.ts b/src/lib/server/songs.ts index d998f92..0c94192 100644 --- a/src/lib/server/songs.ts +++ b/src/lib/server/songs.ts @@ -155,14 +155,14 @@ export const prepareSong = async (songId: number) => { const addTask = (id: string, task: string) => ({ id, task, progress: 0 }).also(it => state.items.push(it)) const processLyrics = async () => { // 1. Get Lyrics - const taskLyrics = addTask('lyrics', '从网易云获取歌词') + const taskLyrics = addTask('lyrics', 'lyrics') const raw = await getLyricsRaw(songId) taskLyrics.progress = 1 if (raw.lang !== 'jpn') throw new Error('不是日语歌曲') // 2. AI Process - const taskAI = addTask('ai', 'AI 标注歌词读音') + const taskAI = addTask('ai', 'ai') // Check cache if (await checkLyricsProcessed(songId)) taskAI.progress = 1 @@ -175,12 +175,12 @@ export const prepareSong = async (songId: number) => { const processMusic = async () => { // 3. Audio - const taskAudio = addTask('music', '从网易云获取音乐') + const taskAudio = addTask('music', 'music') await getSongUrl(songId) taskAudio.progress = 1 // 4. Source Separation - const taskSeparation = addTask('separation', 'AI 人声分离') + const taskSeparation = addTask('separation', 'separation') const inputPath = path.join(CACHE_DIR, `${songId}/exhigh.mp3`) const outputDir = path.join(CACHE_DIR, `${songId}`) @@ -188,7 +188,7 @@ export const prepareSong = async (songId: number) => { await separateSong(inputPath, outputDir) taskSeparation.progress = 1 } catch (e: any) { - addTask('error', `错误: ${e.message}`).progress = -1 + addTask('error', e.message).progress = -1 // Don't fail the whole process, just this step } } @@ -197,7 +197,7 @@ export const prepareSong = async (songId: number) => { await Promise.all([processLyrics(), processMusic()]) state.status = 'done' } catch (e) { - addTask('error', `错误: ${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 77f604f..5c7df3f 100644 --- a/src/routes/song/[id]/+page.svelte +++ b/src/routes/song/[id]/+page.svelte @@ -5,12 +5,12 @@ import PlayerAppBar from "$lib/ui/player/PlayerAppBar.svelte" import ProgressList from "$lib/ui/ProgressList.svelte" import { goto } from "$app/navigation" - import { artistAndAlbum } from "$lib/utils" - import { getI18n } from "$lib/i18n" + import { getI18n, useMsg } from "$lib/i18n" import { typingSettingsDefault } from "$lib/types" - import { getNextSong } from "$lib/ui/player/SongSwitching.js"; + import { getNextSong } from "$lib/ui/player/SongSwitching.js" const t = getI18n().song.mode + const getMsg = useMsg() let { data } = $props() @@ -52,24 +52,31 @@ 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 + // 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) => { + let taskName = getMsg(`song.prepare.${item.id}`) || item.task + if (item.id === 'error') { + taskName = getMsg('song.prepare.error') + item.task } - 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' : - item.progress === -1 ? 'i-material-symbols:error text-red-500' : - 'i-material-symbols:sync animate-spin' - })) - - const totalProgress = state.items.reduce((acc: number, cur: any) => acc + Math.max(0, cur.progress), 0) - progressPercentage = Math.min(100, Math.round((totalProgress / 4) * 100)) + return { + title: taskName + (item.progress > 0 && item.progress < 1 ? ` (${Math.round(item.progress * 100)}%)` : ''), + icon: item.progress === 1 ? 'i-material-symbols:check text-green-500' : + item.progress === -1 ? 'i-material-symbols:error text-red-500' : + 'i-material-symbols:sync animate-spin' + } + }) + + const totalProgress = state.items.reduce((acc: number, cur: any) => acc + Math.max(0, cur.progress), 0) + progressPercentage = Math.min(100, Math.round((totalProgress / 4) * 100)) } if (state.status === "done") {