A native macOS app that merges Panasonic P2 card clips into self-contained MXF or MOV files — without re-encoding.
Panasonic P2 cameras (AJ-PX5000G, AJ-HPX, VariCam LT, etc.) record in MXF OP-Atom — video and each audio channel are separate files:
CONTENTS/
├── VIDEO/
│ └── 0001AB.MXF ← video only (AVC-Intra)
└── AUDIO/
├── 0001AB00.MXF ← audio channel 1
├── 0001AB01.MXF ← audio channel 2
├── 0001AB02.MXF ← audio channel 3
└── 0001AB03.MXF ← audio channel 4
Most NLEs handle this fine. But MAM systems, archive workflows, and delivery specs often require a single self-contained file (MXF OP1a or MOV).
FFmpeg can't do this for P2 AVC-Intra — it chokes on Panasonic's proprietary frame padding:
[mxf @ ...] track 0: frame size does not match index unit size, 568320 != 568832
P2toMXF solves this using the BMX toolkit (BBC) which has Panasonic-specific lookup tables, then chains to FFmpeg for concatenation. The result is bit-for-bit identical video and audio — only the container changes.
Screenshots coming soon
- Merge & Concatenate — Combine multiple clips into a single output file
- Individual Export — Rewrap each clip to its own self-contained file
- Batch Queue — Queue multiple jobs, process sequentially
- Multi-Card Loading — Load all P2 cards from a parent folder at once (Cmd+O)
- Output Verification — Quick or full decode tests on converted files
- Timecode Preservation — Original P2 timecodes carried through
- Audio Remapping — All channels, stereo mix, or mono
- Time Estimation — Learns from past conversions for accurate ETAs
- Sleep Prevention — Keeps Mac awake during long batch runs
| Output | Container | Typical Use |
|---|---|---|
| MXF OP1a | .mxf |
Broadcast, MAM, archive |
| QuickTime | .mov |
NLE editing, general delivery |
- Download the latest DMG from Releases
- Open the DMG and drag P2toMXF to Applications
- On first launch, right-click > Open (macOS Gatekeeper)
Requirements: macOS 14.0+ (Sonoma), Apple Silicon (arm64)
git clone https://github.com/Xpycode/P2toMXF.git
cd P2toMXF
open 01_Project/P2toMXF.xcodeprojBuild with Xcode 16+ (Cmd+B). All dependencies (FFmpeg, BMX) are bundled in the project.
- Load a P2 Card — Cmd+O or click "Load P2 Card". Select a card or a folder containing multiple cards.
- Select Clips — Click clips to select, or use Select All. Clips are grouped by recording span.
- Choose Settings — Output format (MXF/MOV), mode (Merge/Individual), audio mapping
- Set Output — Choose destination folder and filename
- Convert — "Convert Now" for immediate processing, or "Add to Queue" for batch
| Shortcut | Action |
|---|---|
| Cmd+O | Open P2 card picker |
| Cmd+A | Select all clips |
P2 Card (OP-Atom) BMX FFmpeg
┌─────────────┐ ┌──────────┐ ┌──────────┐
│ VIDEO/*.MXF │──▶│bmxtrans- │───▶│ concat │───▶ Final
│ AUDIO/*.MXF │ │wrap -t │OP1a│ demuxer │ MXF/MOV
└─────────────┘ │op1a │ └──────────┘
└──────────┘
- BMX rewraps each P2 clip (1 video + 4 audio files) into a single OP1a MXF
- FFmpeg concatenates the OP1a MXFs into the final output (stream copy, no re-encoding)
All operations are stream copy — no transcoding. Typical throughput:
| Operation | Speed |
|---|---|
| BMX rewrap | ~30x realtime |
| FFmpeg concat | ~60x realtime |
| 16 clips merged | ~1-2 minutes |
Everything runs self-contained — no Homebrew, no PATH setup:
| Tool | Version | Purpose |
|---|---|---|
| FFmpeg | 8.0.1 | Concatenation, verification, thumbnails |
| bmxtranswrap | 1.2 | OP-Atom to OP1a rewrapping |
| mxf2raw | 1.2 | MXF inspection |
01_Project/P2toMXF/
├── P2toMXFApp.swift # App entry point
├── ContentView.swift # Main three-column layout
├── ConversionViewModel.swift # Core state
├── ConversionViewModel+CardManagement.swift
├── ConversionViewModel+Conversion.swift
├── ConversionViewModel+RecordGroups.swift
├── Models/
│ ├── P2Clip.swift # P2 card/clip data models
│ ├── ConversionJob.swift # Queue job model
│ ├── ProgressModels.swift # Metrics, estimates
│ └── VerificationModels.swift
├── Services/
│ ├── P2CardParser.swift # P2 XML metadata parsing
│ ├── FFmpegWrapper.swift # FFmpeg process management
│ ├── FFmpegWrapper+Conversion.swift # Rewrap and merge logic
│ ├── FFmpegWrapper+Thumbnails.swift # Frame extraction
│ ├── BMXWrapper.swift # BMX toolkit wrapper
│ ├── QueueManager.swift # Job queue + persistence
│ ├── QueueManager+Processing.swift
│ ├── QueueManager+Operations.swift
│ ├── QueueManager+Verification.swift
│ ├── VerificationService.swift # Decode verification
│ ├── SpeedTracker.swift # Historical speed data
│ └── ThumbnailManager.swift # Async thumbnail cache
├── Views/ # SwiftUI views
└── Resources/
├── ffmpeg, bmxtranswrap, mxf2raw # Bundled binaries
└── lib/ # BMX dylibs
Only needed if you want to update the bundled BMX version:
brew install cmake uriparser expat
git clone https://github.com/bbc/bmx.git
cd bmx && mkdir -p out/build && cd out/build
export CMAKE_PREFIX_PATH="/opt/homebrew/opt/expat;/opt/homebrew/opt/uriparser"
cmake ../../ -DCMAKE_BUILD_TYPE=Release
cmake --build . -j$(sysctl -n hw.ncpu)See CLAUDE.md for library bundling and code signing details.
MIT License. See LICENSE for details.
- FFmpeg — LGPL/GPL (ffmpeg.org)
- BMX — BSD 3-Clause (github.com/bbc/bmx)
Contributions welcome. See CLAUDE.md for architecture documentation.
- BBC BMX Project — the MXF toolkit that makes this possible
- FFmpeg — multimedia Swiss Army knife
- App icon by NanoBanana