Robust Google Takeout metadata fixer and Google Photos Takeout metadata fixer for restoring EXIF dates, GPS, descriptions, people tags, and video timestamps from Google Takeout JSON sidecars.
This project is built for one job: take messy Google Photos / Google Takeout exports and turn them back into a clean, portable media library with correct metadata embedded into the actual files.
Project description for GitHub homepage:
Robust Google Takeout / Google Photos Takeout metadata fixer that restores EXIF dates, GPS, descriptions, people tags, and video timestamps from JSON sidecars.
Google Takeout often separates important metadata from the original media file and stores it in JSON sidecars. That breaks photo timelines, maps, descriptions, and portability across tools like Google Photos, Apple Photos, Windows Photos, Immich, Lightroom, PhotoPrism, and plain file explorers.
This project fixes that by reading the Takeout JSON sidecars and writing the metadata back into the media files themselves with ExifTool.
| Feature | This tool | gpth | google-photos-migrate | GoogleTakeoutFixer |
|---|---|---|---|---|
| Writes real EXIF dates | ✅ | ❌ file timestamps only | ✅ | ✅ |
| Writes GPS coordinates | ✅ | ❌ | ✅ | ✅ |
| Writes descriptions | ✅ | ❌ | ✅ | ✅ |
| Writes people tags | ✅ | ❌ | ❌ | ❌ |
| Handles videos well | ✅ | ❌ | ✅ | ✅ |
Supports new supplemental-metadata names |
✅ | ❌ | ❌ | ❌ |
| Handles truncated JSON names | ✅ | ✅ | ✅ | ✅ |
| Handles edited filenames in 12+ languages | ✅ | ✅ | Partial | ❌ |
| Handles live photo pairing | ✅ | ❌ | ✅ | ✅ |
Falls back to JSON title matching |
✅ | ❌ | ✅ | ❌ |
| Reads zips directly from Android over ADB | ✅ | ❌ | ❌ | ❌ |
| Works without extracting zips locally | ✅ | ❌ | ❌ | ❌ |
| Resume support | ✅ | ❌ | ❌ | ❌ |
| Recovery path for broken zip listings | ✅ | ❌ | ❌ | ❌ |
After processing, your files can contain:
- Correct capture dates via
DateTimeOriginal,CreateDate, and related video timestamps - GPS latitude, longitude, and altitude
- Descriptions via
ImageDescription - People tags via
XMP:PersonInImage - Better portability across photo managers because metadata is embedded in the media file itself
- Robust Google Takeout metadata fixer for both local zip files and Android-hosted zip files
- Google Photos Takeout metadata fixer focused on correct embedded dates, not only filesystem timestamps
- Full JSON sidecar matching for Google’s newer
supplemental-metadatanaming scheme - Truncation handling for long filenames and sidecar names
- Duplicate file handling such as
photo(2).jpg - Edited-file suffix support in 12+ languages
- Live photo still/video matching
- JSON
titlefallback matching when filenames are inconsistent - Resume support for interrupted runs
- Batched ExifTool execution for speed and reduced overhead
- ADB mode for streaming sidecars from the phone without consuming huge extra local disk space
- Specialized recovery helper for problematic zips whose central directory can still be read even when standard unzip listing is unreliable
- Python 3.9+
- ExifTool on your
PATH - ADB on your
PATHfor Android / phone mode
Install optional downloader dependencies:
pip install -r requirements.txtLocal zip mode:
python google_takeout_metadata_fixer.py --output ./Output --local-zips ./takeout-zipsADB / phone mode:
python google_takeout_metadata_fixer.py --output ./Output --phone-dir /sdcard/DownloadDry run:
python google_takeout_metadata_fixer.py --output ./Output --local-zips ./takeout-zips --dry-runpython extract_takeout_media.py --adb /sdcard/Download --output ./Outputpython adb_resumable_copy.py --source-dir ./Output --dest-dir /sdcard/Download/Outputpython recover_takeout_zip_metadata.py --remote-zip /sdcard/Download/takeout-example.zip --output ./Output- Lists zip contents to discover media files and JSON sidecars
- Extracts only metadata sidecars where possible instead of exploding entire archives
- Applies layered matching rules to pair the right JSON with the right media file
- Converts JSON metadata into ExifTool arguments
- Writes metadata in batches and saves progress so interrupted runs can resume safely
Google Takeout sidecars are inconsistent. This project handles all of these patterns:
| Pattern | Example |
|---|---|
| Standard sidecar | photo.jpg.supplemental-metadata.json |
| Truncated sidecar | photo.jpg.supplemental-metad.json |
| Duplicate suffix | photo.jpg.supplemental-metadata(2).json |
| Older export format | photo.jpg.json or photo.json |
| Bracket variants | photo.jpg(1).json |
| Edited filename variants | photo-edited.jpg -> original photo JSON |
| Live photo mapping | video file matched to still image JSON |
| JSON title fallback | uses the title field from the JSON |
Supported edited suffixes include English, German, French, Spanish, Portuguese, Italian, Dutch, Polish, Swedish, Finnish, Turkish, Russian, and Japanese variants already seen in real exports.
DateTimeOriginalCreateDateModifyDateGPSLatitudeGPSLongitudeGPSAltitudeImageDescriptionXMP:PersonInImage
All of the above where applicable, plus:
TrackCreateDateTrackModifyDateMediaCreateDateMediaModifyDate
- OAuth secrets and tokens are ignored via
.gitignore - Generated logs and progress files are ignored
- Local absolute paths have been removed from publishable helper scripts
- The repo is intended to be safe to push after you verify any local untracked files you want to keep out of version control
| File | Purpose |
|---|---|
google_takeout_metadata_fixer.py |
Main Google Takeout metadata fixer |
extract_takeout_media.py |
Extract media from Takeout zips, including ADB mode |
recover_takeout_zip_metadata.py |
Recovery helper for problematic zip listings over ADB |
adb_resumable_copy.py |
Resumable ADB copy helper back to phone storage |
google_photos_downloader.py |
Optional Google Photos downloader using your own API credentials |
If this project saves you time, storage, or a broken migration, you can support continued maintenance here:
MIT
Pull requests and issue reports are welcome, especially for:
- New Google Takeout naming edge cases
- More edited filename language variants
- Better zip recovery and matching heuristics
- Test cases from unusual Takeout exports