Last active
August 7, 2024 21:42
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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) |
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
posted about it at https://community.gopro.com/s/profile/005Uv0000026pJd and https://exiftool.org/forum/index.php?topic=16254.0