Recording-time + audio-waveform multicam sync for Premiere Pro — a UXP plugin with a bundled FFmpeg decoder.
Syncitol resolves each clip's real recording start time (embedded creation-time/timecode metadata, falling back to file dates), lays every clip out on a new timeline so gaps match real clock time, then fine-aligns the audio by waveform cross-correlation. One click ("Auto Sync") runs the whole pipeline.
- No ffmpeg install. The decoder is a bundled native hybrid addon
(
win/x64/syncitol.uxpaddon, 2.3 MB) — a trimmed, statically linked LGPL FFmpeg 8.1.2 (audio demuxers/decoders only).probe()reads metadata,decodePcm()decodes audio. No PATH setup, no external downloads. - Tiny install.
npm run buildproduces a ~1.3 MB.ccx.
Verified end-to-end on Premiere Pro 26.3 (Windows) against a real 30-file
two-camera shoot: Auto Sync (scan → build → coarse+fine align) syncs every
file, multi-track A/V link groups survive the build, and the coarse pass
resolves from Premiere's .pek peak cache with no audio decoding.
| Area | State |
|---|---|
DSP / sync brain (js/dsp.js) |
Envelope cross-correlation, coarse search policy, pek parsing, drift probes, learned-offset search — npm test 45/45 |
| Native FFmpeg addon | Compiled, self-contained (only Windows system DLL imports), verified in-panel |
Host ops (js/premiere.js) |
Verified live: scan, clone-based Build (createMoveAction, not createSetStartAction — see note), transactional shifts, undo = one step |
Engine (js/main.js) |
Staged coarse (pek → timecode → timestamp → learned → head → full), fine pass with rail guard, clock-drift report, cancel, boundary compensation |
| Caches | Envelope disk cache in the plugin data folder (30-day prune); .pek/.mcdb index via UXP fs |
| UI | Auto Sync, manual steps, Detected Clips + Sync Results tables, score badges, Revert, Cancel, active-sequence polling, instructions overlay |
| Packaging | npm run build → dist/Syncitol-UXP-<version>.ccx (minimal staging; never bundles native sources or shared FFmpeg DLLs) |
- DSP (pure):
js/dsp.js— envelopes, cross-correlation, coarse policy,.pekparsing, timecode.buildEnvelopetakes anInt16Array(from the addon) and the pek readers acceptArrayBuffer(UXP fs) or NodeBuffer(tests). Unit-tested withnode --test. - Audio (JS → native):
js/audio.js— wraps the addon; per-run memory cache + persistent disk envelope cache keyed by path+mtime+size+slice. - Pek fast path:
js/pek.js— maps media →.pekvia Adobe's.mcdbmedia-cache records and serves coarse envelopes straight from the peaks. - Host (JS → UXP DOM):
js/premiere.js— scan, clone-based build, delta moves, rename, all insidelockedAccess+executeTransaction.
createSetStartActionthrows "Invalid parameter" whenever a new start lands inside another clip's span — timeline reshuffles must use the delta-basedcreateMoveAction.- Moving an item does NOT move its linked items; shift every member of a link group by the same delta. Links (including 4-item MXF video+3×audio groups) survive clone + move — no re-link API is needed (UXP has none).
Constants.TrackItemType: EMPTY 0, CLIP 1, TRANSITION 2, PREVIEW 3, FEEDBACK 4.- UXP
<button>widgets ignore author CSS backgrounds — actions are styled<div class="btn">elements with an.is-disabledclass.
- Load: UXP Developer Tool, or the CLI:
uxp service start, thenuxp plugin load|reload --apps premiereprofrom this folder. - Offline checks:
npm run lint(parse gate) andnpm test(DSP suite). - Dev harness:
js/selftest.js(dev-only; stripped from the.ccx) runs the command named indebug-command.jsonon panel load and writesdebug-report.json— commands cover env probes, host-API shape dumps, build/shift round-trips and position comparisons.
Load the folder via the UXP Developer Tool (a self-built .ccx is unsigned,
and Creative Cloud only installs packages signed through Adobe's Developer
Distribution portal — submit there for a one-click installable build).
Premiere Pro 26.0+ on Windows x64. The bundled FFmpeg decoder is a UXP hybrid addon; Premiere 25.x loads the panel but reports "Addon is not supported", so 26.0 is the real floor. macOS needs the addon compiled for arm64/x64 on a Mac (source lives in the native build workspace) — not yet built.
node scripts/set-version.js 1.2.3— updates manifest, package.json and the panel footer together.npm run build— stages the runtime files only and zips them (forward-slash entries) intodist/Syncitol-UXP-<version>.ccx, failing if the package is suspiciously large.
Bundling FFmpeg means complying with the LGPL v2.1+: the addon links an
LGPL-configured FFmpeg 8.1.2 (--disable-everything + audio-only components),
no GPL components enabled. FFmpeg source: https://ffmpeg.org. IBM Plex fonts
under the OFL (fonts/LICENSE.txt). If distributed commercially, ship an
offer to provide the FFmpeg build scripts/objects for relinking.