Personal Library Format

PBE Karaoke ships with no song content at all. To study with it, you point it at a library manifest — a JSON file describing your own already-cleared recordings and the words/timing to sing along with them — plus the audio files that manifest refers to. This page describes what that manifest and its accompanying audio folder need to look like.

Loading a Library

Once you have a manifest and its audio files ready, the gate on the main page accepts them three ways:

Manifest Shape

The manifest is a single JSON object with three top-level fields:

{
  "year": "2026-2027",
  "styles": [ ... ],
  "sections": [ ... ]
}
yearAny string. Not shown in the UI — just a label for the manifest itself.
stylesThe list of musical styles used anywhere in sections. See below.
sectionsOne entry per chapter (or verse range) you have recordings for. See below.

styles

{
  "id": "contemporarychristian",
  "label": "Contemporary Christian",
  "emoji": "🙏",
  "churchFit": "great-match"
}
idRequired. Short, stable, unique identifier — this is what each recording's style field points back to.
labelRequired. Human-readable name shown in the style picker.
emojiOptional. One vibe emoji shown next to the label.
churchFitOptional. One of "great-match", "nervous", or "very-uncomfortable" — shown as a face icon. Leave it out if you'd rather not rate it; the app just shows the label.

sections & recordings

Each section covers one chapter, or one verse range within a chapter, and lists every recording available for it:

{
  "book": "Mark",
  "chapter": 6,
  "verseStart": 30,
  "verseEnd": 56,
  "recordings": [
    {
      "style": "contemporarychristian",
      "take": 1,
      "instrumentalUrl": "Mark 6_30-56 (1).instrumental.m4a",
      "vocalUrl": "Mark 6_30-56 (1).vocal.m4a",
      "words": [
        { "word": "Now", "start": 0.42, "end": 0.71, "verse": 30 },
        { "word": "the", "start": 0.71, "end": 0.85, "verse": 30 },
        { "word": "apostles", "start": 0.85, "end": 1.38, "verse": 30 }
      ]
    }
  ]
}
bookBook name exactly as it should be displayed and grouped in the passage picker.
chapterChapter number.
verseStart / verseEndOptional. Omit both (or set to null) for a whole-chapter section.
recordingsAt least one recording, described below. A section can have several — different styles, or multiple takes of the same style.

Each entry in recordings:

styleMust match one of the top-level styles[].id values.
takeA number distinguishing alternate recordings of the same section+style. Any distinct numbers work — they don't need to start at 1 or be contiguous.
instrumentalUrl / vocalUrl Two separate audio files for the same recording — one with vocals removed, one with just the vocals — rather than a single mixed track. The app always plays both together and fades only the vocal track in and out, so the two files must be the same length and stay in sync. Any browser-playable audio format works (e.g. mp3, m4a, wav). See "Folder Structure" below for what these paths should look like.
wordsWord-by-word timing for this specific recording, described below.

words

An ordered array covering every word in the recording, used to drive the karaoke highlight, the blanking/recall study modes, and Type Ahead/Sing-Along scoring:

{ "word": "apostles", "start": 0.85, "end": 1.38, "verse": 30 }
wordThe word as it should be displayed.
start / endSeconds into this recording's own audio files (not the section, not a global clock) when the word is sung.
verse The verse number this word belongs to. Use null for words that aren't part of the scripture text itself (a spoken intro, an ad-lib, filler) — those play normally but are excluded from study/scoring and from the verse picker.

Folder Structure (Local Folder / OneDrive Folder)

For a hosted URL, folder layout doesn't matter — only that instrumentalUrl and vocalUrl are correct, reachable URLs. For "Load Local Folder…" or a shared OneDrive folder link, the app reads relative to whatever single folder you point it at, so that folder needs a specific shape:

For example, a folder organized by style:

My Library/
├── manifest.local.json
├── Contemporary Christian/
│   ├── Mark 6_30-56 (1).instrumental.m4a
│   └── Mark 6_30-56 (1).vocal.m4a
└── Broadway/
    ├── Mark 6_30-56 (1).instrumental.m4a
    └── Mark 6_30-56 (1).vocal.m4a

would need the matching recording entry to read:

"instrumentalUrl": "Contemporary Christian/Mark 6_30-56 (1).instrumental.m4a",
"vocalUrl": "Contemporary Christian/Mark 6_30-56 (1).vocal.m4a"

Any folder layout works as long as the paths line up — a single flat folder of audio files is just as valid as one organized by style or by book.