# Overview

Braccato is the Better Lyrics rendering engine and its lyric parsers, published as npm packages. Use it to parse any response from this API into one shape, then render it with syllable-level highlighting and autoscroll.

It is the same code that runs inside the Better Lyrics extension, packaged so you can use it in your own player, site, or app.

-   Demo and docs: [braccato.boidu.dev](https://braccato.boidu.dev/)
-   Source: [github.com/better-lyrics/braccato](https://github.com/better-lyrics/braccato) (MIT)

## Packages

| Package | Version | What it does |
| --- | --- | --- |
| `@braccato/core` | `1.16.14` | The `<braccato-lyrics>` custom element that renders synced lyrics |
| `@braccato/parsers` | `0.4.0` | TTML, LRC, SRT, QRC and plain text parsers, with format detection |
| `@braccato/provider-blyrics` | `0.2.3` | A provider chain that fetches from several lyrics sources in priority order |
| `@braccato/types` | `1.0.0` | The shared `Lyric` and `LyricPart` types. Types only, and re-exported by core and parsers |
| `@braccato/rics` | `0.1.3` | Compiles RICS theme source to plain CSS |

Most projects need `@braccato/core` and `@braccato/provider-blyrics`. Add `@braccato/parsers` when you call this API yourself.

## Quickstart

#### The minimal setup

Register the providers once, ask for a song, and hand the result to `<braccato-lyrics>`. If a provider has nothing for the song, the chain tries the next one.

npm i @braccato/core @braccato/provider-blyrics

[Provider chain docs](https://docs.betterlyrics.org/braccato/provider)

1.  ##### Import
    
    element, styles, providers
    
    ```javascript
    import "@braccato/core/element";
    import "@braccato/core/styles/variables.css";
    import "@braccato/core/styles/lyrics.css";
    import "@braccato/core/styles/instrumental.css";
    import {
      ProviderChain,
      createBLyricsProvider,
      createPortatoProvider,
      createLegatoProvider,
    } from "@braccato/provider-blyrics";
    ```
    
2.  ##### Build the chain
    
    first match wins
    
    ```javascript
    const chain = new ProviderChain();
    chain.register({
      key: "ttml",
      displayName: "TTML",
      syncType: "syllable",
      fetch: createBLyricsProvider(),
    });
    chain.register({
      key: "qq",
      displayName: "QQ",
      syncType: "word",
      fetch: createPortatoProvider(),
    });
    chain.register({
      key: "kugou",
      displayName: "Kugou",
      syncType: "line",
      fetch: createLegatoProvider(),
    });
    ```
    
3.  ##### Fetch and render
    
    hand the result to the element
    
    ```javascript
    const result = await chain.fetchLyrics({
      song: "APT.",
      artist: "ROSÉ, Bruno Mars",
      album: "APT.",
      duration: 170,
      signal: new AbortController().signal,
    });
    
    // <audio id="player" src="song.mp3"></audio>
    // <braccato-lyrics source="#player"></braccato-lyrics>
    if (result) {
      document.querySelector("braccato-lyrics").lyrics = result.lyrics;
    }
    ```
    

### Add the element

Put the media element before the lyrics element, so the `source` selector resolves when the element connects. Give the element a height and let it scroll.

```markup
<audio id="player" src="song.mp3" controls></audio>
<braccato-lyrics source="#player"></braccato-lyrics>

<style>
  braccato-lyrics {
    display: block;
    height: 60vh;
    overflow-y: auto;
  }
</style>
```

With `source` set, the element reads the playback position from the `<audio>` element on its own, and a click on a line seeks it.

### Drive the clock yourself

If your player is not a media element (an embedded player, a native bridge, a remote device), leave out `source` and write the position on every frame. `currentTime` is in seconds.

```javascript
function tick() {
  view.currentTime = player.getCurrentTime();
  view.playing = player.isPlaying();
  requestAnimationFrame(tick);
}
requestAnimationFrame(tick);

view.addEventListener("braccato:line-click", (event) => {
  player.seekTo(event.detail.timeS);
});
```

## Next steps

-   [Parsers](https://docs.betterlyrics.org/braccato/parsers): parse the TTML, Kugou and QQ responses
-   [Renderer](https://docs.betterlyrics.org/braccato/renderer): properties, events, scrolling and theming
-   [Provider](https://docs.betterlyrics.org/braccato/provider): fetch from several sources with fallback

Source: https://docs.betterlyrics.org/braccato
