Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/6xingyv/accompanist-lyrics-core/llms.txt

Use this file to discover all available pages before exploring further.

KaraokeLine is the sealed interface for lyrics lines that carry syllable-level timing — the building block for animated, word-by-word highlighting. It extends ISyncedLine and adds a list of KaraokeSyllable objects, alignment information for multi-singer layouts, and optional phonetic annotations. There are two concrete subtypes: MainKaraokeLine for the primary vocalist (which may embed AccompanimentKaraokeLine tracks), and AccompanimentKaraokeLine for background or harmony vocals. Both enforce end >= start in their init blocks.

Sealed interface: KaraokeLine

sealed interface KaraokeLine : ISyncedLine {
    val syllables: List<KaraokeSyllable>
    val translation: String?
    val alignment: KaraokeAlignment
    override val start: Int
    override val end: Int
    val phonetic: String?

    fun progress(current: Int): Float
    fun isFocused(current: Int): Boolean
}

Interface properties

syllables
List<KaraokeSyllable>
Ordered list of syllables that make up this line. See KaraokeSyllable.
translation
String?
Optional translation of the full line; null when not provided.
alignment
KaraokeAlignment
Visual alignment hint for multi-singer layouts. See KaraokeAlignment below.
start
Int
Start time of the line in milliseconds.
end
Int
End time of the line in milliseconds.
phonetic
String?
Optional phonetic (romanized) representation of the full line; null when absent.
duration
Int
Computed as end - start in each concrete subtype. Inherited from ISyncedLine.

Interface methods

progress(current: Int): Float

fun progress(current: Int): Float
Returns a normalized playback progress for this line in the range [0.0, 1.0].
ConditionReturn value
current < start0.0
current in start..end(current - start) / duration
current > end1.0
current
Int
Current playback position in milliseconds.

isFocused(current: Int): Boolean

fun isFocused(current: Int): Boolean
Returns true when current falls within [start, end]. Use this to decide whether to render the line as active (e.g. apply a highlight color or scale animation).
current
Int
Current playback position in milliseconds.

MainKaraokeLine

The primary lyrics line. May embed a list of AccompanimentKaraokeLine objects for background vocals that sing simultaneously.
data class MainKaraokeLine(
    override val syllables: List<KaraokeSyllable>,
    override val translation: String?,
    override val alignment: KaraokeAlignment,
    override val start: Int,
    override val end: Int,
    override val phonetic: String? = null,
    val accompanimentLines: List<AccompanimentKaraokeLine>? = null
) : KaraokeLine
syllables
List<KaraokeSyllable>
required
Syllables for the main vocal line.
translation
String?
Optional translation of the line.
alignment
KaraokeAlignment
required
Alignment hint for display — Start, End, or Unspecified.
start
Int
required
Start time in milliseconds. Must be ≤ end.
end
Int
required
End time in milliseconds. Must be ≥ start; otherwise construction throws IllegalArgumentException.
phonetic
String?
default:"null"
Optional phonetic annotation for the full line.
accompanimentLines
List<AccompanimentKaraokeLine>?
default:"null"
Zero or more accompaniment (background/harmony) vocal lines that overlap with this main line. null when the format carries no accompaniment data.

Additional property

accompanimentLines
List<AccompanimentKaraokeLine>?
Embedded accompaniment lines. null indicates no accompaniment; an empty list means the field was explicitly set to none.

AccompanimentKaraokeLine

A background or harmony vocal line. Structurally identical to MainKaraokeLine but without the accompanimentLines field. Instances of this type are typically found nested inside MainKaraokeLine.accompanimentLines.
data class AccompanimentKaraokeLine(
    override val syllables: List<KaraokeSyllable>,
    override val translation: String?,
    override val alignment: KaraokeAlignment,
    override val start: Int,
    override val end: Int,
    override val phonetic: String? = null
) : KaraokeLine
syllables
List<KaraokeSyllable>
required
Syllables for the accompaniment vocal.
translation
String?
Optional translation of the accompaniment line.
alignment
KaraokeAlignment
required
Alignment hint; typically KaraokeAlignment.End to visually separate it from the main line.
start
Int
required
Start time in milliseconds. Must be ≤ end.
end
Int
required
End time in milliseconds. Must be ≥ start; otherwise construction throws IllegalArgumentException.
phonetic
String?
default:"null"
Optional phonetic annotation.

KaraokeAlignment

An enum that communicates the intended visual alignment of a line within a multi-singer UI layout.
enum class KaraokeAlignment {
    Start, End, Unspecified
}
Start
KaraokeAlignment
The line should be aligned to the leading edge (typically the primary vocalist, left in LTR layouts).
End
KaraokeAlignment
The line should be aligned to the trailing edge (typically a second vocalist or background harmony, right in LTR layouts).
Unspecified
KaraokeAlignment
No alignment preference. The UI can apply its own default, or center the line.

Extension functions

KaraokeLine.copy()

fun KaraokeLine.copy(
    syllables: List<KaraokeSyllable> = this.syllables,
    translation: String? = this.translation,
    alignment: KaraokeAlignment = this.alignment,
    start: Int = this.start,
    end: Int = this.end,
    phonetic: String? = this.phonetic
): KaraokeLine
A top-level extension function (not a data class method) that provides a unified copy helper across both KaraokeLine subtypes without requiring a when expression. Delegates to the data class copy() of the underlying concrete type, preserving the runtime type.
This extension does not expose accompanimentLines. To change accompanimentLines on a MainKaraokeLine, cast to MainKaraokeLine and call its data class copy() directly.
val updated = line.copy(
    phonetic = "hēllō wörld",
    alignment = KaraokeAlignment.Start
)

KaraokeLine.toSyncedLine()

fun KaraokeLine.toSyncedLine(): SyncedLine
Collapses this line’s syllable list into a single SyncedLine by joining all syllable content strings (trimmed). Useful when you need to fall back to line-level display or serialize to a simpler format.
val syncedLine: SyncedLine = karaokeLine.toSyncedLine()
// syncedLine.content == karaokeLine.syllables.contentToString().trim()

Usage examples

Dispatching on subtype with when

when (val line = lyrics.lines[index]) {
    is KaraokeLine.MainKaraokeLine -> {
        renderMain(line)
        line.accompanimentLines?.forEach { renderAccompaniment(it) }
    }
    is KaraokeLine.AccompanimentKaraokeLine -> renderAccompaniment(line)
    else -> {}
}

Animating syllable progress

val positionMs: Int = player.currentPosition.toInt()

line.syllables.forEach { syllable ->
    val progress = syllable.progress(positionMs)
    drawHighlight(syllable.content, progress)
}

Checking line focus and progress

if (line.isFocused(positionMs)) {
    val lineProgress = line.progress(positionMs)
    applyLineAnimation(lineProgress)
}

Multi-singer layout using alignment

val mainLines = lyrics.lines
    .filterIsInstance<KaraokeLine.MainKaraokeLine>()

mainLines.forEach { main ->
    val mainAlign = when (main.alignment) {
        KaraokeAlignment.Start -> Alignment.Start
        KaraokeAlignment.End -> Alignment.End
        KaraokeAlignment.Unspecified -> Alignment.CenterHorizontally
    }
    renderLine(main, mainAlign)

    main.accompanimentLines?.forEach { acc ->
        val accAlign = when (acc.alignment) {
            KaraokeAlignment.Start -> Alignment.Start
            KaraokeAlignment.End -> Alignment.End
            KaraokeAlignment.Unspecified -> Alignment.CenterHorizontally
        }
        renderLine(acc, accAlign)
    }
}

Build docs developers (and LLMs) love