Skip to content

Instantly share code, notes, and snippets.

@joba-1
Last active August 7, 2024 21:42
Show Gist options
  • Save joba-1/bdff43371dee7e23f536e7da5e373116 to your computer and use it in GitHub Desktop.
Save joba-1/bdff43371dee7e23f536e7da5e373116 to your computer and use it in GitHub Desktop.
Fix wrong Gopro Hero7 2016 media timestamps from correct JPEG GPS metadata timestamps
"""
Read timestamps of jpegs from given or current directory.
If there are files with creation year 2016
and if the difference between creation date and gps date is the same for all those files
then fix metadata dates and file dates of all 2016 media files (not just the jpegs)
"""
TZ = 2*60 # desired difference in minutes between GPS (UTC) and TZ to use within media files
from subprocess import check_output
from datetime import datetime, timedelta
from sys import argv
from os import utime
from statistics import fmean
import json
def diff(cr, gd, gt):
created = datetime(int(cr[0:4]), int(cr[5:7]), int(cr[8:10]), int(cr[11:13]), int(cr[14:16]), int(cr[17:19]))
gps = datetime(int(gd[0:4]), int(gd[5:7]), int(gd[8:10]), int(gt[0:2]), int(gt[3:5]), int(gt[6:8]))
return timedelta.total_seconds(gps - created)
if len(argv) == 2:
dir = argv[1]
else:
dir = '.'
cmd = 'exiftool -j -CreateDate -GpsDateStamp -GpsTimeStamp -ext jpg'.split()
cmd.append(dir)
pics = json.loads(check_output(cmd))
pics = [{'file': pic['SourceFile'], 'diff': diff(pic['CreateDate'], pic['GPSDateStamp'], pic['GPSTimeStamp'])} for pic in pics if pic['CreateDate'].startswith('2016:') and 'GPSDateStamp' in pic]
if len(pics) == 0:
print(f'No 2016 jpegs found in {dir}')
exit
dmin = int(min([pic['diff'] for pic in pics]))
dmax = int(max([pic['diff'] for pic in pics]))
davg = round(fmean([pic['diff'] for pic in pics]))
if davg != dmax and davg != dmin:
print(f'multiple time differences found: min={dmin}, avg={davg}, max={dmax}')
exit
cmd = 'exiftool -j -CreateDate'.split()
cmd.append(dir)
meds = json.loads(check_output(cmd))
print(meds)
meds = [{'file': med['SourceFile'], 'date': med['CreateDate']} for med in meds if 'CreateDate' in med and med['CreateDate'].startswith('2016:')]
for med in meds:
cr = med['date']
created = datetime(int(cr[0:4]), int(cr[5:7]), int(cr[8:10]), int(cr[11:13]), int(cr[14:16]), int(cr[17:19]))
fixed = created + timedelta(seconds=davg + TZ*60)
fixed_str = fixed.strftime('%Y:%m:%d %H:%M:%S')
cmd = ['exiftool', f'-time:all="{fixed_str}"', '-wm', 'w']
cmd.append(med['file'])
result = check_output(cmd).decode()
fixed_ts = fixed.timestamp()
utime(med['file'], times=(fixed_ts, fixed_ts))
print(med['file'], result)
@joba-1
Copy link
Author

joba-1 commented Jul 20, 2024

@joba-1
Copy link
Author

joba-1 commented Aug 7, 2024

not all JPEGs of the gopro seem to get GPS timestamps -> changed script to only use those that got it.
(used on caba1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment