7.7 KiB
ProPresenter 7 .probundle File Format Specification
Version: 1.0
Target Audience: AI agents, automated parsers, developers
Proto Source: greyshirtguy/ProPresenter7-Proto v7.16.2 (MIT License)
1. Overview
File Format
- Extension:
.probundle - Container Format: Standard ZIP archive (PKZIP 2.0+, default deflate compression)
- Binary Format: Protocol Buffers (Google protobuf v3) for the embedded
.profile - Top-level Message:
rv.data.Presentation(defined inpresentation.proto) - Proto Definitions: greyshirtguy/ProPresenter7-Proto v7.16.2 (MIT)
- Predecessor: Pro6
.pro6xformat
Container Structure
- Archive Type: Standard ZIP with deflate compression (default)
- ZIP64 EOCD Quirk: ProPresenter 7 exports have the same 98-byte EOCD discrepancy as
.proplaylistfiles - Entry Layout:
- Media files at absolute paths with leading
/(e.g.,/Users/me/Downloads/Media/image.png) - Single
.profile at root (filename only, no directory)
- Media files at absolute paths with leading
Purpose
A .probundle packages a single ProPresenter presentation (.pro file) together with all its referenced media assets (images, videos, audio) into a single portable archive. This enables sharing presentations between machines without losing media references.
File Validity
- Empty files (0 bytes): Invalid. Throw exception.
- Archives without
.pro: Invalid. Throw exception. - Bundles without media: Valid. A presentation with no media actions produces a ZIP containing only the
.profile.
2. Archive Structure
Entry Layout
/Users/me/Downloads/pp-test/Media/background.png <-- Media file (absolute path with leading /)
SongName.pro <-- Protobuf-encoded presentation
Entry Order
- Media files first, then the
.profile last - ProPresenter does not enforce order, but this matches PP7 export behavior
Media Entry Naming
- Media entries use absolute filesystem paths with a leading
/ - Standard unzip tools strip the leading
/with a warning:warning: stripped absolute path spec from /Users/.../image.png - This is intentional and matches PP7 export behavior
Compression
- ProPresenter exports: Standard deflate compression
- Writer output: Standard deflate compression (ZipArchive defaults)
- No special attributes needed: Standard permissions, no forced store compression
3. Protobuf Content (.pro File)
Media URL Format
Media references in the .pro protobuf must use file:/// absolute URLs with a LocalRelativePath in URL.local.
URL Structure
message URL {
string absolute_string = 1; // "file:///Users/me/Downloads/Media/image.png"
LocalRelativePath local = 4; // Root + relative path
Platform platform = 5; // PLATFORM_MACOS
}
LocalRelativePath
message LocalRelativePath {
Root root = 1; // Enum mapping to macOS directory
string path = 2; // Relative path from root directory
}
Root Type Mappings
| Root Enum | Value | macOS Directory |
|---|---|---|
ROOT_BOOT_VOLUME |
0 | / (fallback) |
ROOT_USER_HOME |
2 | ~/ |
ROOT_USER_DOWNLOADS |
4 | ~/Downloads/ |
ROOT_USER_DOCUMENTS |
5 | ~/Documents/ |
ROOT_USER_DESKTOP |
6 | ~/Desktop/ |
ROOT_USER_MUSIC |
7 | ~/Music/ |
ROOT_USER_PICTURES |
8 | ~/Pictures/ |
ROOT_USER_VIDEOS |
9 | ~/Movies/ |
ROOT_SHOW |
10 | ProPresenter library directory |
Path Construction Example
For media at file:///Users/thorsten/Downloads/pp-test/Media/background.png:
URL.absolute_string = "file:///Users/thorsten/Downloads/pp-test/Media/background.png"
URL.local.root = ROOT_USER_DOWNLOADS (4)
URL.local.path = "pp-test/Media/background.png"
URL.platform = PLATFORM_MACOS
Media Metadata
| Field | Expected Value | Notes |
|---|---|---|
Metadata.format |
Lowercase: "png", "jpg", "mp4" |
PP7 uses lowercase |
Action.type |
ACTION_TYPE_MEDIA |
Media action type |
MediaType.layer_type |
LAYER_TYPE_FOREGROUND |
Default for slide media |
4. ZIP64 EOCD Quirk
Issue
ProPresenter 7 exports .probundle files with the same ZIP64 EOCD bug as .proplaylist files: a 98-byte discrepancy between the ZIP64 EOCD locator offset and the actual EOCD position.
Workaround
The reader applies Zip64Fixer before opening the archive. This searches backward from the end of file for the ZIP64 EOCD signature (0x06064b50) and corrects the offset.
Writer Behavior
The writer produces standard ZIPs without the bug. PHP's ZipArchive creates clean archives that PP7 imports without issues.
5. Differences from .proplaylist
| Aspect | .proplaylist |
.probundle |
|---|---|---|
| Purpose | Playlist with multiple songs | Single presentation with media |
| Compression | Store only (method 0) | Deflate (default) |
| Metadata entry | data file (protobuf rv.data.Playlist) |
None (.pro file IS the data) |
| Song entries | Multiple .pro files |
Single .pro file |
| Media paths | Absolute minus leading / |
Absolute with leading / |
| ZIP64 | Always ZIP64 | Standard ZIP (PP7 exports as ZIP64) |
6. Edge Cases
Bundles Without Media
- Valid. Archive contains only the
.profile. - Use case: Sharing a lyrics-only presentation.
Multiple Media Files
- Valid. Each media file gets its own ZIP entry at its absolute path.
- Deduplication: Same path stored once.
Non-Image Media
- Videos (
.mp4,.mov): Same URL format, differentMetadata.format. - Audio (
.mp3,.wav): Same pattern,MediaType.audiofield used.
Case Sensitivity
.profile detection is case-insensitive (.pro,.Pro,.PRO).- Media format strings should be lowercase to match PP7 behavior.
7. Reverse-Engineering Evidence
Reference Files
- TestBild.probundle: Generated by this library, verified importable by PP7 with image found
- RestBildExportFromPP.probundle: Exported by PP7 after import, used as comparison reference
Key Discoveries
- Absolute paths with leading
/: PP7 stores media at full absolute filesystem paths in the ZIP, including the leading/ URL.localis required: PP7 cannot find media without theLocalRelativePathinURL.localfile:///prefix required:URL.absolute_stringmust use thefile:///protocol prefix- Lowercase format: PP7 uses lowercase format strings (
"png"not"PNG") - Standard ZIP is fine: PP7 imports standard deflate-compressed ZIPs without issues — the ZIP64/store/permission quirks in PP7 exports are artifacts, not requirements
- ZIP64 EOCD bug: PP7 exports have the same 98-byte offset quirk as
.proplaylistfiles
What Didn't Work (Rejected Approaches)
- Relative media paths: PP7 cannot resolve
Media/image.png— needs absolute paths - Missing
URL.local: PP7 shows "image not found" withoutLocalRelativePath - Missing
file:///: Plain paths like/Users/me/image.pngare not recognized - Uppercase format:
"PNG"works but doesn't match PP7's own output - Forced store compression / 000 permissions: Unnecessary hacks that don't affect import
Appendix: PP7 Export vs Library Output
PP7 Export Characteristics (informational only)
- ZIP64 format with 98-byte EOCD offset bug
- Store compression (method 0)
- File permissions set to
0000 - These are PP7 artifacts — the library reader handles them, the writer doesn't reproduce them
Library Output Characteristics
- Standard ZIP (PKZIP 2.0+)
- Deflate compression (ZipArchive default)
- Normal file permissions
- PP7 imports these without issues
End of Specification