mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-18 07:30:29 +00:00
fix(lyrics): keep explicit [bg:] trailing ends as line ends
A background layer's trailing marker is exact source timing. Without it on Line.End, normalization treats a terminal bg cue end equal to the next line start as a next-line fallback and drops it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016L1sBqsygMkdhf583gTEnE
This commit is contained in:
parent
e6cd424157
commit
fcda9ebd5e
@ -53,8 +53,12 @@ func parseLRC(language, text string) (*Lyrics, error) {
|
||||
flushLine := func() {
|
||||
value, cues, end := parseEnhancedLine(priorLine)
|
||||
var merged bool
|
||||
value, cues, merged = mergeBgLayers(value, cues, pendingBg)
|
||||
var bgEnd *int64
|
||||
value, cues, bgEnd, merged = mergeBgLayers(value, cues, pendingBg)
|
||||
hasBg = hasBg || merged
|
||||
if bgEnd != nil && (end == nil || *bgEnd > *end) {
|
||||
end = bgEnd
|
||||
}
|
||||
for idx := range timestamps {
|
||||
startCopy := timestamps[idx]
|
||||
shift := timestamps[idx] - timestamps[0]
|
||||
@ -207,13 +211,20 @@ func parseLRC(language, text string) (*Lyrics, error) {
|
||||
|
||||
// mergeBgLayers appends parsed [bg:] content to a line's value and cues as a
|
||||
// background agent layer, mirroring the TTML background-vocal representation.
|
||||
func mergeBgLayers(value string, cues []Cue, bgLines []string) (string, []Cue, bool) {
|
||||
// It also returns the latest explicit trailing end among the merged layers, so
|
||||
// an exact source end is not mistaken for a next-line fallback during
|
||||
// normalization.
|
||||
func mergeBgLayers(value string, cues []Cue, bgLines []string) (string, []Cue, *int64, bool) {
|
||||
merged := false
|
||||
var latestEnd *int64
|
||||
for _, bg := range bgLines {
|
||||
bgValue, bgCues, _ := parseEnhancedLine(bg)
|
||||
bgValue, bgCues, bgEnd := parseEnhancedLine(bg)
|
||||
if len(bgCues) == 0 {
|
||||
continue
|
||||
}
|
||||
if bgEnd != nil && (latestEnd == nil || *bgEnd > *latestEnd) {
|
||||
latestEnd = bgEnd
|
||||
}
|
||||
offset := 0
|
||||
if value != "" {
|
||||
offset = len(value) + 1
|
||||
@ -228,7 +239,7 @@ func mergeBgLayers(value string, cues []Cue, bgLines []string) (string, []Cue, b
|
||||
}
|
||||
merged = true
|
||||
}
|
||||
return value, cues, merged
|
||||
return value, cues, latestEnd, merged
|
||||
}
|
||||
|
||||
func fillMainAgentID(lines []Line) {
|
||||
|
||||
@ -183,6 +183,14 @@ var _ = Describe("parseLRC", func() {
|
||||
Expect(lyrics.Line[1].Value).To(Equal("Next"))
|
||||
})
|
||||
|
||||
It("keeps an explicit [bg:] trailing end that equals the next line start", func() {
|
||||
lyrics, err := parseLRC("xxx", "[00:01.00]Main\n[bg: <00:01.50>Ooh<00:03.00>]\n[00:03.00]Next")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(lyrics.Line).To(HaveLen(2))
|
||||
Expect(lyrics.Line[0].Value).To(Equal("Main Ooh"))
|
||||
Expect(lyrics.Line[0].End).To(Equal(new(int64(3000))))
|
||||
})
|
||||
|
||||
It("should skip a [bg:] line that has no inline timing", func() {
|
||||
lyrics, err := parseLRC("xxx", "[00:01.00]Hi\n[bg: untimed]\n[00:03.00]Next")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user