videoffmpeggopro

ffmpeg concat and preserve metadata streams


I'm trying to concat multiple files that are the result of a GoPro Hero6 splitting movies to avoid the FAT 4GB limit. ffmpeg works great for this purpose but I need the telemetry data that is encoded in the metadata streams, and ffmpeg by default doesn't seem to preserve this. Using the ffprobe command you can see that the source videos have:

Stream #0:3(eng): Data: none (gpmd / 0x646D7067), 36 kb/s (default)
Metadata:
  creation_time   : 2018-07-15T16:16:26.000000Z
  handler_name    : GoPro MET

I know from research that this is the stream I need (although I'd like to be able to copy all streams). However when using ffmpeg -f concat the output is:

[concat @ 0x7febb9800000] Could not find codec parameters for stream 2 (Unknown: none): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[concat @ 0x7febb9800000] Could not find codec parameters for stream 3 (Unknown: none): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[concat @ 0x7febb9800000] Could not find codec parameters for stream 4 (Unknown: none): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, concat, from 'tmp.txt':
  Duration: N/A, start: 0.000000, bitrate: 66194 kb/s
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 2704x1520 [SAR 1:1 DAR 169:95], 66005 kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 119.88 tbc
    Metadata:
      creation_time   : 2018-07-15T16:08:22.000000Z
      handler_name    : GoPro AVC
      encoder         : GoPro AVC encoder
      timecode        : 16:23:48:21
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s
    Metadata:
      creation_time   : 2018-07-15T16:08:22.000000Z
      handler_name    : GoPro AAC
      timecode        : 16:23:48:21
    Stream #0:2: Unknown: none
    Stream #0:3: Unknown: none
    Stream #0:4: Unknown: none
Output #0, mp4, to 'GH0089.MP4':
  Metadata:
    encoder         : Lavf58.12.100
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 2704x1520 [SAR 1:1 DAR 169:95], q=2-31, 66005 kb/s, 0.02 fps, 59.94 tbr, 60k tbn, 60k tbc
    Metadata:
      creation_time   : 2018-07-15T16:08:22.000000Z
      handler_name    : GoPro AVC
      encoder         : GoPro AVC encoder
      timecode        : 16:23:48:21
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s
    Metadata:
      creation_time   : 2018-07-15T16:08:22.000000Z
      handler_name    : GoPro AAC
      timecode        : 16:23:48:21
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help

The warnings Could not find codec parameters are especially interesting and Stream mapping shows that only the video and audio streams are mapped. I've played around with map_metadata to no avail. I may not have the format right but it seems more likely that the issue is related to the warning as the codecs are not recognized and I would expect all streams to be mapped by default.

I would expect or hope for an answer that ignore the warnings and map the unrecognized streams without attempting to understand them.

Any help is appreciated.


Solution

  • Solved this one eventually... mostly...

    ffmpeg \
        -y -f concat -i test.txt -c copy \
        -map 0:v -map 0:a -map 0:3 \
        -copy_unknown -tag:2 gpmd \
        test2.mp4
    

    Seems ffmpeg will understand the telemetry data if it's tagged as gpmd ... however there's 2 other streams that will not map across no matter what I do. It seems that ffmpeg must be able to parse it out and cannot simply copy the bits across for some reason. It can understand the gpmd stream if you tag it, but one of the others it can't (fsck I think ... seems to be mostly for the hardware so not important anyway). The timecode stream is tagged tmcd but it seems that the GoPro doesn't follow the standard here so it can't be mapped 1:1... the code above produces what seems to be the most stable result, at least with the settings I've tried.