Programster's Blog

Tutorials focusing on Linux, programming, and open source

Extracting GPS From Go Pro Hero 5

GPS

In the tutorial below, we are going to use a Golang script and FFmpeg to extract the GPS data from the video file we pulled off the SD card on a GoPro Hero 5 Black.

Similar Posts

Steps

Install FFmpeg if you haven't got it already.

Probe your video file...

ffprobe GOPRxxxx.MP4

... and you should see something like below...

...
  Duration: 00:06:54.98, start: 0.000000, bitrate: 45147 kb/s
    Chapter #0:0: start 5.818000, end 414.976000
    Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 44958 kb/s, 47.95 fps, 47.95 tbr, 48k tbn, 95.90 tbc (default)
    Metadata:
      creation_time   : 2017-12-07T07:06:41.000000Z
      handler_name    :     GoPro AVC
      encoder         : GoPro AVC encoder
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2017-12-07T07:06:41.000000Z
      handler_name    :     GoPro AAC
    Stream #0:2(eng): Data: none (gpmd / 0x646D7067), 38 kb/s (default)
    Metadata:
      creation_time   : 2017-12-07T07:06:41.000000Z
      handler_name    :     GoPro MET
    Stream #0:3(eng): Data: none (fdsc / 0x63736466), 12 kb/s (default)
    Metadata:
      creation_time   : 2017-12-07T07:06:41.000000Z
      handler_name    :     GoPro SOS
Unsupported codec with id 0 for input stream 2
Unsupported codec with id 0 for input stream 3

The key thing we are looking for is gpmd which appears to be stream 2 as seen here:

Stream #0:2(eng): Data: none (gpmd / 0x646D7067), 38 kb/s (default)

Extract that stream into a file using the following command (notice we are using -map 0:2 because we found the data was in stream 2 in the previous step).

ffmpeg -y -i GOPR0xxx.MP4 -codec copy -map 0:2 -f rawvideo gps-data.bin

That will have created a binary file that will look similar to below if you try to open it in a text editor.

4445 5643 0001 1270 4456 4944 4c04 0001
0000 0001 4456 4e4d 6301 0006 4361 6d65
7261 0000 5449 434b 4c04 0001 0001 0c49
5354 524d 0001 0518 5453 4d50 4c04 0001
0000 00c4 5449 434b 4c04 0001 0001 0c49
5354 4e4d 6301 0032 4163 6365 6c65 726f
...

In order to convert that binary file into a useful format (a JSON text file in this case), we need to install Golang in order to use an open source tool to do the conversion for us.

sudo apt-get install golang-go

Now that we have golang, we need to download the script that we will run to convert the file.

wget https://raw.githubusercontent.com/JuanIrache/gopro-utils/master/bin/gopro2json/gopro2json.go

Unfortunately, that script will require some packages. Set a path to where you want to the packages to be kept, and grab them using the commands below. Because I am doing this as a one off, I am just going to use my local folder.

export GOPATH=`pwd`
go get github.com/JuanIrache/gopro-utils/telemetry
go get github.com/paulmach/go.geo

Now we can finally run the go script to convert the binary file into a useful JSON format:

go run gopro2json.go \
-i gps-data.bin \
-o gps-data.json

If you open up the gps-data.json file, you will see the JSON data all on one line. This is doesn't matter to a computer, but if you want to be able to read it as a human, you can use JSON lint to expand it into a form you could possibly read. The result is below:

{
    "data": [{
        "lat": -23.508924,
        "lon": -46.7155405,
        "alt": 716.334,
        "spd": 10.528,
        "spd_3d": 10.5,
        "utc": 1512637481309000,
        "gps_accuracy": 362,
        "gps_fix": 3,
        "temp": 30.673828,
        "track": 237.93483235905228
    }, {
        "lat": -23.5089242,
...

References