惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - xgqfrms

Dell 显示器 S2419HM 灰屏 &花屏 All In One AI Harness Engineering All In One 电脑外接显示器天梯榜 All In One How to change the speed display unit of GSP from mph to km/h using GoPro Labs All In One WHCA 白宫记者协会 All In One Pascal Editor All In One 主流犬种图解指南 All In One 泡沫喷雾 & 辣椒喷雾 All In One 如何给身份证照片添加水印 All In One GoPro MISSION 1 PRO price All In One 杭州历史天气数据 All In One Pandoc All In One GoPro MISSION 1 SERIES All In One NHTSA FARS All In One How to extract raw telemetry data from GoPro videos using FFmpeg All In One Free Vercel Services All In One How to run for loop in Python REPL All In One 使用不同 AI 大模型生成一杯装满的红酒的高脚杯挑战赛 All In One CSS Custom Highlight API All In One OpenCode All In One OpenClaw 设置 cron 定时任务 All In One free MongoDB Cloud API All In One 如何在 Raspberry Pi 安装 OpenClaw All In One free cloud LLM models API All In One Claude Code Free Video Tutorials All In One 如何解决 OpenClaw 升级后导致 feishu plugin 无法使用的问题 All In One Claude Code skills & plugins All In One LLM Benchmark All In One How to fix use the FileZilla FTP upload file error All In One
GoPro telemetry 中的 GPS5 与 GPS9 是什么 All In One
xgqfrms · 2026-04-15 · via 博客园 - xgqfrms

GoPro telemetry 中的 GPS5 与 GPS9 是什么 All In One

GoPro GPS telemetry / 自定义 GPS 仪表盘

GPS5

old version

image

https://github.com/JuanIrache/gopro-telemetry/blob/65df053342c60791d2ae67761c98ff6e5cc45abe/code/processGPS5.js

https://github.com/JuanIrache/gopro-telemetry/issues/120
https://github.com/JuanIrache/gopro-telemetry/pull/120

https://github.com/JuanIrache/gopro-telemetry/pull/120/changes/65df053342c60791d2ae67761c98ff6e5cc45abe#diff-b28f647f2365e603c6fd4e39bf0cdab5c63043d6528b994a7902bb0e2ce496c8

image

https://github.com/JuanIrache/gopro-telemetry/tree/65df053342c60791d2ae67761c98ff6e5cc45abe

GPS9

new version

image

https://github.com/JuanIrache/gopro-telemetry/blob/master/code/processGPS.js#L25

demos

image

const fs = require("fs");
const gpmfExtract = require("gpmf-extract");
const GoProTelemetry = require("gopro-telemetry");


const rawData = fs.readFileSync("GX010918_Trim_06.11.MP4");

