JuanIrache / gopro-telemetry

Reads telemetry from the GPMF track in GoPro cameras (Hero5 and later) and converts it to multiple formats
https://tailorandwayne.com/gopro-telemetry-extractor/
MIT License
310 stars 56 forks source link

Data mismatch while extracting telemetry #212

Closed talarad closed 9 months ago

talarad commented 10 months ago

Hello, I've developed a program which allows me to extract telemetry from multiple videos. I'm encountering a strange behaviour in my program and I hope you might help me out by identifying what went wrong.

I have a video filmed by GoPro Hero 10 Black and I tried to extract the telemetry from it by using the following function:

async function convertFileToJSON(
    file: Buffer,
    file_name: String
): Promise<Telemetry> {
    return new Promise((resolve, reject) => {
        try {
            const cancellationToken = { cancelled: false };
            gpmfExtract(file, { browserMode: false, progress, cancellationToken })
                .then(async (extracted) => {
                    if (!extracted) return;

                    cancellationToken.cancelled = true;

                    await goproTelemetry(
                        extracted,
                        {  stream: "GPS5" },
                        (telemetry: Telemetry) => { resolve(telemetry) }
                    );
                })
                .catch((err) => reject(err));
        } catch (e) {
            reject(e);
        }
    });
}

The JSON extracted shows that the samples are taken from 2015-10-18 (While the video was taken at 2022-09-11). I tried to use your tool in order to check whether the video is faulty but I got a valid JSON (same video):

faulty-json example: {"1":{"streams":{"GPS5":{"samples":[{"value":[31.6771656,34.6042632,75.035,0,0],"cts":81610.70799999998,"date":"2015-10-18T00:02:24.099Z"},{"value":[31.6771656,34.6042632,75.035,0,0],"cts":81710.73119999998,"date":"2015-10-18T00:02:24.199Z"},{"value":[31.6771656,34.6042632,75.035,0,0],"cts":81810.75439999998,"date":"2015-10-18T00:02:24.299Z"},{"value":[31.6771656,34.6042632,75.035,0,0],"cts":81910.77759999997,"date":"2015-10-18T00:02:24.399Z"}, ........

and the JSON extracted from your tool: {"1":{"streams":{"GPS5":{"samples":[{"value":[32.1026345,34.8322371,66.825,3.817,5.25],"cts":384401.024,"date":"2022-11-09T11:08:56.399Z","sticky":{"fix":3,"precision":475,"altitude system":"MSLV"}},{"value":[32.1026385,34.8322336,66.452,3.854,5.96],"cts":384501.4496,"date":"2022-11-09T11:08:56.499Z"},{"value":[32.1026377,34.8322326,67.006,3.661,6],"cts":384601.8752,"date":"2022-11-09T11:08:56.599Z"} .......

Do you have any idea what might cause that? Maybe some headers in goproTelemetry() are missing? Thank you, Tal

JuanIrache commented 9 months ago

I'm updating this with the information discussed over email, in case someone else bumps into this issue. The problem is the camera didn't have a GPS lock when the video started, and in those cases, it can end up recording bad (old) GPS times. The solution is to pass GPS quality options to the gopro-telemetry module, so only good samples are extracted. For example:

{
  stream: 'GPS5',
  GPSPrecision: 700,
  GPSFix: 2
}

This is done by default in the online version, so that's why the results were different in your tests. Be aware that this will delete samples, especially from the beginning of the video. For some tips on how to record good GPS data throughout the video, see this tutorial: https://www.youtube.com/watch?v=4R4X_Vs3LFA