I want to extract the last few seconds of a GoPro video losslessly with FFmpeg so that it keeps telemetry info and keeps the original stream order.
A GoPro video has 4 streams, in that order:
Stream #0:0[0x1](eng): VideoStream #0:1[0x2](eng): AudioStream #0:2[0x3](eng): Data: none (tmcd / 0x64636D74) (default)Stream #0:3[0x4](eng): Data: bin_data (gpmd / 0x646D7067), 59 kb/s (default)
Details (using the commandffmpeg -i gopro_video.mp4):
Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 59703 kb/s, 59.94 fps, 59.94 tbr, 60k tbn (default)
Metadata:
creation_time : 2024-11-23T23:10:03.000000Z
handler_name : GoPro H.265
vendor_id : [0][0][0][0]
encoder : GoPro H.265 encoder
timecode : 23:26:28:23
Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default)
Metadata:
creation_time : 2024-11-23T23:10:03.000000Z
handler_name : GoPro AAC
vendor_id : [0][0][0][0]
timecode : 23:26:28:23
Stream #0:2[0x3](eng): Data: none (tmcd / 0x64636D74) (default)
Metadata:
creation_time : 2024-11-23T23:10:03.000000Z
handler_name : GoPro TCD
timecode : 23:26:28:23
Stream #0:3[0x4](eng): Data: bin_data (gpmd / 0x646D7067), 59 kb/s (default)
Metadata:
creation_time : 2024-11-23T23:10:03.000000Z
handler_name : GoPro MET
I try to use this command to extract the last few seconds of a GoPro video with ffmpeg so that it keeps telemetry info and keeps the original stream order:
ffmpeg -sseof -10 -i input.MP4 -map 0:v -map 0:a -map 0:3 -c copy -copy_unknown output.MP4
However, it inverses the order of Stream #0:2[0x3](eng) and Stream #0:3[0x4](eng), i.e. the output file output.MP4 has 4 streams, in that order:
Stream #0:0[0x1](eng): VideoStream #0:1[0x2](eng): AudioStream #0:3[0x3](eng): Data: bin_data (gpmd / 0x646D7067), 59 kb/s (default)Stream #0:2[0x4](eng): Data: none (tmcd / 0x64636D74) (default)
Stream details of the output file output.MP4:
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output.MP4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2mp41
encoder : Lavf61.7.100
Duration: 00:00:10.24, start: 0.000000, bitrate: 60393 kb/s
Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 60132 kb/s, 59.94 fps, 59.94 tbr, 60k tbn (default)
Metadata:
handler_name : GoPro H.265
vendor_id : [0][0][0][0]
encoder : GoPro H.265 encoder
timecode : 23:26:28:23
Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default)
Metadata:
handler_name : GoPro AAC
vendor_id : [0][0][0][0]
Stream #0:2[0x3](eng): Data: bin_data (gpmd / 0x646D7067), 60 kb/s (default)
Metadata:
handler_name : GoPro MET
Stream #0:3[0x4](eng): Data: none (tmcd / 0x64636D74), 0 kb/s
Metadata:
handler_name : GoPro H.265
timecode : 23:26:28:23
It is tempting to instead use the following command, since, as slhck wrote, "the order of the -map options determines the order of the streams in the output file":
ffmpeg -sseof -10 -i input.MP4 -map 0:v -map 0:a -map 0:2 -map 0:3 -c copy output.MP4
However, one can't use -map on streams that FFmpeg doesn't understand, and as a result, one gets this error:
[mp4 @ 00000292a73dd140] You requested a copy of the original timecode track so timecode metadata are now ignored
[mp4 @ 00000292a73dd140] Could not find tag for codec none in stream #2, codec not currently supported in container
[out#0/mp4 @ 00000292a793ec40] Could not write header (incorrect codec parameters ?): Invalid argument
Conversion failed!
One may otherwise try to move -copy_unknown in front of -map 0:3, i.e.:
ffmpeg -sseof -10 -i input.MP4 -map 0:v -map 0:a -copy_unknown -map 0:3 -c copy output.MP4
But FFmpeg doesn't care about the order of -copy_unknown relative to -map so that doesn't change the stream order.
I'm out of ideas. For testing convenience, here is an example of a GoPro video file (18.5 MiB). Rename it as input.MP4 to try the aforementioned commands and use -sseof -1 instead of -sseof -10 since the video is only 2-second long.
How can I extract the last few seconds of a GoPro video losslessly with ffmpeg so that it keeps telemetry info and keeps the original stream order?