Skip to main content

gps-video-sync

Find each video's clock offset relative to an IGC GPS flight track. The offset maps timestamps in the video to UTC times on the track, even when the camera's date or time is wrong.

The tool uses camera GPS time when available and falls back to motion matching. It also checks clock drift and can plot the alignment. In a batch, two accepted recordings from the same camera can place clips which have otherwise weak evidence.

Install

Requires Python 3.10 or later. Tests cover Python 3.10 to 3.15.

uv tool install gps-video-sync

or with pip

pip install gps-video-sync

Align recordings

Match your recordings against an IGC flight track and save the results:

gps-video-sync sync takeoff.MP4 ridge.MP4 landing.MP4 --track flight.igc --json sync.json

Use one or more recordings, each listed once. Include all recordings from the flight to help align short clips. File order does not matter.

Each recording gets a result in sync.json. ok means it has an alignment. ambiguous means there is not enough reliable evidence. failed means the recording could not be processed. Other recordings still get their results.

Run gps-video-sync sync --help for more options. Results contain file paths and recording dates. Remove private data before sharing.

Use the Python API

from gps_video_sync import match_videos, read_track, read_video, synchronize

track = read_track("flight.igc")
results = match_videos(track, ["takeoff.MP4", "ridge.MP4", "landing.MP4"])
for result in results:
    print(result.video, result.status, result.offset_seconds)

telemetry = read_video("ridge.MP4", hz=10)
result = synchronize(track, telemetry)

match_videos returns one result per input, in input order. It joins confirmed continuous chapters and places unresolved clips from camera-session anchors. A file error gives a failed result for that file only. read_video reads one recording. synchronize matches one recording and also accepts array-based Telemetry.

To match exported telemetry, use source="npz" in the API or --source npz in the CLI. NPZ exports from telemetry --out keep the original recording identity, duration, media offset, and optional recording-clock and camera-start evidence. Telemetry.slice clears both kinds of timing evidence. In a batch result, input_file identifies the NPZ archive.

The result maps video seconds to UTC seconds from midnight of the track date:

utc_seconds = video_seconds * clockRate + offset_seconds

Supported cameras

The bundled test recordings are from a GoPro HERO11 Black. They test motion alignment but contain no GPS data. GPS extraction and alignment have synthetic tests only. GoPro documents compatible metadata for the other models below, but this package has no recordings from them. Their extraction, alignment, and frame verification are untested.

The reader needs a timed GPMF track with sample format gpmd in the original video. It uses these fields:

  • GPS9 supplies UTC and fix status for GPS alignment. The older GPS5 format needs GPSU for UTC and GPSF for fix status. The reader accepts only valid 3D fixes. GPS9 takes priority when both formats occur in a packet.
  • GYRO and ACCL supply the motion features. Motion alignment works without camera GPS, within the limits below.
  • The reader also extracts GRAV, CORI, and IORI when present. Alignment does not need these fields. The matcher estimates gravity from ACCL.
Camera GPS metadata for UTC alignment GYRO + ACCL GRAV + CORI + IORI Compatibility / test status
HERO5 Black GPS5 + GPSU + GPSF Yes Not documented GPS and motion expected; untested
HERO5 Session None Yes Not documented Motion only expected; untested
HERO6 Black GPS5 + GPSU + GPSF Yes Not documented GPS and motion expected; untested
HERO7 Black GPS5 + GPSU + GPSF Yes Not documented GPS and motion expected; untested
HERO8 Black GPS5 + GPSU + GPSF Yes Yes GPS and motion expected; untested
HERO9 Black GPS5 + GPSU + GPSF Yes Yes GPS and motion expected; untested
HERO10 Black GPS5 + GPSU + GPSF Yes Yes GPS and motion expected; untested
HERO10 Black Bones None Yes Yes Motion only expected; untested
HERO11 Black GPS9, plus legacy GPS5 Yes Yes Motion tested with bundled recordings; GPS untested
HERO12 Black None Yes Yes Motion only expected; untested
HERO13 Black GPS9 Yes Yes GPS and motion expected; untested
Fusion Not documented in the cited table Yes Not documented Motion metadata compatible; 360 workflow untested
MAX GPS5 + GPSU + GPSF Yes Yes Metadata compatible; 360 workflow untested
MAX2 GPS9 Yes Yes Metadata compatible; 360 workflow untested
MISSION 1 family GPS9 Yes Yes Metadata compatible per GoPro; untested

