Post

Combine GoPro Files with FFmpeg

I have a HERO10 Black that I use to record video from my kids hockey games (such as this one), but since I typically move around with the camera between periods, the videos end up being “chaptered”, or multiple single videos. Though you’d think you could just sort these files by filename, GoPro’s file naming convention doesn’t actually lend itself well to this, and doing so results in out of sequence video.

For example, a recent video that I took had a directory listing like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ ll

-rwx------  1 alex  staff   265M 20 Dec 19:14 GL010118.LRV
-rwx------  1 alex  staff   265M 20 Dec 19:35 GL010119.LRV
-rwx------  1 alex  staff   265M 20 Dec 20:08 GL010120.LRV
-rwx------  1 alex  staff   194M 20 Dec 19:22 GL020118.LRV
-rwx------  1 alex  staff   234M 20 Dec 19:46 GL020119.LRV
-rwx------  1 alex  staff   265M 20 Dec 20:20 GL020120.LRV
-rwx------  1 alex  staff    48M 20 Dec 20:22 GL030120.LRV
-rwx------  1 alex  staff   3.7G 20 Dec 19:14 GX010118.MP4
-rwx------  1 alex  staff    10K 20 Dec 19:02 GX010118.THM
-rwx------  1 alex  staff   3.7G 20 Dec 19:35 GX010119.MP4
-rwx------  1 alex  staff    10K 20 Dec 19:24 GX010119.THM
-rwx------  1 alex  staff   3.7G 20 Dec 20:08 GX010120.MP4
-rwx------  1 alex  staff    10K 20 Dec 19:56 GX010120.THM
-rwx------  1 alex  staff   2.7G 20 Dec 19:22 GX020118.MP4
-rwx------  1 alex  staff    10K 20 Dec 19:14 GX020118.THM
-rwx------  1 alex  staff   3.3G 20 Dec 19:46 GX020119.MP4
-rwx------  1 alex  staff    10K 20 Dec 19:35 GX020119.THM
-rwx------  1 alex  staff   3.7G 20 Dec 20:20 GX020120.MP4
-rwx------  1 alex  staff    10K 20 Dec 20:08 GX020120.THM
-rwx------  1 alex  staff   696M 20 Dec 20:22 GX030120.MP4
-rwx------  1 alex  staff    10K 20 Dec 20:20 GX030120.THM

GoPro creates additional LRV and THM files when recording video so that you can quickly preview thumbnails and video on the camera itself. If we filter these out and just view the MP4 files you’ll see these aren’t necessarily in order:

1
2
3
4
5
6
7
8
9
$ ls *.MP4

-rwx------  1 alex  staff   3.7G 20 Dec 19:14 GX010118.MP4
-rwx------  1 alex  staff   3.7G 20 Dec 19:35 GX010119.MP4
-rwx------  1 alex  staff   3.7G 20 Dec 20:08 GX010120.MP4
-rwx------  1 alex  staff   2.7G 20 Dec 19:22 GX020118.MP4
-rwx------  1 alex  staff   3.3G 20 Dec 19:46 GX020119.MP4
-rwx------  1 alex  staff   3.7G 20 Dec 20:20 GX020120.MP4
-rwx------  1 alex  staff   696M 20 Dec 20:22 GX030120.MP4

An easy way to get the videos into a “correct” order would be to sort them chronologically by create date:

1
2
3
4
5
6
7
8
9
$ ll -tr *.MP4

-rwx------  1 alex  staff   3.7G 20 Dec 19:14 GX010118.MP4
-rwx------  1 alex  staff   2.7G 20 Dec 19:22 GX020118.MP4
-rwx------  1 alex  staff   3.7G 20 Dec 19:35 GX010119.MP4
-rwx------  1 alex  staff   3.3G 20 Dec 19:46 GX020119.MP4
-rwx------  1 alex  staff   3.7G 20 Dec 20:08 GX010120.MP4
-rwx------  1 alex  staff   3.7G 20 Dec 20:20 GX020120.MP4
-rwx------  1 alex  staff   696M 20 Dec 20:22 GX030120.MP4

Since I want to upload these videos to YouTube for the team to review, I need a single video file. After hunting around for scripts that could do this for me, I did find a few that looked promising - such as GoPro-Concat-Automation and gopro-linux. Ultimately I wanted to be able to just do this myself with a single command, so though these tools got me most of the way there, I ended up opting for my own script instead:

1
2
3
4
5
# run from the directory where your videos are located
# ex: /Volumes/SDCARD/DCIM/100GOPRO/
ffmpeg -f concat -safe 0 \
    -i <(for f in `ls -tr *.MP4`; do echo "file '$PWD/$f'"; done) \
    -c copy output.mp4

This uses FFmpeg to concatenate the videos and copy them to a new file called output.mp4. The input list for the videos is just a bash command to generate a list of MP4 files with the full path to the file in chronological order by create date.

Note that safe mode is disabled (see ffmpeg options) as having it enabled can result in the video creation failing for file-naming reasons. Why is this enabled by default and not disabled you might ask … #5558 concat protocol should run in “-safe 0” mode by default has more info on that topic.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.