2025-02-10 18:24:31 -06:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2024-02-26 21:12:44 -06:00
|
|
|
import re
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
2024-02-26 22:06:52 -06:00
|
|
|
Seconds = float
|
2024-02-26 21:12:44 -06:00
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class Metadata:
|
|
|
|
name: str
|
|
|
|
value: str
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
|
|
class Subtitle:
|
|
|
|
text: str
|
|
|
|
start: Seconds
|
2025-02-10 18:24:31 -06:00
|
|
|
end: Seconds | None = None
|
2024-02-26 21:12:44 -06:00
|
|
|
|
|
|
|
|
|
|
|
def parse_lrc(text):
|
|
|
|
for line in text.split('\n'):
|
|
|
|
times = []
|
|
|
|
while mobj := re.fullmatch(r'\[(?P<time>((\d+:)?\d+:)?\d+(.\d+)?)\](?P<content>.*)', line):
|
|
|
|
times.append(sum(
|
|
|
|
float(t) * 60**i for i, t in enumerate(reversed(mobj.group('time').split(':')))))
|
|
|
|
line = mobj.group('content')
|
|
|
|
|
|
|
|
for t in times:
|
|
|
|
yield Subtitle(start=t, text=line.strip())
|
|
|
|
|
|
|
|
if not times:
|
|
|
|
if mobj := re.fullmatch(r'\[(?P<name>[^\]:]+):(?P<value>[^\]]+)\]', line):
|
|
|
|
yield Metadata(mobj.group('name'), mobj.group('value').strip())
|
|
|
|
elif line.strip():
|
|
|
|
yield ValueError(line)
|