JSPM

  • Created
  • Published
  • Downloads 627
  • Score
    100M100P100Q106480F
  • License ISC

GoPro telemetry and metadata extraction in JavaScript

Package Exports

  • gopro-telemetry

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (gopro-telemetry) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

GoPro Telemetry

Work in progress. Don't rely on it for important stuff yet.

Reads telemetry from the GPMF track in GoPro cameras (Hero5 and later).

Created for the GoPro Telemetry Extractor.

Here's a playlist with cool uses of the GoPro metadata .

Accepts an object with binary data and timing data. Returns a JavaScript object with a key for each device that was found. See samples/example.js for a basic implementation.

You must extract the raw GMPF data from the video file first. You can do so with gpmf-extract.

gpmf-extract will provide you with an object ready to import. It contains:

  • rawData (buffer) The GPMF track of the video file.
  • timing (object) Provides timing information such as starting time, framerate, payload duration... as extracted from gpmf-extract.

Install:

$ npm i gopro-telemetry

Use:

const goproTelemetry = require('gopro-telemetry');
const telemetry = goproTelemetry(input, options); //Get your input with gpmf-extract

Options (optional)

Some options may be incompatible with others.

  • debug (boolean) Outputs some feedback. Default: false
  • tolerant (boolean) Returns data even if format does not match expectations. Default: false
  • deviceList (boolean) Returns an object with only the ids and names of found devices. Disables the following options. Default: false
  • raw (boolean) Returns the data as close to raw as possible. No matrix transformations, no scaling. Disables the following options. Default: false
  • device (array of numbers) Filters the results by device id. Default: null
  • sensor (array of sstring) Filters the results by device sensor name. You can find information on what many sensors are called here. Default: null
  • repeatSticky (boolean) Puts the sticky values in every sample and deletes the 'sticky' object. Default: false
  • repeatHeaders (boolean) Instead of a 'values' array, the samples will be return under their keys, based on the available name and units. Default: false

Not yet implemented:

  • time (string) Averages samples to time units. Ideally will accept things like frames, milliseconds, seconds, timecode. Default: null

Example:

const telemetry = goproTelemetry(rawData, { sensor: ['ACCL'], repeatSticky: true });

This slightly more comprehensive example includes the data extraction step with gpmf-extract.

const gpmfExtract = require('gpmf-extract');
const goproTelemetry = require(`gopro-telemetry`);
const fs = require('fs');

const file = fs.readFileSync('path_to_your_file.mp4');

gpmfExtract(file)
  .then(extracted => {
    let telemetry = goproTelemetry(extracted);
    fs.writeFileSync('output_path.json', JSON.stringify(telemetry));
    console.log('Telemetry saved as JSON');
  })
  .catch(error => console.log(error));

timing object structure:

{ frameDuration: 0.03336666666666667,
  start: 2017-04-17T19:27:57.000Z,//Date object
  samples:
   [ { cts: 0, duration: 1001 },//Starting point and duration in milliseconds
     { cts: 1001, duration: 1001 },
     { cts: 2002, duration: 1001 },
     { cts: 3003, duration: 1001 },
     { cts: 4004, duration: 1001 } ] }

Output

The output with the default options looks like this:

{ deviceId : {
    data about the device : values,
    sensors : {
      sensor_key : {
        data about the samples : values,
        samples : [
          {
            cts : time from start,
            date : time and date,
            value : sample
            sticky : {
              name : value
            }
          },
          {
            cts : time from start,
            date : time and date,
            value : sample
          }
        ]
      }
    }
  }
}

Sticky values apply to all successive samples. You can export them to the outer object of all samples with the repeatSticky option.

Available data

Depending on the camera, model, settings and accessories, these are some of the available data:

  • GPS location (deg, m)
  • GPS speed (m/s)
  • Accelerometer (m/s²)
  • Gyroscope (rad/s)
  • ISO
  • Shutter Speed (s)
  • Timestamps (µs)
  • Magnetometer (µT)
  • Face detection
  • Highlights (manual and computed)
  • White balance
  • Luma
  • Hue
  • Image uniformity
  • Scene classifier

This project is possible thanks to the gpmf-parser documentation, open sourced by GoPro.

More creative coding

If you liked this you might like other creative coding projects.

To-Do

  • Interpret data
    • Use STPM for time if available?
    • hero6+ble produces strange stnm sensor
    • Create and document time inputs, Document outputs (gps time is utc, mp4 time is local)
    • Enable grouping packets per time unit / frame
    • What to do with tick, tock, tsmp, empt....? then delete them
  • Automated test interpretation
  • Comment index
  • Document output
  • Review console.log/error usage
  • Create additional package for converting the data to other formats
  • Remove Work-in-progress warning
  • Refactoring for performance?

Maybe To-Do

  • Take potential nested arrays into account f[8]? Never found one to test
  • Pending types:
    • d | 64-bit double precision (IEEE 754) | double
    • G | 128-bit ID (like UUID) | uint8_t guid[16]
    • q | 32-bit Q Number Q15.16 | uint32_t | 16-bit integer (A) with 16-bit fixed point (B) for A.B value (range -32768.0 to 32767.99998)
    • Q | 64-bit Q Number Q31.32 | uint64_t | 32-bit integer (A) with 32-bit fixed point (B) for A.B value.