From 1f9fb113f79713eca512fa54732d6be4ad149595 Mon Sep 17 00:00:00 2001 From: ranokay Date: Mon, 23 Feb 2026 11:22:00 +0200 Subject: [PATCH] fix: guarantee main-first cueLine ordering for same index Add stable sort to ensure the main vocals cueLine (empty role) always appears before other roles when multiple cueLines share the same line index. Previously relied on source document order which is not guaranteed across all TTML files. --- server/subsonic/helpers.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/subsonic/helpers.go b/server/subsonic/helpers.go index c27c72f9e..0ca014ae2 100644 --- a/server/subsonic/helpers.go +++ b/server/subsonic/helpers.go @@ -513,6 +513,11 @@ func buildStructuredLyric(mf *model.MediaFile, lyrics model.Lyrics, enhanced boo }) } + // Ensure main vocals (empty role) always comes first + sort.SliceStable(roleOrder, func(i, j int) bool { + return roleOrder[i] == "" && roleOrder[j] != "" + }) + // Create a separate CueLine for each role group for _, role := range roleOrder { cues := cuesByRole[role]