Skip to main content

Multicam audio sync and director-style auto-edit — align N angles of one event by audio cross-correlation, then cut/PiP them into one MP4. Reversible sidecars, never re-encodes the originals.

Project description

polysync

Multicam audio sync + director-style auto-edit. Align N recordings of the same event by audio cross-correlation, then cut or picture-in-picture them into a single MP4 — driven entirely by who's talking.

What makes it different from "yet another sync tool":

  • Reversible sidecars, never re-encodes the originals. Sync writes a tiny <input>.sync.json next to each file holding a single offset. A 75-min 4K 3-camera shoot is 250+ GB; baking offsets into re-encoded copies would double that and lose quality. Downstream applies the offset with ffmpeg -itsoffset at consume time. Originals are touched read-only, always.
  • Envelope cross-correlation, not raw waveform. Matches the log-energy envelope, which both mics hear regardless of their frequency response — robust even when a second camera's on-board mic sounds nothing like the main one.
  • Clock-drift aware. Cheap recorders drift 5–50 ppm; polysync fits the drift across the recording and reports it separately, so long-form lip-sync can correct it while camera-cut editing can ignore it.
  • Handles the messy real cases. Auto-picks the loudest audio track (pro cameras often leave track 1 dead), partial-coverage clips that only span part of the session, and independent verification of the result.

Install

pip install polysync          # once published
# or, from a checkout:
pip install -e ".[dev]"

Requires Python ≥ 3.9 and ffmpeg / ffprobe on your PATH (brew install ffmpeg, apt install ffmpeg, …). Python deps: numpy, scipy.

Quickstart

# 1. Sync each angle to a reference camera (writes <file>.sync.json sidecars)
polysync sync  CAM_A.mp4 CAM_B.mxf
polysync sync  CAM_A.mp4 CAM_C.mxf

# 2. (optional) Verify the alignment — re-checks residual independently
polysync verify CAM_A.mp4 CAM_B.mxf CAM_B.mxf.sync.json

# 3. Build an auto-edit decision list (who's on screen each second)
polysync edit  CAM_A.mp4 CAM_B.mxf CAM_C.mxf --out edl.json

# 4. Render — hard cuts, or with a picture-in-picture inset
polysync render-cuts edl.json --out final.mp4
polysync render-pip  edl.json --out final.mp4 --pip bottom-right

A clip that only covers part of the session (a Riverside / phone / lavalier recording that started mid-way):

polysync sync REFERENCE.mp4 PARTIAL.m4a --partial

How it consumes the sidecar

delta_seconds is the source's t=0 in the reference's timeline (positive = source starts later). To align by hand:

ffmpeg -itsoffset $(jq -r .delta_seconds CAM_B.mxf.sync.json) -i CAM_B.mxf \
       -i CAM_A.mp4 -filter_complex "[0:v][1:v]hstack" out.mp4

The edit / render-* commands read every sidecar automatically.

Python API

from polysync import compute_sync           # pure-numpy core, unit-testable
from polysync.sync import sync_files         # file → sidecar
from polysync.verify import verify_files
from polysync.edit import build_edl

Status

Beta (0.1). Sync + verify are battle-tested on real Sony FX3/FX6 multicam interview footage; the auto-edit is audio-energy-driven (no face detection). Issues and PRs welcome.

License

MIT © 王建硕 (Jian Shuo Wang)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polysync-0.1.0.tar.gz (21.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

polysync-0.1.0-py3-none-any.whl (23.4 kB view details)

Uploaded Python 3

File details

Details for the file polysync-0.1.0.tar.gz.

File metadata

  • Download URL: polysync-0.1.0.tar.gz
  • Upload date:
  • Size: 21.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for polysync-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f17ae6c136facb66b855e6c592254d725597ad243f44e381a045b9b4dcfbabc0
MD5 2e988208a84e47a6760af8dceb671bd7
BLAKE2b-256 9bb8ffd83a971d635db19f03353ca82562a6a8bd9b5bf43c30298c287146d791

See more details on using hashes here.

Provenance

The following attestation bundles were made for polysync-0.1.0.tar.gz:

Publisher: publish.yml on jianshuo/polysync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file polysync-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: polysync-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for polysync-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a815bc9d04be3a1eecffea0693fe27b06dc132661838a555c8161c0aa05b0750
MD5 76eaf0b99682c361fcb27430bc0128ef
BLAKE2b-256 8224cd696f8ee2ee73d6bbcbf7da11aa5309027968b54bf9832aa697b18f19fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for polysync-0.1.0-py3-none-any.whl:

Publisher: publish.yml on jianshuo/polysync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page