One may losslessly concatenate two MP4 files using FFmpeg as follows:
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4
with list.txt:
file 'C:\file1.mp4'
file 'C:\file2.mp4'
However, if the input files C:\file1.mp4 and C:\file2.mp4 have telemetry information, output.mp4 won't have it, as ffprobe can confirm. In my case,
C:\file1.mp4 and C:\file2.mp4 have GPMF™ formatted telemetry data used within GoPro® cameras.
How can I losslessly concatenate two MP4 files and keep the telemetry information using FFmpeg?
ffprobe ouput for one of the input file with telemetry information:
C:\>ffprobe GX010013.MP4
ffprobe version 5.0.1-full_build-www.gyan.dev Copyright (c) 2007-2022 the FFmpeg developers
built with gcc 11.2.0 (Rev7, Built by MSYS2 project)
configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
libavutil 57. 17.100 / 57. 17.100
libavcodec 59. 18.100 / 59. 18.100
libavformat 59. 16.100 / 59. 16.100
libavdevice 59. 4.100 / 59. 4.100
libavfilter 8. 24.100 / 8. 24.100
libswscale 6. 4.100 / 6. 4.100
libswresample 4. 3.100 / 4. 3.100
libpostproc 56. 3.100 / 56. 3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'GX010013.MP4':
Metadata:
major_brand : mp41
minor_version : 538120216
compatible_brands: mp41
creation_time : 2022-07-16T20:36:19.000000Z
firmware : H21.01.01.42.00
Duration: 00:08:54.55, start: 0.000000, bitrate: 59971 kb/s
Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 5312x2988 [SAR 1:1 DAR 16:9], 59702 kb/s, 59.94 fps, 59.94 tbr, 60k tbn (default)
Metadata:
creation_time : 2022-07-16T20:36:19.000000Z
handler_name : GoPro H.265
vendor_id : [0][0][0][0]
encoder : GoPro H.265 encoder
timecode : 20:35:05:32
Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default)
Metadata:
creation_time : 2022-07-16T20:36:19.000000Z
handler_name : GoPro AAC
vendor_id : [0][0][0][0]
timecode : 20:35:05:32
Stream #0:2[0x3](eng): Data: none (tmcd / 0x64636D74) (default)
Metadata:
creation_time : 2022-07-16T20:36:19.000000Z
handler_name : GoPro TCD
timecode : 20:35:05:32
Stream #0:3[0x4](eng): Data: bin_data (gpmd / 0x646D7067), 60 kb/s (default)
Metadata:
creation_time : 2022-07-16T20:36:19.000000Z
handler_name : GoPro MET
Unsupported codec with id 0 for input stream 2
Unsupported codec with id 98314 for input stream 3
https://github.com/gopro/gpmf-parser gives an overview of the GoPro's MP4 structure:
Telemetry carrying MP4 files will have a minimum of four tracks: Video, audio, timecode and telemetry (GPMF). A fifth track ('SOS') is used in file recovery in HERO4 and HERO5, can be ignored.
File structure:
ftyp [type ‘mp41’] mdat [all the data for all tracks are interleaved] moov [all the header/index info] ‘trak’ subtype ‘vide’, name “GoPro AVC”, H.264 video data ‘trak’ subtype ‘soun’, name “GoPro AAC”, to AAC audio data ‘trak’ subtype ‘tmcd’, name “GoPro TCD”, starting timecode (time of day as frame since midnight) ‘trak’ subtype ‘meta’, name “GoPro MET”, GPMF telemetry