← Blog

My cameras couldn't agree what day it was

In 2023 I filmed kitchen installs for The Kitchen Fitter, a timelapse channel on YouTube. A cabinetmaker did the fitting and I did the filming, with three or four cameras running all day on each job: GoPros, a Sony and a phone, all filming the same room. Then life got in the way. Nearly 800 GB of footage sat on my NAS for two years, most of it never edited.

This month I started working through it with Claude Code. Before cutting anything, I needed to know what was actually on the drive. The folders weren’t much help. Some were named after the job, some after the camera, and a few after what I happened to be wearing that day: white nike T, black adidas, gray shirt white kitchen. Useful in 2023. Meaningless now.

The files know more than the folders

Every clip carries its own metadata. There’s a creation time. A GoPro writes a firmware tag that names the model, plus a telemetry stream with GPS in it. A Sony adds a metadata stream of its own. So instead of trusting the folders, Claude built a catalogue straight from the files: 282 videos, sorted by their metadata alone.

The videos are multi-camera. The edit cuts between angles of the same moment, so everything depends on knowing when each clip started. The timestamp is the whole job.

One day, two dates

The first pass read every creation time as written. The biggest build, the one I most wanted to edit, apparently started at 9:27 pm the night before and ran until just before 4 the next afternoon. Nobody was installing a kitchen at 9:27 pm.

Every one of those timestamps ends in a Z, which means UTC. Fine: believe it, and convert to Brisbane time (UTC+10, no daylight saving). Now the Sony starts at a sensible 7:27 am. But the GoPros now run from 5:27 pm until nearly 2 in the morning.

Three timelines of the same 41 clips. Read as written, the Sony and phone clips start the evening before. Trusting the UTC label, the GoPro clips run past midnight. With a rule per camera, every clip lands in one working day from 7:27 am to 4:10 pm

The same 41 clips, three ways. Only the bottom row is a day anyone worked.

Neither reading works, because the cameras don’t agree on what the Z means.

Four clocks, four conventions

SourceWhat the timestamp really is
GoProBrisbane local time, labelled as UTC, at the start of recording
SonyTrue UTC, at the start
PhoneTrue UTC, at the end of recording
An edited exportWhen it was exported. Not a filming time at all

The GoPro is set to local time and writes it out with a Z stuck on the end. The Sony is honest. The phone is honest about the time zone, but it stamps the moment you stop recording, not the moment you start. The longest phone clip ran 2 hours 38 minutes, so reading its stamp as a start puts it 2 hours 38 minutes late. That’s the long green bar hanging off the end of the day in the middle row.

Proving it, with nothing to check against

Nobody wrote down when anything was filmed, so each rule had to prove itself from the files. Three checks did it:

  • A file can’t be finished before it starts. One GoPro clip is stamped 07:35:47Z and runs 8 minutes 52 seconds. The file’s last-modified time is 21:44:39 UTC the evening before, which is 7:44:39 am in Brisbane. That’s the exact second the recording ended, if 07:35:47 was local time. If the Z were true, the camera finished writing the file ten hours before it started filming.
  • Phones put the start time in the filename. On all 18 phone clips that have one, the metadata stamp minus the clip’s length lands within four seconds of the filename. Read as a start time, each one is out by its own length.
  • One camera can’t record two clips at once. Read as start times, the Sony clips run through the day in order, with a single 11-second overlap. Read as end times, five of the eleven hand-offs overlap, one by nearly three hours.

Claude got one of these wrong first. Its first pass treated the phone stamps as start times, like everything else. The project’s own architecture notes already said phones stamp the end. Reading those notes caught an error that a fresh derivation had missed, which is a lesson I keep relearning.

Two more traps in the same metadata

GoPro chapters. A GoPro splits a long recording into chapter files. The Hero 7 stamps each chapter with its own start time. The Hero 9 and Hero 10 stamp every chapter with the first chapter’s time. Thirteen recordings were split that way, and uncorrected, the last chapter of the worst one lands 87 minutes early. The fix only runs when every chapter in a group shares one timestamp. It checks rather than assumes, because the models disagree.

GPS that remembers the last job. GoPros log a GPS position with a fix quality. Indoors they rarely get a satellite lock, and 86 of the 191 GoPro clips with GPS data had none. Without a lock, the camera reports the last place it had one. On the biggest build, the Hero 7 reported the site of the previous job, 29 km away and twelve days earlier. An unlocked position is a memory, not a location, so no clip gets attributed to a site on one.

The GPS also solved a mystery folder. One folder of GoPro clips placed itself in Peru. That wasn’t a glitch: it was a 2022 motorbike trip through the Andes that had wandered in among the kitchens. It has its own home now.

One day

With a rule per camera, the biggest build is one day: 7:27 am to 4:10 pm, 41 clips from three kinds of camera, all inside one working day.

Across the whole library, reading every stamp as written invents five shoot days that never happened, all of them Sony and phone clips landing on the evening before. Trusting the Z invents three different ones, all GoPro afternoons spilling past midnight. Either way you get days that never happened. Which days depends on which clock you believed.

Then the tidy-up was boring, on purpose

With every file attributed, reorganising the drive was mechanical. A plan file listed 614 moves and 14 deletions, with a rollback script written out beside it. The moves were renames on the same share, so no data was copied and the whole thing took seconds.

The deletions were 13 byte-identical duplicates, about 35 GB, each hashed twice in separate runs before anything was removed. The fourteenth was a corrupt copy of a clip that still had a healthy twin. A before-and-after listing of the drive matched the plan exactly: nothing gone that wasn’t on the list.

The parts I’d reuse

  • A timestamp isn’t a time until you know the device’s convention. The Z is a claim, not a fact.
  • Work the rule out per camera, and prove it from the file itself: its modified time, its filename, whether the sequence overlaps. One rule for the whole library was wrong both ways.
  • Detect quirks like chaptering, don’t assume them. Different models from the same brand disagreed.
  • An unlocked GPS fix is where the camera last was, not where it is.
  • Read the project’s own notes before trusting a fresh answer. The notes had the phone right before the code did.