Lightroom Classic writes XMP sidecars for photos but not for videos, so everything I type on a video stays trapped in the catalog. I wrote this plugin so my media asset pipeline sees captions, keywords, and GPS on video files the same way it sees them on raw stills.
A Lightroom Classic plugin that writes standard XMP sidecar files for videos. Select videos, run the export, and each one gets a companion file carrying its captions, keywords, GPS, ratings, and camera details, readable by any tool that understands XMP.
Lightroom's developer SDK returns nothing for these fields on video, so the plugin reads them directly from the catalog database, always in read-only mode. It adds the video's own technical facts (resolution, frame rate, duration), offers a preview of every sidecar before writing, and can run standalone on a folder of videos without Lightroom.
Features
- Saves each selected video's details into a standard companion file right next to the video, where any other program can read them
- Frees the titles, captions, locations, and copyright details that Lightroom otherwise keeps locked inside its catalog
- Carries everything worth carrying, keywords, ratings, GPS, camera and lens details, the video's own technical facts, and the full professional set from creator contact to usage rights
- Keywords you have marked as do-not-export stay private, matching how Lightroom exports photos
- Preview mode shows exactly what would be written before any file is saved
- Runs on its own over a whole folder of videos, no Lightroom needed
- Keeps working across Lightroom version upgrades
- Never touches the catalog itself: everything is read-only, so nothing can be damaged
Under the hood
- —Reads IPTC fields for videos straight from the .lrcat SQLite catalog, the one place Lightroom actually stores them; the SDK returns nothing for these fields on video, so direct catalog access is the only complete path
- —Catalog is opened read-only at the SQLite level (mode=ro), and its schema is probed at runtime with PRAGMA table_info rather than hard-coded, so the plugin cannot corrupt the database and survives Lightroom upgrades that shuffle columns
- —Sidecars use the standard XMP namespaces (dc, photoshop, Iptc4xmpCore, xmpDM, exif, tiff) and cover the IPTC Extension and rights fields, so any conformant tool reads them without knowing this plugin exists
- —Video technicals come from ffprobe and camera EXIF from exiftool; both are located at startup across common Homebrew and system paths because Lightroom launches subprocesses with a minimal PATH
- —Metadata is normalized on the way out, GPS parsed from both decimal and degrees-minutes-seconds forms, frame dimensions swapped for 90 and 270 degree rotations, and keywords filtered by Lightroom's include-on-export flag, so sidecars match what Lightroom itself would export for a photo
- —SDK calls run inside Lightroom's async task wrapper because SDK methods yield internally and plain Lua pcall blocks those yields
- —Two-part build, a thin Lua plugin driving a Python subprocess: Lua handles Lightroom selection and UI, Python does catalog reads and XMP generation, and the same Python core doubles as a standalone CLI
