Converting a batch of Dashcam videos into a timelapse

I recently took a family vacation from St. Louis, MO to Branson, MO, and as it was the first time driving with my new Mobius Action Cam Mini dashcam installed on our Toyota Sienna (see a full writeup and review here), I wanted to see if I could quickly whip up a time lapse video of the entire drive.

Driving in St. Louis - dashcam loop gif
A tiny snippet of the final time-lapse video of my STL to Branson drive.

While the Mobius has the ability to do time lapses built-in, doing so would require me to choose between either having a time lapse or recording continuous 30fps video. And for insurance purposes, a timelapse with only a frame every second or two would not be that helpful!

So, knowing that my Mac can do many powerful things, I thought it might be able to do the following:

  1. Take a folder of 3-minute 1080p video clips at 30 frames per second straight from the Mobius Action Cam
  2. Speed up the clips to turn them into a proper time lapse (~5x or ~10x speedup).
  3. Merge all the clips into one, much more compact, time lapse video of the entire trip.

As an experiment, I wanted to just grab two files, speed both up, and merge them—after success there, I'll go on to automate the batch process for an entire directory of videos!

Speeding up two videos

I grabbed the first two videos in a series of videos from our trip, and put them on my desktop. Then I did the following to get ready to speed up the videos:

  1. Open Terminal (in Applications > Utilities)
  2. Install ffmpeg (using Homebrew): brew install ffmpeg
  3. Change directories to the Desktop: cd ~/Desktop (where I have two videos, REC_0007.MOV and REC_0008.MOV)

For each video (MOV format, straight from the Mobius Action Cam, 1080p, mono audio), I ran the command:

ffmpeg -i REC_0007.MOV -vf "setpts=0.05*PTS" -an SPEEDY7.MOV

I switched 7 for 8 to speed up the second video.

What this command does is grabs the input file (-i), sets the Presentation TimeStamp to [value]*[current PTS], which is a fancy way of saying "make the video much faster—in this case 50x faster, with a value of 0.05, and then store the re-encoded file in the same directory, with a different name.

Merging two videos

With both videos considerably faster (50x) and smaller (~30 MB instead of ~400 MB), I wanted to merge the two to make one continuous video (since the Dash cam was configured to split clips in 3 minute increments, this is a necessary step if you want any kind of continuous viewing experience).

So, to merge the two clips, since they weren't in a format that allows direct 'concatenation' (e.g. ffmpeg -i "concat:SPEEDY7.MOV|SPEEDY8.MOV" -codec copy, I had to first create a text file that included one line for each clip, with the filesystem path to the clip (I called the file concat.txt):

file 'SPEEDY7.MOV'
file 'SPEEDY8.MOV'

Note: If you don't use individual filenames (e.g. if you want to use a path like ~/Desktop/SPEEDY7.MOV or /path/to/, then you will need to add the -safe 0 option before the -i in the following command, otherwise you'll see an error like Unsafe file name '~/Desktop/SPEEDY7.MOV' ... concat.txt: Operation not permitted.

Then I ran ffmpeg's command to concatenate videos based on a text file:

ffmpeg -f concat -i concat.txt -c copy

After running this command, I ended up with one video, but there were a few frames of a gap between the two which didn't look that great. I realized that the Mobius Action Cam sticks about an extra second from the previous clip at the start of the next clip... so I need to remove the duplicate frames after the initial clip speedup process but before concatenation using the -ss option ('seek' to position—thanks to this Super User answer for the tip!):

ffmpeg -i SPEEDY8.MOV -ss 00.12 -an SPEEDY8-fixed.MOV

I used a value of 00.12 because I wanted to remove the first three frames of the video after it had been sped up, and ffmpeg only accepts values in HH:MM:SS.SS (in this case, we have 30 fps, and want to remove two frames, so we need to seek to 00.12 seconds (.03 seconds per frame) after the sped up video is written to disk. I also tried using -ss 01.03 to remove the first 31 frames of the video prior to speeding it up in the first command (e.g. ffmpeg -ss 01.03 -i REC_0007.MOV -vf "setpts=0.05*PTS" -an SPEEDY7.MOV), but this resulted in a couple 'junk' frames at the beginning that made the concatenated video have a stutter where the two clips were joined.

Compare by viewing the following video files:

1080p sped up video concatenation - uncorrected

1080p sped up video concatenation - fixed!

I ran that command over both files, then concatenated them again, and now I have a much nicer clip! Now that I've proven I can do this programmatically, the next step is to automate the process so I can process and combine hundreds of videos for a long trip (a 4 hour drive generated almost 100 3-minute clips!).

Batching the process

I'm an advocate for automating all the things, and mundane tasks like re-encoding and concatenating dozens or hundreds of clips is the perfect candidate for automation! I spent some time wrapping all of the above commands into a flexible shell script, which I've posted as a Gist on GitHub:

That gist will be updated over time as needed, and I may be able to spend a little more time working on the CLI UX—for now, pop in your dashcam's memory card, adjust the variables at the top of the file, then run the script, and some time later, you'll end up with a file of sped-up footage from a recent drive!

More Resources


thanks for this script. my son wanted to do exactly this, but find it painful with gui. I learned a bit about ffmpeg in past couple days and this script just made this whole task much easier

Glad I could help! I actually needed this today again, so I'm glad I spent the time to write it up back when I did it initially :)

Just got a dashcam and was hoping I'd be able to find something like this! Will give this a go sometime soon. (especially as I have a couple of ~7 hour journeys coming soon!
It's an electric car, so I'm hoping I can find a permanently on fuse socket for the hardwire kit so I can capture the charging as well.

Wow, Ok, here goes. First Blackvue dr650s 1ch, then 750, now 900. Registrator Viewer worked perfectly with the 650 then no more.
Russian Dev passed away a while back. His software was kinda perfect. I'm sure you're familiar, but check this..…

Solved, in my opinion, the one issue with all manufacturer software, namely Blackvue's Viewer.
COMBINING the clips without OVERLAP!…

If someone could take this guys idea on move, I'll help.


Thanks! This is exactly what I want to do. You saved me alot of time.

Hi, thanks for the hints! I had the same "double-frame" issues, but with hundreds of short videos. In the end it was much easier to merge and then speed up.

Thanks again

Thx a bunch for the script, was about to write my own and you saved me 1-n hours! ;-)

Just changed the following (until now):

# Create a file listing all the videos in the current directory.
printf "file '%s'\n" *.$VIDEO_EXTENSION | sort --version-sort > concat.txt

The "--version-sort" helps to get filenames with different characters including counting numbers (1-n) sorted in a meaningful (in order of time) way, at least for me. Might not work on any OS, only GNU sort has iirc this option.

Another idea for anyone starting, just try it out with 3 or so short input files, so you can repeat and adjust to your needs quickly until you are satisfied, it took my Notebook nearly 25 Minutes to process for about 30 clips with just 25 seconds each!

So thx again, still impressed how smooth the outcome looks


Thank you for this, I ended up writing my own script using your method as a base, and the result is great. I use two dash cams (front and rear) and added code to add my rear camera in the time-lapse as a PiP. I also sped up audio to match time-lapse.Making the resulting time-lapse in 60fps creates a much smoother video.My final command scaling the video to 1440p looks something like this: FFMpeg.exe -v error -stats -f concat -safe 0 -i "Z:\Concat.txt" -filter_complex "[0:v]format=yuv420p,scale=in_range=auto:out_range=auto:h=1440:w=-1,crop=w=2560,setpts=(20/100)*PTS,fps=60[v];[0:a]atempo=1/(20/100)[a]" -map "[v]" -c:v libx264 -preset slow -crf 22 -map "[a]" -movflags +faststart+write_colr "Z:\TimeLapse.mp4"