fix(lyrics): consider trailing timestamp in ELRC lyrics (#5677)

* fix: take into account trailing timestamp in elrc

* refactor: slightly simplify the loop
This commit is contained in:
Jorge Pardo 2026-06-27 22:11:08 +02:00 committed by GitHub
parent 13e96a0e81
commit 11f5441eb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 0 deletions

View File

@ -189,6 +189,7 @@ func parseEnhancedLine(text string) (string, []Cue) {
segments := make([]segment, 0, len(matches))
var rawValue strings.Builder
var trailingEnd *int64
for i, match := range matches {
timeMs, err := parseTime(
// Rewrite <...> as [...] so parseTime can handle it with the same logic
@ -217,6 +218,9 @@ func parseEnhancedLine(text string) (string, []Cue) {
word := text[textStart:textEnd]
if word == "" {
if i == len(matches)-1 {
trailingEnd = &timeMs
}
continue
}
@ -258,6 +262,10 @@ func parseEnhancedLine(text string) (string, []Cue) {
})
}
if trailingEnd != nil && len(cues) > 0 {
cues[len(cues)-1].End = trailingEnd
}
return strings.TrimSpace(finalRaw), cues
}

View File

@ -188,6 +188,42 @@ var _ = Describe("parseLRC", func() {
}))
})
It("should use a trailing Enhanced LRC marker as the end of the last word", func() {
lyrics, err := parseLRC("xxx", "[00:01.00]<00:01.00>Some <00:01.50>lyrics<00:02.00>\n[00:30.00]Instrumental over")
Expect(err).ToNot(HaveOccurred())
Expect(lyrics.Line).To(HaveLen(2))
t1000, t1500, t2000 := int64(1000), int64(1500), int64(2000)
line := lyrics.Line[0]
Expect(line.Value).To(Equal("Some lyrics"))
Expect(line.End).To(Equal(&t2000))
Expect(line.Cue).To(Equal([]Cue{
{Start: &t1000, End: &t1500, Value: "Some ", ByteStart: 0, ByteEnd: 4},
{Start: &t1500, End: &t2000, Value: "lyrics", ByteStart: 5, ByteEnd: 10},
}))
})
It("should shift a trailing Enhanced LRC marker for repeated line occurrences", func() {
lyrics, err := parseLRC("xxx", "[00:10.00][00:30.00]<00:10.10>Hello <00:10.50>world<00:10.90>")
Expect(err).ToNot(HaveOccurred())
Expect(lyrics.Line).To(HaveLen(2))
t10100, t10500, t10900 := int64(10100), int64(10500), int64(10900)
t30100, t30500, t30900 := int64(30100), int64(30500), int64(30900)
Expect(lyrics.Line[0].End).To(Equal(&t10900))
Expect(lyrics.Line[0].Cue).To(Equal([]Cue{
{Start: &t10100, End: &t10500, Value: "Hello ", ByteStart: 0, ByteEnd: 5},
{Start: &t10500, End: &t10900, Value: "world", ByteStart: 6, ByteEnd: 10},
}))
Expect(lyrics.Line[1].End).To(Equal(&t30900))
Expect(lyrics.Line[1].Cue).To(Equal([]Cue{
{Start: &t30100, End: &t30500, Value: "Hello ", ByteStart: 0, ByteEnd: 5},
{Start: &t30500, End: &t30900, Value: "world", ByteStart: 6, ByteEnd: 10},
}))
})
It("should shift inline ELRC word timestamps for each repeated line occurrence", func() {
lyrics, err := parseLRC("xxx", "[00:10.00][00:30.00]<00:10.10>Hello <00:10.50>world")
Expect(err).ToNot(HaveOccurred())