Use original, normal-speed recordings. Enable GPS on cameras that have it and wait for a satellite lock before you record. Some clips can still lack usable fixes. Edited, transcoded, or stitched exports can omit the metadata track. Check each recording with gps-video-sync info.

The 360 camera rows cover sensor metadata only. Stitching, projection, and frame extraction from native 360 files are untested.

The table does not cover Silver, White, Mini, or entry-level HERO models, HERO4 and earlier cameras, external GPS accessories, or special recording modes. A model number or GPS chip alone does not establish compatibility.

Sources:

Firmware and recording mode can change the available streams. The reader checks for metadata keys, not camera model names.

Limits

GoPro extraction allows at most 1,000,000 resampled samples per recording. Lower --hz if the recording duration in seconds multiplied by --hz exceeds this limit.

Motion matching needs at least 90 seconds of usable overlap. The overlap must also cover at least 65% of the shorter feature sequence. Each independent file or confirmed continuous group needs enough varying motion. Repeated turns, data gaps, or low motion can produce ambiguous or false matches. Check the plot and distinctive events before you use an alignment. Short clips cannot establish clock stability. Session placement uses other accepted recordings to place such clips. A GPS UTC step blocks placement. A continuity candidate with no approved common mapping cannot use session placement when it retains an accepted member.

See the API and format reference for data contracts, plugins, telemetry formats, and matching limits.

Run the tests

uv sync --extra dev --extra verify
uv run pytest
uv run python scripts/check_independent_videos.py
uv run python scripts/check_continuous_videos.py

Run the tests from a repository checkout. Release archives exclude tests and fixtures. The bundled fixtures contain flight coordinates, times, and media.

  • Extraction and alignment tests need no external program.
  • Parity tests use the ffprobe marker and need ffprobe 9 or later.
  • Frame tests need ffmpeg and Matplotlib.
  • To skip integration tests, run uv run pytest -m 'not integration'.

scripts/check_continuous_videos.py needs the verify extra and ffmpeg. It runs the API and the CLI on the bundled recordings with cold and warm caches. It checks exact boundaries, reordered inputs, subsets, weak chapters, non-unit drift, gaps, overlaps, counters, contradictory fits, and failures. It also checks cache rebuilds, NPZ and JSON exports, crops, saved-result selection, plots, and frames against direct FFmpeg seeks.

scripts/check_independent_videos.py checks independent motion crops and GPS recordings with gaps, overlaps, shuffled inputs, and isolated failures. It also checks exports and file-local frame extraction on the bundled videos.

Check an alignment visually

Check an alignment with a plot:

gps-video-sync verify ridge.MP4 --track flight.igc --result sync.json --output ridge.png

Plot output requires the verify extra. Install it with uv tool install 'gps-video-sync[verify]'.

License

MIT.

Metadata

Release files for gps-video-sync 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gps-video-sync 1.1.0
File Size Uploaded Provenance
gps_video_sync-1.1.0.tar.gz 47.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for gps-video-sync 1.1.0
File Interpreter ABI Platform
gps_video_sync-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 89.9 kB

Release files / gps_video_sync-1.1.0.tar.gz

Download URL gps_video_sync-1.1.0.tar.gz
Size 47.8 kB
Tags Source
SHA-256 checksum
How to use checksums
9d0640eb46d4adca89ca9a62c350e76054ff556bd5cee8893f61c663d5f51d53
BLAKE2b-256 checksum
How to use checksums
f9a4f6c4fb57c021e4c370a951b07e6c6c3e5b0ab85b86238d09f979c89f828e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Release files / gps_video_sync-1.1.0-py3-none-any.whl

Download URL gps_video_sync-1.1.0-py3-none-any.whl
Size 42.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4621064e8414a13f2a1609802a2a6e3943512e3c29787f451bcd8fd0ac65cb19
BLAKE2b-256 checksum
How to use checksums
c9831f03c116a331cfcddafdfd34673f060377dd2b1f39271f69e98b609f1d75
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

Security for gps-video-sync 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for gps_video_sync-1.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page