mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-12 20:37:12 +02:00
feat(plugins): content-sniff plugin lyrics for all formats
Replace model.ToLyrics (LRC/plain only) with model.ParseEmbedded so plugin responses are content-sniffed for TTML, SRT, YAML, LRC, and plain text. ParseEmbedded returns a LyricList, so the loop now flattens multiple tracks per response entry. The test-lyrics WASM plugin gains a "ttml" format mode (configured via pdk.GetConfig) that returns a minimal TTML document; rebuilt with the standard Go wasip1 toolchain (GOOS=wasip1 GOARCH=wasm). A new Ginkgo test asserts Synced==true and the exact cue value, which the old plain-text path could not produce. GetLyrics doc comment updated to reflect content-sniffing; a later task will retarget it to ParseLyrics once that function is introduced.
This commit is contained in:
parent
7559e20d41
commit
0ec7a818fb
3 changed files with 45 additions and 5 deletions
|
|
@ -31,8 +31,9 @@ type LyricsPlugin struct {
|
|||
plugin *plugin
|
||||
}
|
||||
|
||||
// GetLyrics calls the plugin to fetch lyrics, then parses the raw text responses
|
||||
// using model.ToLyrics.
|
||||
// GetLyrics calls the plugin to fetch lyrics, then content-sniffs each response
|
||||
// via model.ParseEmbedded (TTML/SRT/YAML/LRC/plain). A later task retargets this
|
||||
// to ParseLyrics once that function is introduced.
|
||||
func (l *LyricsPlugin) GetLyrics(ctx context.Context, mf *model.MediaFile) (model.LyricList, error) {
|
||||
req := capabilities.GetLyricsRequest{
|
||||
Track: mediaFileToTrackInfo(l.plugin, mf),
|
||||
|
|
@ -50,13 +51,15 @@ func (l *LyricsPlugin) GetLyrics(ctx context.Context, mf *model.MediaFile) (mode
|
|||
if lang == "" {
|
||||
lang = "xxx"
|
||||
}
|
||||
parsed, err := model.ToLyrics(lang, lt.Text)
|
||||
parsed, err := model.ParseEmbedded(lang, lt.Text)
|
||||
if err != nil {
|
||||
log.Warn(ctx, "Error parsing plugin lyrics", "plugin", l.name, err)
|
||||
continue
|
||||
}
|
||||
if parsed != nil && !parsed.IsEmpty() {
|
||||
result = append(result, *parsed)
|
||||
for _, lyric := range parsed {
|
||||
if !lyric.IsEmpty() {
|
||||
result = append(result, lyric)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
|
|
|
|||
|
|
@ -83,6 +83,25 @@ var _ = Describe("LyricsPlugin", Ordered, func() {
|
|||
_, err := p.GetLyrics(GinkgoT().Context(), track)
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("content-sniffs TTML returned by the plugin", func() {
|
||||
manager, _ := createTestManagerWithPlugins(map[string]map[string]string{
|
||||
"test-lyrics": {"format": "ttml"},
|
||||
}, "test-lyrics"+PackageExtension)
|
||||
|
||||
p, ok := manager.LoadLyricsProvider("test-lyrics")
|
||||
Expect(ok).To(BeTrue())
|
||||
|
||||
track := &model.MediaFile{ID: "track-1", Title: "Test Song", Artist: "Test Artist"}
|
||||
result, err := p.GetLyrics(GinkgoT().Context(), track)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(result).To(HaveLen(1))
|
||||
// Verify the result is parsed as TTML (synced, with the exact cue text),
|
||||
// not mangled as plain text with raw XML markup.
|
||||
Expect(result[0].Synced).To(BeTrue())
|
||||
Expect(result[0].Line).To(HaveLen(1))
|
||||
Expect(result[0].Line[0].Value).To(Equal("plugin ttml line"))
|
||||
})
|
||||
})
|
||||
|
||||
Describe("PluginNames", func() {
|
||||
|
|
|
|||
18
plugins/testdata/test-lyrics/main.go
vendored
18
plugins/testdata/test-lyrics/main.go
vendored
|
|
@ -21,6 +21,24 @@ func (t *testLyrics) GetLyrics(input lyrics.GetLyricsRequest) (lyrics.GetLyricsR
|
|||
return lyrics.GetLyricsResponse{}, fmt.Errorf("%s", errMsg)
|
||||
}
|
||||
|
||||
// Return a minimal TTML document to exercise content-sniffing for rich formats.
|
||||
format, hasFormat := pdk.GetConfig("format")
|
||||
if hasFormat && format == "ttml" {
|
||||
const ttml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tt xmlns="http://www.w3.org/ns/ttml">
|
||||
<body xml:lang="eng">
|
||||
<div>
|
||||
<p begin="00:00.000" end="00:01.000">plugin ttml line</p>
|
||||
</div>
|
||||
</body>
|
||||
</tt>`
|
||||
return lyrics.GetLyricsResponse{
|
||||
Lyrics: []lyrics.LyricsText{
|
||||
{Lang: "eng", Text: ttml},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Check if we should omit language (to test default language handling)
|
||||
noLang, hasNoLang := pdk.GetConfig("no_lang")
|
||||
lang := "eng"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue