2

Want to get FFmpeg 7.1 (macOS) to compress MP4 files produced by GoPro while copying the metadata streams, particularly the GPS data. It works to MOV output but not MP4 output. I would like to keep it as MP4 for maximum compatibility. It seems to choke copying stream 2, the tmcd stream.

Here's the command that works:

ffmpeg -i GX-0195-02.MP4 -copy_unknown -map 0 -map_metadata 0 -c:v hevc_videotoolbox -q:v 45 -vtag hvc1 GX-0195-02-htb45.mov

If I simply change the output file name from .mov to .mp4, I get the following error:

[mp4 @ 0x13af06a70] You requested a copy of the original timecode track so timecode metadata are now ignored
[mp4 @ 0x13af06a70] Could not find tag for codec none in stream #2, codec not currently supported in container
[out#0/mp4 @ 0x600000194180] Could not write header (incorrect codec parameters ?): Invalid argument
[vf#0:0 @ 0x600000594140] Error sending frames to consumers: Invalid argument
[vf#0:0 @ 0x600000594140] Task finished with error code: -22 (Invalid argument)
[vf#0:0 @ 0x600000594140] Terminating thread with return code -22 (Invalid argument)
[out#0/mp4 @ 0x600000194180] Nothing was written into output file, because at least one of its streams received no packets.

Here's the input file info:

% ffprobe GX-0195-02.MP4                                            11:05:32
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'GX-0195-02.MP4':
Metadata:
major_brand     : mp41
minor_version   : 538120216
compatible_brands: mp41
creation_time   : 2024-08-05T16:21:07.000000Z
firmware        : H22.01.02.30.70
Duration: 00:03:31.01, start: 0.000000, bitrate: 45108 kb/s
Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 44844 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
Metadata:
creation_time   : 2024-08-05T16:21:07.000000Z
handler_name    : GoPro H.265
vendor_id       : [0][0][0][0]
encoder         : GoPro H.265 encoder
timecode        : 10:00:05:09
Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default)
Metadata:
creation_time   : 2024-08-05T16:21:07.000000Z
handler_name    : GoPro AAC  
vendor_id       : [0][0][0][0]
timecode        : 10:00:05:09
Stream #0:2[0x3](eng): Data: none (tmcd / 0x64636D74) (default)
Metadata:
creation_time   : 2024-08-05T16:21:07.000000Z
handler_name    : GoPro TCD  
timecode        : 10:00:05:09
Stream #0:3[0x4](eng): Data: bin_data (gpmd / 0x646D7067), 57 kb/s (default)
Metadata:
creation_time   : 2024-08-05T16:21:07.000000Z
handler_name    : GoPro MET  
Unsupported codec with id 0 for input stream 2
Unsupported codec with id 98314 for input stream 3`

Have tried variations on -tag:2 based on other searches, but I don't quite know what that's actually doing so don't fully understand syntax or implications.

Giacomo1968
  • 58,727

1 Answers1

2

I found a way to make it work. Changing the command line to specifying all the streams except the tmcd stream.

ffmpeg -i GX-0195-02.MP4 -copy_unknown -map 0:0 -map 0:1 -map 0:3 -map_metadata 0 -c:v hevc_videotoolbox -q:v 45 -vtag hvc1 GX-0195-02-htb45.mp4

Produces a new MP4 with compressed video and audio but the other stream (the gpmd stream) also copied. The tcmd "stream" is reconstructed by the MP4 output, apparently, albeit it is rearranged from the original order of streams.

I cannot explain why -map 0 worked for .mov output files but not for .mp4 output.

I would prefer that I would not have to know the full stream structure of these files ahead of time. Seems like the -copy_unknown flag should behave by copying all streams without any further -map flags. But, this is the way I got it to work for now.