mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-06-24 08:17:28 +08:00
feat: 新增歌詞翻譯模組和 OpenCC 翻譯引擎
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { useSettingsStore } from '@/store/modules/settings';
|
||||
import type { ILyricText } from '@/types/music';
|
||||
|
||||
/**
|
||||
* Translate lyric lines according to selected engine.
|
||||
* Supports runtime-loading `opencc-rust` from CDN and caches the converter.
|
||||
*/
|
||||
export async function translateLyrics(lines: ILyricText[] | undefined) {
|
||||
if (!lines || lines.length === 0) return lines || [];
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const engine = settingsStore.setData?.lyricTranslationEngine || 'none';
|
||||
|
||||
switch (engine) {
|
||||
case 'opencc': {
|
||||
const mod: any = await import('./translation-engines/opencc');
|
||||
const engineMod = await mod.ensureOpenccConverter();
|
||||
return engineMod.translateLines(lines);
|
||||
}
|
||||
default: {
|
||||
return lines.map((l) => ({ ...l, trText: l.trText || '' }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
translateLyrics
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
// Re-export available translation engines from this folder.
|
||||
// Add more engines here as separate files and re-export them.
|
||||
export * from './opencc';
|
||||
@@ -0,0 +1,94 @@
|
||||
import type { ILyricText } from '@/types/music';
|
||||
|
||||
let _inited = false;
|
||||
let _converter: any = null;
|
||||
|
||||
export async function init(): Promise<void> {
|
||||
if (_inited) return;
|
||||
const mod: any = await import('https://cdn.jsdelivr.net/npm/opencc-rust/dist/opencc-rust.mjs');
|
||||
if (!mod?.initOpenccRust || !mod?.getConverter) {
|
||||
throw new Error('opencc-rust module missing expected exports');
|
||||
}
|
||||
await mod.initOpenccRust();
|
||||
_converter = mod.getConverter();
|
||||
_inited = true;
|
||||
}
|
||||
|
||||
export async function convert(text: string): Promise<string> {
|
||||
await init();
|
||||
if (!_converter) return text;
|
||||
return _converter.convert(text);
|
||||
}
|
||||
|
||||
export async function convertLines(lines: string[]) {
|
||||
await init();
|
||||
if (!_converter) return lines.slice();
|
||||
|
||||
const cjkRe = /[\u4e00-\u9fff]/;
|
||||
|
||||
const convertOne = async (s: string) => {
|
||||
const src = (s || '').trim();
|
||||
if (!src || !cjkRe.test(src)) return '';
|
||||
try {
|
||||
return await _converter.convert(src);
|
||||
} catch (e) {
|
||||
console.warn('opencc convertLines item failed:', e);
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
const results = await Promise.all(lines.map((s) => convertOne(s)));
|
||||
return results;
|
||||
}
|
||||
|
||||
export async function translateLines(lines: ILyricText[]) {
|
||||
if (!lines || lines.length === 0) return lines.slice();
|
||||
const srcInfo = lines.map((l) => {
|
||||
const hasTr = !!(l.trText && l.trText.trim() !== '');
|
||||
return {
|
||||
src: hasTr ? (l.trText || '').trim() : (l.text || '').trim(),
|
||||
targetIsTr: hasTr
|
||||
};
|
||||
});
|
||||
|
||||
const srcLines = srcInfo.map((s) => s.src);
|
||||
const converted = await convertLines(srcLines);
|
||||
|
||||
return lines.map((l, i) => {
|
||||
const { targetIsTr } = srcInfo[i];
|
||||
const conv = converted[i] || '';
|
||||
if (targetIsTr) {
|
||||
const tr = conv || l.trText || l.text || '';
|
||||
return { ...l, trText: tr };
|
||||
}
|
||||
const txt = conv || l.text || '';
|
||||
return { ...l, text: txt };
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
init,
|
||||
convert,
|
||||
convertLines,
|
||||
translateLines
|
||||
};
|
||||
|
||||
// Ensure the engine is initialized and return public API.
|
||||
let _ensurePromise: Promise<any> | null = null;
|
||||
export async function ensureOpenccConverter() {
|
||||
if (_ensurePromise) return _ensurePromise;
|
||||
_ensurePromise = (async () => {
|
||||
try {
|
||||
await init();
|
||||
} catch (e) {
|
||||
console.warn('opencc ensureOpenccConverter init failed:', e);
|
||||
}
|
||||
return {
|
||||
init,
|
||||
convert,
|
||||
convertLines,
|
||||
translateLines
|
||||
};
|
||||
})();
|
||||
return _ensurePromise;
|
||||
}
|
||||
Reference in New Issue
Block a user