fix: parse long embedded lyrics before truncation

This commit is contained in:
ranokay 2026-05-26 20:26:40 +03:00
parent 719fa5dc99
commit 0100e8893a
No known key found for this signature in database
3 changed files with 48 additions and 1 deletions

View File

@ -130,7 +130,7 @@ func (md Metadata) mapGain(rg, r128 model.TagName) *float64 {
}
func (md Metadata) mapLyrics() string {
rawLyrics := md.Pairs(model.TagLyrics)
rawLyrics := md.rawPairs(model.TagLyrics)
lyricList := make(model.LyricList, 0, len(rawLyrics))

View File

@ -4,6 +4,7 @@ import (
"encoding/json"
"os"
"sort"
"strings"
"github.com/navidrome/navidrome/model"
"github.com/navidrome/navidrome/model/metadata"
@ -141,6 +142,42 @@ var _ = Describe("ToMediaFile", func() {
}))
})
It("should parse embedded TTML lyrics longer than the metadata tag max length", func() {
padding := strings.Repeat(`<text for="unused">padding</text>`, 1400)
content := `<tt xmlns="http://www.w3.org/ns/ttml" xmlns:itunes="http://music.apple.com/lyric-ttml-internal" xml:lang="en">
<head>
<metadata>
<iTunesMetadata xmlns="http://music.apple.com/lyric-ttml-internal">
<translations>
<translation xml:lang="en-US">` + padding + `</translation>
</translations>
</iTunesMetadata>
</metadata>
</head>
<body>
<div>
<p begin="00:00:01.000" end="00:00:02.500" itunes:key="L1">Long embedded TTML line</p>
</div>
</body>
</tt>`
Expect(len(content)).To(BeNumerically(">", 32768))
mf = toMediaFile(model.RawTags{
"LYRICS:ENG": {content},
})
var actual model.LyricList
err := json.Unmarshal([]byte(mf.Lyrics), &actual)
Expect(err).ToNot(HaveOccurred())
Expect(actual).To(HaveLen(1))
Expect(actual[0].Kind).To(Equal("main"))
Expect(actual[0].Lang).To(Equal("en"))
Expect(actual[0].Line).To(Equal([]model.Line{
{Start: P(int64(1000)), End: P(int64(2500)), Value: "Long embedded TTML line"},
}))
})
It("should parse embedded SRT lyrics with the tag language", func() {
mf = toMediaFile(model.RawTags{
"LYRICS:POR": {`1

View File

@ -70,6 +70,7 @@ func New(filePath string, info Info) Metadata {
return Metadata{
filePath: filePath,
fileInfo: info.FileInfo,
rawTags: lowerTags(info.Tags),
tags: clean(filePath, info.Tags),
audioProps: info.AudioProperties,
hasPicture: info.HasPicture,
@ -79,6 +80,7 @@ func New(filePath string, info Info) Metadata {
type Metadata struct {
filePath string
fileInfo FileInfo
rawTags model.Tags
tags model.Tags
audioProps AudioProperties
hasPicture bool
@ -114,6 +116,14 @@ func (md Metadata) Pairs(key model.TagName) []Pair {
values := md.tags[key]
return slice.Map(values, func(v string) Pair { return Pair(v) })
}
func (md Metadata) rawPairs(key model.TagName) []Pair {
mapping, ok := model.TagMappings()[key]
if !ok {
return nil
}
values := filterDuplicatedOrEmptyValues(processPairMapping(key, mapping, md.rawTags))
return slice.Map(values, func(v string) Pair { return Pair(v) })
}
func (md Metadata) first(key model.TagName) string {
if v, ok := md.tags[key]; ok && len(v) > 0 {
return v[0]