fix: full-feature LRC parser by umechi migrated into main app

This commit is contained in:
alikia2x 2024-07-28 18:30:56 +08:00
parent 9e388b66ce
commit 8b541818c9
3 changed files with 41 additions and 9 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "aquavox", "name": "aquavox",
"version": "1.12.14", "version": "1.12.15",
"private": false, "private": false,
"scripts": { "scripts": {
"dev": "vite dev", "dev": "vite dev",

View File

@ -51,11 +51,13 @@ export interface LrcMetaData {
export interface ParsedLrc extends LrcMetaData { export interface ParsedLrc extends LrcMetaData {
scripts?: ParserScriptItem[]; scripts?: ParserScriptItem[];
[key: string]: any; [key: string]: any;
} }
export interface LrcJsonData extends LrcMetaData { export interface LrcJsonData extends LrcMetaData {
scripts?: ScriptItem[]; scripts?: ScriptItem[];
[key: string]: any; [key: string]: any;
} }
@ -64,10 +66,10 @@ interface IDTag {
} }
function convertTimeToMs({ function convertTimeToMs({
mins, mins,
secs, secs,
decimals decimals
}: { }: {
mins?: number | string; mins?: number | string;
secs?: number | string; secs?: number | string;
decimals?: string; decimals?: string;
@ -102,6 +104,7 @@ const alpha = alt_sc(
); );
const alphaStr = apply(rep(alpha), (r) => r.join('')); const alphaStr = apply(rep(alpha), (r) => r.join(''));
function spaces<K>(): Parser<K, Token<K>[]> { function spaces<K>(): Parser<K, Token<K>[]> {
return rep_sc(str(' ')); return rep_sc(str(' '));
} }
@ -279,3 +282,24 @@ export function parseLRC(
} }
}, {} as ParsedLrc); }, {} as ParsedLrc);
} }
export default function lrcParser(lrc: string): LrcJsonData {
const parsedLrc = parseLRC(lrc, { wordDiv: '', strict: true });
if (parsedLrc.scripts === undefined) {
return parsedLrc as LrcJsonData;
}
let finalLrc: LrcJsonData = parsedLrc as LrcJsonData;
let lyrics: ScriptItem[] = [];
let i = 0;
while (i < parsedLrc.scripts.length - 1) {
let lyricLine = parsedLrc.scripts[i] as ScriptItem;
lyricLine.start/=1000;
lyricLine.end = parsedLrc.scripts[i+1].start / 1000;
if (parsedLrc.scripts[i+1].text.trim() === "") {
i+=2;
} else i++;
lyrics.push(lyricLine);
}
finalLrc.scripts = lyrics;
return finalLrc;
}

View File

@ -8,14 +8,14 @@
import extractFileName from '$lib/extractFileName'; import extractFileName from '$lib/extractFileName';
import localforage from 'localforage'; import localforage from 'localforage';
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import lrcParser, { type LrcJsonData } from 'lrc-parser-ts'; import lrcParser, { type LrcJsonData } from '$lib/lyrics/parser';
import userAdjustingProgress from '$lib/state/userAdjustingProgress'; import userAdjustingProgress from '$lib/state/userAdjustingProgress';
import type { IAudioMetadata } from 'music-metadata-browser'; import type { IAudioMetadata } from 'music-metadata-browser';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import progressBarRaw from '$lib/state/progressBarRaw'; import progressBarRaw from '$lib/state/progressBarRaw';
const audioId = $page.params.id; const audioId = $page.params.id;
let audioPlayer: HTMLAudioElement; let audioPlayer: HTMLAudioElement | null = null;
let volume = 1; let volume = 1;
let name = ''; let name = '';
let singer = ''; let singer = '';
@ -44,22 +44,26 @@
] ]
}); });
ms.setActionHandler('play', function () { ms.setActionHandler('play', function () {
if (audioPlayer===null) return;
audioPlayer.play(); audioPlayer.play();
paused = false; paused = false;
}); });
ms.setActionHandler('pause', function () { ms.setActionHandler('pause', function () {
if (audioPlayer===null) return;
audioPlayer.pause(); audioPlayer.pause();
paused = true; paused = true;
}); });
ms.setActionHandler('seekbackward', function () { ms.setActionHandler('seekbackward', function () {
if (audioPlayer===null) return;
if (audioPlayer.currentTime > 4) { if (audioPlayer.currentTime > 4) {
audioPlayer.currentTime = 0; audioPlayer.currentTime = 0;
} }
}); });
ms.setActionHandler('previoustrack', function () { ms.setActionHandler('previoustrack', function () {
if (audioPlayer===null) return;
if (audioPlayer.currentTime > 4) { if (audioPlayer.currentTime > 4) {
audioPlayer.currentTime = 0; audioPlayer.currentTime = 0;
} }
@ -81,6 +85,7 @@
prepared.push('cover'); prepared.push('cover');
}); });
localforage.getItem(`${audioId}-file`, function (err, file) { localforage.getItem(`${audioId}-file`, function (err, file) {
if (audioPlayer===null) return;
if (file) { if (file) {
const f = file as File; const f = file as File;
audioFile = f; audioFile = f;
@ -105,6 +110,7 @@
} }
function playAudio() { function playAudio() {
if (audioPlayer===null) return;
if (audioPlayer.duration) { if (audioPlayer.duration) {
duration = audioPlayer.duration; duration = audioPlayer.duration;
} }
@ -114,7 +120,7 @@
} }
$: { $: {
if (!launched) { if (!launched && audioPlayer) {
const requirements = ['name', 'file', 'cover']; const requirements = ['name', 'file', 'cover'];
let flag = true; let flag = true;
for (const r of requirements) { for (const r of requirements) {
@ -152,6 +158,7 @@
$: { $: {
clearInterval(mainInterval); clearInterval(mainInterval);
mainInterval = setInterval(() => { mainInterval = setInterval(() => {
if (audioPlayer===null) return;
if ($userAdjustingProgress === false) if ($userAdjustingProgress === false)
currentProgress = audioPlayer.currentTime; currentProgress = audioPlayer.currentTime;
progressBarRaw.set(audioPlayer.currentTime); progressBarRaw.set(audioPlayer.currentTime);
@ -159,6 +166,7 @@
} }
onMount(() => { onMount(() => {
if (audioPlayer===null) return;
audioPlayer.volume = localStorage.getItem('volume') ? Number(localStorage.getItem('volume')) : 1; audioPlayer.volume = localStorage.getItem('volume') ? Number(localStorage.getItem('volume')) : 1;
}); });
@ -175,7 +183,7 @@
</script> </script>
<svelte:head> <svelte:head>
<title>{name} - Aquavox</title> <title>{name} - AquaVox</title>
</svelte:head> </svelte:head>
<Background coverId={audioId} /> <Background coverId={audioId} />