JSPM

  • Created
  • Published
  • Downloads 615
  • Score
    100M100P100Q107987F
  • License ISC

Reads telemetry from the GPMF track in GoPro cameras (Hero5 and later) and converts it to multiple formats

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

Parses 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 (or optionally other file formats) 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.

gopro-telemetry expects an object with the following properties:

  • 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

  • debug (boolean) Outputs some feedback.
  • tolerant (boolean) Returns data even if format does not match expectations.
  • promisify (boolean) Runs code asynchronously and returns a Promise that will resolve to the data when ready.
  • deviceList (boolean) Returns an object with only the ids and names of found devices. Disables the following options.
  • streamList (boolean) Returns an object with only the keys and names of found streams by device. Disables the following options.
  • device (array of numbers) Filters the results by device id.
  • stream (array of strings) Filters the results by device stream (often a sensor) name. You can find information on what many sensors are called here.
  • raw (boolean) Returns the data as close to raw as possible. No matrix transformations, no scaling, no filtering. Disables the following options.
  • repeatSticky (boolean) Puts the sticky values in every sample and deletes the 'sticky' object. This will increase the output size.
  • repeatHeaders (boolean) Instead of a 'values' array, the samples will be returned under their keys, based on the available name and units. This might increase the output size.
  • timeOut (string) By default the code exports both cts (milliseconds since first frame) and date (full date and time). Specify one (cts or date) in order to ignore the other.
  • timeIn (string) By default the code uses MP4 time (local, based on device) for cts and GPS time (UTC) for date. Specify one (MP4 or GPS) in order to ignore the other.
  • groupTimes (number/string) Group samples by units of time (milliseconds). For example, if you want one sample per second, pass it 1000. It also accepts the string frames to match the output to the video frame rate. This can drastically reduce the output size. By default, it will interpolate new samples if a time slot is empty.
  • disableInterpolation (boolean) Will allow groupTimes to work slightly faster by skipping time slots where there are no samples.
  • disableMerging (boolean) Will allow groupTimes to work slightly faster by selecting one sample per time slot instead of merging them all.
  • smooth (number) Uses the adjacent samples os a sample to smoothen it. For example, a value of 3 would average 3 samples before and 3 samples after each one. This can be a slow process.
  • dateStream (boolean) Creates an additional stream with only date information, no values, to make sure we have timing information of the whole track, even if the selected streams have empty sections.
  • ellipsoid (boolean) By default, the GPS5 altitude will be converted to sea level with EGM96 (Earth Gravitational Model 1996). Use this option if you prefer the default values, based on WGS84 (World Geodetic System) ellipsoid.
  • geoidHeight (boolean) Saves the altitude offset without applying it, for third party processing. Only relevant when ellipsoid is enabled.
  • GPS5Precision (number) Will filter out GPS5 samples where the Dilution of Precision is higher than specified (under 500 should be good).
  • GPS5Fix (number) Will filter out GPS5 samples where the type of GPS lock is lower than specified (0: no lock, 2: 2D lock, 3: 3D Lock).
  • preset (string) Will convert the final output to the specified format. Some formats will force certain options. See details below.
  • name (string) Some preset formats (gpx) accept a name value that will be included in the file.

All options default to null/false. Using filters to retrieve the desired results reduces the processing time.

Example:

const telemetry = goproTelemetry(rawData, { stream: ['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,
    streams : {
      stream_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
  • White balance (ºK or RGB)
  • Luma
  • Hue
  • Image uniformity
  • Scene classifier

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

Presets

These are the available preset formats:

  • gpx (.gpx) GPS Exchange format (returns as string). Compatible with many maps systems. For a quick visualization you can use the DJI SRT Viewer. Will force the stream filter to be GPS5 and will use ellipsoid altitude if not specified.
  • kml (.kml) Keyhole Markup Language (returns as string). Compatible with Google Earth. Will force the stream filter to be GPS5.
  • geojson (.json / .geojson) Open standard format designed for representing simple geographical features. Will force the stream filter to be GPS5, the timeOut to be null (output both cts and date) and will use ellipsoid altitude if not specified.
  • csv (.csv) Comma separated values, readable by Excel and other spreadsheet software. Will return an object with a CSV formatted string for every stream in every device (except when filters are present).
  • mgjson (.mgjson) Format for Adobe After Effects. The file can be imported as standard footage and will generate data streams to link properties/effects to. Experimental. See how to use data in After Effects here.

More creative coding

If you liked this you might like some of my app prototyping.

To-Do

  • Merge more than one video file
  • Hardcode (r,g,b) in rgb gains output?
  • Accept rawdata as input

Maybe To-Do