Here are some details about how I made this timelapse video with a GoPro and a Mac. It wasn't as straight-forward as I thought it would be, so I wanted to share what I learned.
As you can see from the video, the subject was me building a wooden mechanical 3D puzzle which took me nearly 18 hours to build. I took a photo once every 5 seconds which yeilded more than 12.7k photos.
Here's what I used to make a timelapse video.
- GoPro Hero3: Silver
- MacBook Pro
- Mac OS Big Sur (v11.5.2)
- Apple Photos (v6.0)
- iMovie (v10.2.5)
- ffmpeg (v4.4)
Here's the process I used to make the timelapse video.
The first step was to take the photos which would later be combined into the timelapse video. This was fairly straight-forward with the GoPro once the settings were configured.
- Set the time and date on the GoPro*
- Configured the GoPro to take a photo every 5 seconds
- Set up the camera in the desired location and tried not to move it the entire time
- Began taking photos while I built the puzzle
- When the memory card was full, I imported the photos into Apple Photos
- Formated the card after all photos were safely imported onto my computer
- Repeated steps 4-6 until the build was complete
* Setting the time and date correctly was important to keeping the photos in order because the filenames will repeat as the card is reused. The time/date was reset at one point in the middle of the build which caused a headache later.
After the photography of the build was complete, I organized all of the photos in albums so they could be exported to the video editing programs. There were over 12.7k photos which was crashing Apple Photos when they were all in a single album, so I sorted the photos into 10 albums based on when they were imported.
Another issue I ran into was the clock on the GoPro was reset for a few hundred photos, so they were marked as 8 years older than the others. Luckily, Apple Photos kept track of when I imported the photos, so I was able to adjust and fudge the dates based on import order such that all photos were in proper chronological order.
Once the photos were sorted and ordered, I exported each album with sequential filenames. This allowed video editing software to understand order independent of date metadata.
Initially, I exported all photos to a single directory, but I learned the hard way that Mac has trouble handling directories with 12.7k files. I found that any command with a globbed filename would simply fail, including simple commands like rm
! E.g.,
[I] ➜ rm *.jpeg
zsh: argument list too long: rm
If you find yourself in this situation, a workaround is to simply use a bash for loop, e.g.,
for i in *.jpeg; do rm "$i"; done
Originally I had planned to simply drag-and-drop the photos into an iMovie timeline, but 12.7k photos was simply too many photos for iMovie to handle without crashing. I decided to use the ffmpeg command-line video editor to stich photos together into video clips, and import those into iMovie later.
Even though the photos were exported with sequential filenames, they were not ordered correctly when sorted alphanumerically. E.g.,
1.jpg
10.jpg
11.jpg
12.jpg
2.jpg
3.jpg
...
10
appears immediately after 1
instead of 2
because the .
in 1
is being compared to the 0
in 10
. To get these to sort correctly alphanumerically, we can insert leading zeros, e.g.,
01.jpg
02.jpg
03.jpg
...
10.jpg
11.jpg
12.jpg
To handle this renaming, I used a program called rename
, installed with brew install rename
. I had filenames that looked like this, with the first number being the album number, leftover from when I tried exporting all files to a single directory:
1.JPG
10.JPG
2.JPG
...
Using this command:
rename -e 's/\d+/sprintf("%04d",$&)/e' -- *.JPG
They were renamed to:
0001.JPG
0002.JPG
0010.JPG
...
See this StackOverflow answer for more info on how to use rename
to add leading zeros to filenames.
Unfortunately installing ffmpeg
was not as simple as running brew install ffmpeg
because we need a special codec, libx264
that isn't included with the brew
binary. I used @df-a 's instructions to compile ffmpeg
from source configured with that codec (and many others) which worked like a charm.
Update: You should only have to brew install ffmpeg
now instead of compiling from source!
Finally I was ready to create video clips by stitching the timelapse photos together. For each album set, I ran something like the following command to create the clips:
ffmpeg -framerate 60 -pattern_type glob -i "*.JPG" -vcodec libx264 -s 2880x2160 -pix_fmt yuv420p timelapse.mp4
-framerate
is how many frames-per-second to encode. 30 FPS is typical, but I like 60 FPS b/c it's smoother and faster.-s 2880x2160
is the clip resolution which is the 4:3 "4k" scale of the original photo resolution of 3840x2880. (I chose this resolution because I wanted the final video clip to be in 4k.)-pix_fmt yuv420p
is a colorspace option to allow the video to work in Quicktime and iMovie. See this StackExchange answer for more info
Now that I had 10 working clips rendered with ffmpeg
, I imported them into a new iMovie project, and then added them to the timeline in order. It was more than 8 minutes long, which is too long for a timelapse, so I sped up the footage by about 2x, which left me with a 4 minute video.
I added some free music from the YouTube Free Audio Library, a title screen, a short end video clip of the train in action, and a few captions. I then exported the video in 4k and uploaded it to YouTube.
That's it!
Here are a few things I learned.
- One photo every 5 seconds is too frequent for a 17+ hour build. If I did it again, I'd probably halve the frequency to 10 at least
- Apple Photos will crash if you try to export 12.7k photos
- iMovie will crash if you try to add thousands of photos to the timeline
- Mac (and Linux?) cannot handle globbing together 12.7k files, but we can use a
for
loop as a workaround