gpmfExtract(rawData)
  .then(buffer => {
    // console.log(`✅ buffer:`, buffer);
    console.log(`✅ buffer.rawData:`, buffer.rawData);
    // console.log(`✅ buffer.timing:`, buffer.timing);
    // console.log(`✅ buffer.timing.samples:`, buffer.timing.samples.length, buffer.timing.samples[0]);
    // [{ cts: 0, duration: 1001 }, ...]
    // buffer.timing.samples: 83 { cts: 0, duration: 1001 }


    GoProTelemetry(buffer, {}, telemetry => {
      // console.log(`\n✅ telemetry: `, telemetry);
      console.log(`\n✅ telemetry keys: `,  Object.keys(telemetry));
      // [ '1', 'frames/second' ]
      console.log(`\n✅ telemetry['1'] keys: `, Object.keys(telemetry['1']));
      // [ 'streams', 'device name' ]
      console.log(`\n✅ telemetry['1'].streams: `, Object.keys(telemetry['1'].streams));
      // [ 'ACCL', 'GYRO', 'SHUT', 'WBAL', 'WRGB', 'ISOE', 'YAVG', 'UNIF', 'SCEN', 'HUES', 'GPS9', 'CORI', 'IORI', 'FASC', 'GRAV', 'WNDM', 'MWET', 'AALP', 'MSKP', 'LSKP', 'CSCM', 'USRD' ]
      console.log(`\n✅ telemetry['1'].streams.GPS9: `, Object.keys(telemetry['1'].streams.GPS9));
      // [ 'samples', 'name', 'units' ]
      // console.log(`\n✅ telemetry['1'].streams.GPS9: `, telemetry['1'].streams.GPS9);
      // { value: [Array], cts: 0, date: 2026-04-12T14:59:21.199Z, sticky: [Object] },
      console.log(`\n✅ telemetry['1'].streams.GPS9.samples[0]: `, telemetry['1'].streams.GPS9.samples[0]);
      /* 
        {
          value: [
            31.0449444, 121.2269421,
                4.696,       7.645,
                  7.15,        9598,
              53961.2,         1.6,
                    3
          ],
          cts: 0,
          date: 2026-04-12T14:59:21.199Z,
          sticky: { 'altitude system': 'MSLV' }
        }
      */

      /* 
        各字段含义如下:
        value: 一个数组,依次为(通常 GoPro GPS9 各项含义如下,具体顺序可查阅 GoPro Telemetry 文档):
          纬度(Latitude)
          经度(Longitude)
          海拔高度(Altitude, 单位米)
          水平速度(2D Speed, 单位米/秒)
          3D速度(3D Speed, 单位米/秒)
          水平精度(Horizontal Accuracy, 单位厘米或毫米,具体依设备而定)
          垂直精度(Vertical Accuracy)
          航向(Heading, 单位度)
          卫星数量(Satellites)
        cts: 当前时间戳(采样点的相对时间,通常为毫秒)
        date: 采样点的绝对时间(ISO 格式时间戳)
        sticky: 额外的附加信息,这里 'altitude system': 'MSLV' 表示高度基准为“Mean Sea Level Vertical”(平均海平面)

     */

      // fs.writeFileSync('output_path.json', JSON.stringify(telemetry));
      // console.log('Telemetry saved as JSON');
    });
    // GoProTelemetry(buffer, {stream: ["GPS5"]}, telemetry => {
    //   console.log(`telemetry: `, telemetry);
    //   const gps = telemetry["0"]?.streams?.GPS5;
    //   if (!gps) {
    //     console.log("❌ 没有找到 GPS 数据");
    //     return;
    //   }
    //   console.log(`GSP: `, gps)
    //   // fs.writeFileSync('output_path.json', JSON.stringify(telemetry));
    //   // console.log('Telemetry saved as JSON');
    // });
  }).catch(error => {
    console.error(error);
  });



/* 


 $ node ./demo.js
✅ buffer: {
  rawData: <Buffer 44 45 56 43 00 01 1f ac 44 56 49 44 4c 04 00 01 00 00 00 01 44 56 4e 4d 63 0c 00 01 48 45 52 4f 31 33 20 42 6c 61 63 6b 53 54 52 4d 00 01 05 24 53 54 ... 673646 more bytes>,
  timing: {
    videoDuration: 82.82226666666666,
    frameDuration: 0.016661087641654932,
    start: 2026-04-12T06:59:23.000Z,
    samples: [
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object]
    ]
  }
}

✅ telemetry:  {
  '1': {
    streams: {
      ACCL: [Object],
      GYRO: [Object],
      SHUT: [Object],
      WBAL: [Object],
      WRGB: [Object],
      ISOE: [Object],
      YAVG: [Object],
      UNIF: [Object],
      SCEN: [Object],
      HUES: [Object],
      GPS9: [Object],
      CORI: [Object],
      IORI: [Object],
      FASC: [Object],
      GRAV: [Object],
      WNDM: [Object],
      MWET: [Object],
      AALP: [Object],
      MSKP: [Object],
      LSKP: [Object],
      CSCM: [Object],
      USRD: [Object]
    },
    'device name': 'HERO13 Black'
  },
  'frames/second': 60.02009121540584
}

*/


image

const fs = require("fs");
const gpmfExtract = require("gpmf-extract");
const GoProTelemetry = require("gopro-telemetry");


const rawData = fs.readFileSync("GX010918_Trim_06.11.MP4");
// const rawData = fs.readFileSync("GX010931.MP4");

gpmfExtract(rawData)
  .then(buffer => {
    // console.log(`✅ buffer:`, buffer);
    console.log(`✅ buffer.rawData:`, buffer.rawData);
    // console.log(`✅ buffer.timing:`, buffer.timing);
    // console.log(`✅ buffer.timing.samples:`, buffer.timing.samples.length, buffer.timing.samples[0]);
    // [{ cts: 0, duration: 1001 }, ...]
    // buffer.timing.samples: 83 { cts: 0, duration: 1001 }


    GoProTelemetry(buffer, {}, telemetry => {
      // console.log(`\n✅ telemetry: `, telemetry);
      console.log(`\n✅ telemetry keys: `,  Object.keys(telemetry));
      // [ '1', 'frames/second' ]
      console.log(`\n✅ telemetry['1'] keys: `, Object.keys(telemetry['1']));
      // [ 'streams', 'device name' ]
      console.log(`\n✅ telemetry['1'].streams: `, Object.keys(telemetry['1'].streams));
      // [ 'ACCL', 'GYRO', 'SHUT', 'WBAL', 'WRGB', 'ISOE', 'YAVG', 'UNIF', 'SCEN', 'HUES', 'GPS9', 'CORI', 'IORI', 'FASC', 'GRAV', 'WNDM', 'MWET', 'AALP', 'MSKP', 'LSKP', 'CSCM', 'USRD' ]
      console.log(`\n✅ telemetry['1'].streams.GPS9: `, Object.keys(telemetry['1'].streams.GPS9));
      // [ 'samples', 'name', 'units' ]
      // console.log(`\n✅ telemetry['1'].streams.GPS9: `, telemetry['1'].streams.GPS9);
      // { value: [Array], cts: 0, date: 2026-04-12T14:59:21.199Z, sticky: [Object] },
      // console.log(`\n✅ telemetry['1'].streams.GPS9.samples[0]: `, telemetry['1'].streams.GPS9.samples[0]);
      console.log(`telemetry['1'].streams.GPS9.samples.length`, telemetry['1'].streams.GPS9.samples.length);
      // 831 1m22s 60fps 约 82s 约 82*60=4920帧 但 GPS9 只有 831 个样本,说明 GPS9 的采样率远低于视频帧率,可能是每秒10-15个样本左右 (10.134帧/秒)
      // GoPro GPS9 采样率较低,可能是每秒10-15个样本左右,这与视频帧率(60fps)相比明显较低,说明 GPS 数据并非每帧都采集,而是以较低频率采集以节省电量和存储空间。
      // 这也意味着在分析 GPS 数据时,需要注意时间戳(cts 和 date)以正确对齐视频帧和 GPS 样本,尤其是在需要将 GPS 数据叠加到视频上的应用场景中。
      // ???
      // 206 20s 60fps 约 1200帧 但 GPS9 只有 206 个样本,说明 GPS9 的采样率远低于视频帧率,可能是每秒10-15个样本左右 (10.3帧/秒)
      let i = 0;
      let arr = [];
      for (const sample of telemetry['1'].streams.GPS9.samples) {
        // console.log(`sample =`, sample);
        // 水平速度 m/s 转 km/h
        // console.log(`sample.value[3] =`, sample.value[3] + ` m/s ✅`, sample.value[3] * 3.6 + ` km/h ✅\n`);
        if(i < 10) {
          arr.push(sample.value[3]);
          i++;
        } else {
          const sum = arr.reduce((a, b) => a + b, 0);
          const speed = parseFloat((sum / arr.length).toFixed(3));
          console.log(`average speed =`, `${speed} m/s🔥`, `${speed * 3.6} km/h✅`,  `${speed * 2.23694} mph🚀`);
          i = 0;
          arr = [];
        }
        // for (const key of ['latitude', 'longitude', 'altitude', '2D speed', '3D speed', 'horizontal accuracy', 'vertical accuracy', 'heading', 'satellites']) {
        //   console.log(`sample.value[${i}] (${key}) =`, sample.value[i]);
        //   i++;
        // }
      }
      /* 
        {
          value: [
            31.0449444, 121.2269421,
                4.696,       7.645,
                  7.15,        9598,
              53961.2,         1.6,
                    3
          ],
          cts: 0,
          date: 2026-04-12T14:59:21.199Z,
          sticky: { 'altitude system': 'MSLV' }
        }
      */

      /* 
        各字段含义如下:
        value: 一个数组,依次为(通常 GoPro GPS9 各项含义如下,具体顺序可查阅 GoPro Telemetry 文档):
          纬度(Latitude)
          经度(Longitude)
          海拔高度(Altitude, 单位米)
          水平速度(2D Speed, 单位米/秒)
          3D速度(3D Speed, 单位米/秒)
          水平精度(Horizontal Accuracy, 单位厘米或毫米,具体依设备而定)
          垂直精度(Vertical Accuracy)
          航向(Heading, 单位度)
          卫星数量(Satellites)
        cts: 当前时间戳(采样点的相对时间,通常为毫秒)
        date: 采样点的绝对时间(ISO 格式时间戳)
        sticky: 额外的附加信息,这里 'altitude system': 'MSLV' 表示高度基准为“Mean Sea Level Vertical”(平均海平面)

     */

      // fs.writeFileSync('output_path.json', JSON.stringify(telemetry));
      // console.log('Telemetry saved as JSON');
    });
    // GoProTelemetry(buffer, {stream: ["GPS5"]}, telemetry => {
    //   console.log(`telemetry: `, telemetry);
    //   const gps = telemetry["0"]?.streams?.GPS5;
    //   if (!gps) {
    //     console.log("❌ 没有找到 GPS 数据");
    //     return;
    //   }
    //   console.log(`GSP: `, gps)
    //   // fs.writeFileSync('output_path.json', JSON.stringify(telemetry));
    //   // console.log('Telemetry saved as JSON');
    // });
  }).catch(error => {
    console.error(error);
  });



/* 


 $ node ./demo.js
✅ buffer: {
  rawData: <Buffer 44 45 56 43 00 01 1f ac 44 56 49 44 4c 04 00 01 00 00 00 01 44 56 4e 4d 63 0c 00 01 48 45 52 4f 31 33 20 42 6c 61 63 6b 53 54 52 4d 00 01 05 24 53 54 ... 673646 more bytes>,
  timing: {
    videoDuration: 82.82226666666666,
    frameDuration: 0.016661087641654932,
    start: 2026-04-12T06:59:23.000Z,
    samples: [
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object]
    ]
  }
}

✅ telemetry:  {
  '1': {
    streams: {
      ACCL: [Object],
      GYRO: [Object],
      SHUT: [Object],
      WBAL: [Object],
      WRGB: [Object],
      ISOE: [Object],
      YAVG: [Object],
      UNIF: [Object],
      SCEN: [Object],
      HUES: [Object],
      GPS9: [Object],
      CORI: [Object],
      IORI: [Object],
      FASC: [Object],
      GRAV: [Object],
      WNDM: [Object],
      MWET: [Object],
      AALP: [Object],
      MSKP: [Object],
      LSKP: [Object],
      CSCM: [Object],
      USRD: [Object]
    },
    'device name': 'HERO13 Black'
  },
  'frames/second': 60.02009121540584
}

*/

image

const fs = require("fs");
const gpmfExtract = require("gpmf-extract");
const GoProTelemetry = require("gopro-telemetry");


const rawData = fs.readFileSync("GX010918_Trim_06.11.MP4");
// const rawData = fs.readFileSync("GX010931.MP4");

gpmfExtract(rawData)
  .then(buffer => {
    // console.log(`✅ buffer:`, buffer);
    // console.log(`✅ buffer.rawData:`, buffer.rawData);
    // console.log(`✅ buffer.timing:`, buffer.timing);
    // console.log(`✅ buffer.timing.samples:`, buffer.timing.samples.length, buffer.timing.samples[0]);
    // [{ cts: 0, duration: 1001 }, ...]
    // buffer.timing.samples: 83 { cts: 0, duration: 1001 }


    GoProTelemetry(buffer, {}, telemetry => {
      console.log(`\n✅ telemetry: `, telemetry);
      // console.log(`\n✅ telemetry keys: `,  Object.keys(telemetry));
      // [ '1', 'frames/second' ]
      console.log(`\n🚀 FPS: `,  telemetry['frames/second']);
      // console.log(`\n✅ telemetry['1'] keys: `, Object.keys(telemetry['1']));
      // [ 'streams', 'device name' ]
      console.log(`\n🚀 device name: `, telemetry['1'][`device name`]);
      // console.log(`\n✅ telemetry['1'].streams: `, Object.keys(telemetry['1'].streams));
      // [ 'ACCL', 'GYRO', 'SHUT', 'WBAL', 'WRGB', 'ISOE', 'YAVG', 'UNIF', 'SCEN', 'HUES', 'GPS9', 'CORI', 'IORI', 'FASC', 'GRAV', 'WNDM', 'MWET', 'AALP', 'MSKP', 'LSKP', 'CSCM', 'USRD' ]
      console.log(`\n✅ telemetry['1'].streams.GPS9: `, Object.keys(telemetry['1'].streams.GPS9));
      // [ 'samples', 'name', 'units' ]
      // console.log(`\n✅ telemetry['1'].streams.GPS9: `, telemetry['1'].streams.GPS9);
      // console.log(`\n✅ telemetry['1'].streams.GPS9: `, telemetry['1'].streams.GPS9);
      console.log(`\n🚀 GPS9 name: `, telemetry['1'].streams.GPS9.name);
      // GPS (Lat., Long., Alt., 2D, 3D, days, secs, DOP, fix)
      console.log(`\n🚀 GPS9 units: `, telemetry['1'].streams.GPS9.units);
      // units:  [ 'deg', 'deg', 'm', 'm/s', 'm/s', '', 's', '', '']
      console.log(`\n✅ telemetry['1'].streams.GPS9.samples[0]: `, telemetry['1'].streams.GPS9.samples[0]);
      // {
      //   value: value: [ 31.0449444, 121.2269421, 4.696, 7.645, 7.15, 9598, 53961.2, 1.6, 3 ],
      //   cts: 0,
      //   date: 2026-04-12T14:59:21.199Z,
      //   sticky: { 'altitude system': 'MSLV' }
      // }
      console.log(`telemetry['1'].streams.GPS9.samples.length`, telemetry['1'].streams.GPS9.samples.length);
      // 831 1m22s 60fps 约 82s 约 82*60=4920帧 但 GPS9 只有 831 个样本,说明 GPS9 的采样率远低于视频帧率,可能是每秒10-15个样本左右 (10.134帧/秒)
      // GoPro GPS9 采样率较低,可能是每秒10-15个样本左右,这与视频帧率(60fps)相比明显较低,说明 GPS 数据并非每帧都采集,而是以较低频率采集以节省电量和存储空间。
      // 这也意味着在分析 GPS 数据时,需要注意时间戳(cts 和 date)以正确对齐视频帧和 GPS 样本,尤其是在需要将 GPS 数据叠加到视频上的应用场景中。
      // ???
      // 206 20s 60fps 约 1200帧 但 GPS9 只有 206 个样本,说明 GPS9 的采样率远低于视频帧率,可能是每秒10-15个样本左右 (10.3帧/秒)
      let i = 0;
      let arr = [];
      for (const sample of telemetry['1'].streams.GPS9.samples) {
        // console.log(`sample =`, sample);
        // 水平速度 m/s 转 km/h
        // console.log(`sample.value[3] =`, sample.value[3] + ` m/s ✅`, sample.value[3] * 3.6 + ` km/h ✅\n`);
        if(i < 10) {
          arr.push(sample.value[3]);
          i++;
        } else {
          const sum = arr.reduce((a, b) => a + b, 0);
          const speed = parseFloat((sum / arr.length).toFixed(3));
          console.log(`average speed =`, `${speed} m/s🔥`, `${speed * 3.6} km/h✅`,  `${speed * 2.23694} mph🚀`);
          i = 0;
          arr = [];
        }
        // for (const key of ['latitude', 'longitude', 'altitude', '2D speed', '3D speed', 'horizontal accuracy', 'vertical accuracy', 'heading', 'satellites']) {
        //   console.log(`sample.value[${i}] (${key}) =`, sample.value[i]);
        //   i++;
        // }
      }

      /* 
        {
          value: [
            31.0449444, 121.2269421,
                4.696,       7.645,
                  7.15,        9598,
              53961.2,         1.6,
                    3
          ],
          cts: 0,
          date: 2026-04-12T14:59:21.199Z,
          sticky: { 'altitude system': 'MSLV' }
        }
      */

      /* 
        各字段含义如下:
        value: 一个数组,依次为(通常 GoPro GPS9 各项含义如下,具体顺序可查阅 GoPro Telemetry 文档):
          纬度(Latitude)
          经度(Longitude)
          海拔高度(Altitude, 单位米)
          水平速度(2D Speed, 单位米/秒)
          3D速度(3D Speed, 单位米/秒)
          水平精度(Horizontal Accuracy, 单位厘米或毫米,具体依设备而定)
          垂直精度(Vertical Accuracy)
          航向(Heading, 单位度)
          卫星数量(Satellites)
        cts: 当前时间戳(采样点的相对时间,通常为毫秒)
        date: 采样点的绝对时间(ISO 格式时间戳)
        sticky: 额外的附加信息,这里 'altitude system': 'MSLV' 表示高度基准为“Mean Sea Level Vertical”(平均海平面)

     */

      
      // GPS5 数据通常在 samples 数组中
      const samples = telemetry['1'].streams.GPS9.samples;
      const speed = samples.map(s => ({
        t: s.date || s.cts,
        lat: s.value[0],
        lon: s.value[1],
        alt: s.value[2],
        speed2d: s.value[3], // 速度(如有)
      }));

      fs.writeFileSync("gps-speed.json", JSON.stringify(speed, null, 2));
      console.log("🎉 gps-speed.json 已生成!");
    });
  }).catch(error => {
    console.error(error);
  });



/* 


 $ node ./demo.js
✅ buffer: {
  rawData: <Buffer 44 45 56 43 00 01 1f ac 44 56 49 44 4c 04 00 01 00 00 00 01 44 56 4e 4d 63 0c 00 01 48 45 52 4f 31 33 20 42 6c 61 63 6b 53 54 52 4d 00 01 05 24 53 54 ... 673646 more bytes>,
  timing: {
    videoDuration: 82.82226666666666,
    frameDuration: 0.016661087641654932,
    start: 2026-04-12T06:59:23.000Z,
    samples: [
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object], [Object], [Object],
      [Object], [Object], [Object]
    ]
  }
}

✅ telemetry:  {
  '1': {
    streams: {
      ACCL: [Object],
      GYRO: [Object],
      SHUT: [Object],
      WBAL: [Object],
      WRGB: [Object],
      ISOE: [Object],
      YAVG: [Object],
      UNIF: [Object],
      SCEN: [Object],
      HUES: [Object],
      GPS9: [Object],
      CORI: [Object],
      IORI: [Object],
      FASC: [Object],
      GRAV: [Object],
      WNDM: [Object],
      MWET: [Object],
      AALP: [Object],
      MSKP: [Object],
      LSKP: [Object],
      CSCM: [Object],
      USRD: [Object]
    },
    'device name': 'HERO13 Black'
  },
  'frames/second': 60.02009121540584
}

*/

m/s => km/h, m/s => mph

1 m/s => 3.6 km/h

1 m/s * 60*60 s => 3600 m/h => 3.6 km/h

1 m/s => 2.23494 mph

image

GPS5 vs GPS9

这些字段是 GoPro 视频文件中提取的传感器流(streams)类型的英文缩写。它们的中文含义如下:

  • ACCL:加速度计(Acceleration)
  • GYRO:陀螺仪(Gyroscope)
  • SHUT:快门(Shutter)
  • WBAL:白平衡(White Balance)
  • WRGB:白平衡 RGB 通道(White Balance RGB)
  • ISOE:ISO 感光度(ISO Exposure)
  • YAVG:亮度均值(Luminance Average)
  • UNIF:均匀性(Uniformity)
  • SCEN:场景类型(Scene)
  • HUES:色调(Hues)
  • GPS9GPS 9 轴数据(GPS 9-axis, 包含经纬度、高度、速度等)
  • CORI:科里奥利力(Coriolis, 可能为惯性相关数据)
  • IORI:惯性方向(Inertial Orientation)
  • FASC:加速度计缩放(Accelerometer Scale)
  • GRAV:重力(Gravity)
  • WNDM:风速(Wind Meter)
  • MWET:湿度(Moisture/Wetness)
  • AALP:自动水平(Auto Level Position)
  • MSKP:主快门键(Main Shutter Key Position)
  • LSKP:左快门键(Left Shutter Key Position)
  • CSCM:色彩空间矩阵(Color Space Conversion Matrix)
  • USRD:用户自定义数据(User Data)

这些字段具体含义可能会因固件或 GoPro 机型不同略有差异,常见的如 ACCL、GYRO、GPS9 是运动/定位相关的核心传感器数据。

GPS9 通常包含以下信息(每个采样点的 value 数组顺序如下):

  1. 纬度(Latitude,单位:度)
  2. 经度(Longitude,单位:度)
  3. 海拔高度(Altitude,单位:米)
  4. 水平速度(2D Speed,单位:米/秒)
  5. 三维速度(3D Speed,单位:米/秒)
  6. 水平精度(Horizontal Accuracy,单位:厘米或毫米,视设备而定)
  7. 垂直精度(Vertical Accuracy,单位:秒或其他,视设备而定)
  8. 航向(Heading,单位:度)
  9. 卫星数量(Satellites)

此外,每个样本还包含:

  • cts:采样点的相对时间戳(通常为毫秒)
  • date:采样点的绝对时间(ISO 格式时间戳)
  • sticky:附加信息(如高度基准)

这些数据可用于定位、速度分析、轨迹绘制等场景。

GoPro 在 GoPro 13 中稍微改变了 GPMF 数据中的 GPS 对象。
以前是“GPS5”对象,现在是“GPS9”。
因此,现有软件需要更新,以支持GoPro 13视频中的新结构。

image

https://www.reddit.com/r/gopro/comments/1i62u25/gpmf_to_gpx_or_other_converter/?tl=zh-hans

GPS9 是和 Hero11 一起推出的,但 Hero11 同时有 GPS9GPS5
Hero 13 只有 GPS9 作为 GPS 数据流。

image

https://www.reddit.com/r/gopro/comments/1k28wad/extract_gps_and_sensor_data_from_gopro_videos/?tl=zh-hans

refs

GoPro Telemetry 相关文档和数据格式说明可参考以下链接:

  1. GoPro 官方 GPMF(GoPro Metadata Format)文档(数据结构说明):
  1. gopro-telemetry(你用的 Node.js 库)官方文档和参数说明:
  1. GPS9 数据字段说明(gopro-telemetry issues 讨论):

如需详细字段释义,建议重点查阅 gopro-telemetry 的 README 和 issues 区。

©xgqfrms 2012-2021

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!