Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

Optimize-TrailCamMedia

A PowerShell pipeline for cleaning up trail camera photos and videos: it compresses video, figures out each file's true capture time even when the camera's clock drifted for DST, and geotags everything with the camera's deployment location, all without touching your original files.

Why this exists

Trail cameras have two annoying habits:

  1. They don't auto-adjust for Daylight Saving Time. If a camera is deployed before a DST transition and retrieved after, every timestamp from that point on is off by an hour, and the camera has no way of knowing this happened.
  2. Copying files off the SD card resets filesystem timestamps. CreationTime/LastWriteTime get set to "whenever you copied the file," not "whenever the camera actually took it." So you can't fix problem #1 by trusting the filesystem. You need the real capture time from somewhere the copy process didn't touch.

This script solves both, plus compresses video (trail cam footage is often needlessly large) and writes GPS coordinates so everything shows up in the right spot on a map when it lands in Google Photos or similar.

What it does

For every photo/video in a folder, the script:

  1. Determines the true capture time, in priority order:
    • Images → EXIF DateTimeOriginal (via ExifTool)
    • MP4 video → embedded creation_time (via ffprobe)
    • Video with no usable embedded metadata (typically AVI) → OCR of the on-screen timestamp burned into the video by the camera itself (via ffmpeg + Tesseract). This is opt-in: it only runs when you pass -UseTesseract.
    • Last resort → the filesystem's LastWriteTime, with a console warning. This is accurate as long as your copy method preserved the original modified date (a plain copy from the SD card in Explorer normally does). If something reset it, it'll just be the copy time (see Known limitations).
  2. Compresses video with ffmpeg, matching the source's video codec (h264/hevc/vp9) and re-encoding audio to AAC. Compressed videos are saved as <original name>_fixed.mp4. Images aren't re-encoded; they're copied as-is.
  3. Writes GPS coordinates to the output file via ExifTool, using the deployment location.
  4. Corrects the timestamp for a missed DST transition, by comparing the UTC offset in effect when you deployed the camera against the UTC offset that should apply at the true capture time. If they differ, the camera missed a transition, and the time is shifted by exactly the difference. This runs last on purpose: ExifTool rewrites the file when it writes GPS data, which resets the modified date, so the timestamp has to be set after that.

Every processed file ends up in a Fixed subfolder. Originals are never modified.

Requirements

Tool Used for Required?
ffmpeg Video compression, extracting a frame for OCR Yes
ffprobe (ships with ffmpeg) Reading codec info and embedded creation_time Yes
ExifTool Reading EXIF DateTimeOriginal, writing GPS coordinates Yes
Tesseract OCR Reading burned-in timestamps on video with no embedded metadata (typically AVI) Only if you pass -UseTesseract

Windows only. The script uses Shell.Application COM automation and System.Drawing, neither of which are available in PowerShell on Linux/macOS.

Usage

. .\Optimize-TrailCamMedia.ps1

Optimize-TrailCamMedia `
    -MediaFolder 'C:\tmp\media' `
    -ffmpegExe 'C:\ffmpeg\bin\ffmpeg.exe' `
    -ffprobeExe 'C:\ffmpeg\bin\ffprobe.exe' `
    -DeployedDate '2026-02-19' `
    -ExifToolExe 'C:\tmp\ExifTool.exe' `
    -Latitude 45.10880 `
    -Longitude -123.62527

If your camera produces AVI files (or any video without an embedded creation date), add -UseTesseract so the on-screen timestamp gets read instead of falling back to the filesystem date:

Optimize-TrailCamMedia `
    -MediaFolder 'C:\tmp\media' `
    -ffmpegExe 'C:\ffmpeg\bin\ffmpeg.exe' `
    -ffprobeExe 'C:\ffmpeg\bin\ffprobe.exe' `
    -DeployedDate '2026-02-19' `
    -ExifToolExe 'C:\tmp\ExifTool.exe' `
    -Latitude 45.10880 `
    -Longitude -123.62527 `
    -UseTesseract

Parameters

Parameter Required Description
-MediaFolder Yes Folder containing the photos/videos to process. Output goes to a Fixed subfolder created inside it.
-ffmpegExe Yes Path to ffmpeg.exe.
-ffprobeExe Yes Path to ffprobe.exe.
-DeployedDate Yes The real-world date/time you set the camera's clock when deploying it. Used to detect a missed DST transition.
-ExifToolExe Yes Path to ExifTool.exe.
-Latitude Yes Latitude in decimal degrees (e.g. 45.10880), written to every file's GPS metadata.
-Longitude Yes Longitude in decimal degrees (e.g. -123.62527, negative for West), written to every file's GPS metadata.
-UseTesseract No Switch. Enables OCR of the burned-in timestamp for video with no embedded creation date. Without it, those files fall back to the file's modified date. The script throws up front if tesseract.exe can't be found.
-Tesseract No Path to tesseract.exe. Defaults to the standard install path. Only used when -UseTesseract is specified.

Alongside the processed files, Fixed also gets a log.txt noting any files that were skipped (e.g. no readable "media created" value at all).

Known limitations

  • Without -UseTesseract, AVIs with no embedded date rely on the file's modified date. If a camera doesn't embed a creation_time/IDIT/ICRD chunk (common on cheaper trail cams), the only sources left are the burned-in on-screen timestamp (needs -UseTesseract) or the filesystem date. A plain copy from the SD card normally preserves Date modified, so the fallback is usually fine. But if your transfer method resets it (some phone/cloud syncs and copy tools do), the burned-in timestamp is the only surviving source of truth, and without OCR the output gets stamped with a date based on when you copied the file. The script warns in the console for each file that takes this fallback. To check your setup, compare a file's Date modified against its on-screen timestamp, or just use -UseTesseract.
  • OCR accuracy depends on your camera's overlay. It's only as good as the contrast and font of the on-screen timestamp, so it's worth spot-checking a few files per camera model.
  • AVI files have no write support in ExifTool. ExifTool can read AVI metadata but can't write to it. This is a limitation of ExifTool itself, not this script. GPS tagging happens on the compressed MP4 output in Fixed, not the original AVI, so it isn't an issue in practice. Just don't expect an original .avi to ever get tagged directly.
  • GPS on video uses a different write path than GPS on images, because MP4/MOV containers don't have an EXIF IFD the way JPEGs do. Writing an unsigned coordinate plus a separate hemisphere reference (the standard EXIF convention) gets silently reduced to a default positive hemisphere when ExifTool remaps it into the XMP-exif group used by video. That's a known quirk, not a bug in this script. Video coordinates are written as signed decimal values instead, which sidesteps the issue.
  • Windows only. COM automation (Shell.Application) and System.Drawing aren't available in PowerShell on other platforms.

License

MIT (or whatever you'd prefer, swap this out).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages