Skip to content

rubysworld/propresenter-protobuf

Repository files navigation

ProPresenter Protobuf Tools

Reverse-engineered TypeScript tools for reading, creating, and modifying ProPresenter 7+ files (.pro, .proplaylist, .proworkspace).

ProPresenter 7 switched from XML to Protocol Buffers for its file formats. This project provides proto definitions, a TypeScript library, and a CLI to work with those files programmatically.

⚠️ Disclaimer

This is an unofficial, community-driven project. It is not created, endorsed, or supported by Renewed Vision.

  • Do not contact Renewed Vision for support with these tools
  • Always back up your files before making modifications
  • Test on copies first — never edit production files directly
  • Proto structures may change between ProPresenter versions

Features

  • Read presentations — extract lyrics, slides, metadata, chord charts, CCLI info
  • Write presentations — modify text, create new .pro files from scratch
  • CLI — command-line tools for common operations (info, export, batch processing)
  • Chord support — read/write chord charts with transposition-aware positioning
  • CCLI metadata — extract and format copyright/licensing information
  • Batch operations — process multiple files at once

Supported File Types

Extension Description Proto Message
.pro Presentation document rv.data.Presentation
.proplaylist Playlist rv.data.PlaylistDocument
.proworkspace Workspace configuration rv.data.Workspace

Installation

git clone https://github.com/rubysworld/propresenter-protobuf.git
cd propresenter-protobuf
npm install

CLI Usage

# Show presentation info
npx tsx src/cli.ts info song.pro
npx tsx src/cli.ts info -v song.pro          # verbose with all slides

# List slides with text
npx tsx src/cli.ts list song.pro
npx tsx src/cli.ts list -g Chorus song.pro   # filter by group

# Extract text/lyrics
npx tsx src/cli.ts text song.pro
npx tsx src/cli.ts text -o lyrics.txt song.pro

# Extract chord chart
npx tsx src/cli.ts chords song.pro
npx tsx src/cli.ts chords --format chordpro song.pro

# Edit slide text
npx tsx src/cli.ts edit song.pro --cue 0 --text "New text"
npx tsx src/cli.ts edit song.pro --cue 0 --text "New text" --dry-run

# Export formats
npx tsx src/cli.ts export -f ccli-report song.pro
npx tsx src/cli.ts export -f markdown song.pro
npx tsx src/cli.ts export -f lyrics-txt song.pro

# Batch operations
npx tsx src/cli.ts batch --list-songs *.pro
npx tsx src/cli.ts batch --ccli-report *.pro

# Debug / validation
npx tsx src/cli.ts dump song.pro             # full JSON dump
npx tsx src/cli.ts decode-rtf song.pro       # raw RTF content
npx tsx src/cli.ts validate song.pro         # verify file integrity

Library Usage

Reading Presentations

import {
  readPresentation,
  getCues,
  getCuesByGroup,
  getCueText,
  setCueText,
  getCueChords,
  getCueNotes,
  getMultiTracksInfo,
  formatCCLI,
  getMusicKey,
  writePresentation,
} from './src/lib/index.js';

// Read a presentation
const pres = await readPresentation('song.pro');
console.log(pres.name);

// CCLI info
console.log(formatCCLI(pres));
// => "Amazing Grace" by John Newton | © 1779 | CCLI #1234567

// Music key
console.log(getMusicKey(pres));
// => { original: 'G', current: 'A' }

// Iterate slides by group
for (const [group, cues] of getCuesByGroup(pres)) {
  console.log(`[${group}]`);
  for (const cue of cues) {
    console.log(getCueText(cue));
    console.log('Chords:', getCueChords(cue));
  }
}

// Modify and save
const cues = getCues(pres);
setCueText(cues[0], 'Updated lyrics');
await writePresentation('modified.pro', pres);

Creating Presentations

import { createPresentation, MusicKey, MusicScale } from './src/lib/create.js';
import { writePresentation } from './src/lib/index.js';

const pres = createPresentation({
  title: "Song Title",
  artist: "Artist Name",
  ccliNumber: 12345,
  publisher: "Publisher",
  copyrightYear: 2024,
  category: "Worship",
  musicKey: { key: MusicKey.G, scale: MusicScale.MAJOR },
  sections: [
    {
      name: "Verse 1",
      slides: [
        "Line one\nLine two",
        {
          text: "Amazing grace how sweet\nThe sound that saved",
          chords: [
            { position: 0, chord: "G" },
            { position: 14, chord: "C" },
            { position: 26, chord: "G" },
          ],
        },
      ],
    },
    {
      name: "Chorus",
      slides: ["Chorus lyrics here"],
    },
  ],
});

await writePresentation("output.pro", pres);

Project Structure

├── proto/              # ProPresenter7-Proto submodule (greyshirtguy)
├── src/
│   ├── generated/      # Generated protobuf TS code
│   ├── lib/            # Library (read, write, create)
│   └── cli.ts          # CLI tool
├── samples/            # Sample .pro files for testing
├── SCHEMA.md           # Detailed file format documentation
└── SKILL.md            # AI agent skill reference

How Chord Transposition Works

ProPresenter stores an original key and a user key. When the user changes the key in ProPresenter, it calculates the interval and transposes all chords automatically. Chords are positioned by character offset within the slide text:

{
  text: "Amazing grace",     // positions 0–12
  chords: [
    { position: 0, chord: "G" },   // above "Amazing"
    { position: 8, chord: "C" },   // above "grace"
  ]
}

Credits

License

MIT (tools only — proto files have their own license, see proto/LICENSE)

About

Read, create, and modify ProPresenter 7+ presentation files (.pro)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors