Today’s new project is a Go library for talking to Garmin Virb cameras over WiFi. It’s on Github as scottlaird/virb. I’ve implemented almost the entire API covered by Garmin’s Camera Network Services API, including listing, copying, and deleting files; shooting video and still images; and configuring the camera.

This has been tested with Go 1.12, but should be trivially compatible with earlier versions of Go.

I’ve tested it with a Garmin Virb Ultra 30 and a Virb 360. Garmin’s documentation says that the older Virb X and XE should work as well, plus the Garmin Dashcam 45, 55, and 65W, but I don’t have one to test with.

The library includes a command-line tool that exists mostly to exercise the library, but can be used to access the camera from the command line or scripts. To install it, just run go get github.com/scottlaird/virb/virb, and Go 1.12+ will fetch all of the dependencies and install it automatically, probably into $HOME/go/bin.


    $ virb --camera 10.1.0.180 medialist
    {Media:[{Date:1539283354 Duration:1800 Fav:false FileSize:18066437201
    FitURL:http://10.1.0.180:80/GMetrix/2018-10-11-10-34-22.fit GroupID:100019
    Index:1 LensMode:360 LowResVideoPath:http://10.1.0.180:80/DCIM/100_VIRB/V0190034.GLV
    Name:V0190034.MP4 ThumbURL:http://10.1.0.180:80/DCIM/100_VIRB/V0190034.THM
    Type:video Url:http://10.1.0.180:80/DCIM/100_VIRB/V0190034.MP4} {Date:1539295752
    Duration:1801 Fav:false FileSize:18074818018 FitURL:http://10.1.0.180:80/GMetrix/2018-10-11-14-07-02.fit
    GroupID:100020 Index:1 LensMode:360 LowResVideoPath:http://10.1.0.180:80/DCIM/100_VIRB/V0200035.GLV
    Name:V0200035.MP4 ThumbURL:http://10.1.0.180:80/DCIM/100_VIRB/V0200035.THM
    Type:video Url:http://10.1.0.180:80/DCIM/100_VIRB/V0200035.MP4}
    ... Result:1}

    $ virb --camera 10.1.0.180 snappicture
    {Media:{Name:V0260044.JPG ThumbUrl:http://10.1.0.180:80/thumb/DCIM/100_VIRB/V0260044.JPG Type:photo Url:http://10.1.0.180:80/DCIM/100_VIRB/V0260044.JPG} Result:1}

I wrote this for another project that’s still under development, but it should be generally useful. It’s pretty trivial to use. Here’s a slight variant on the implementation of the virb snappicture command, condensed for clarity:

package main

import (
	"fmt"
	"github.com/scottlaird/virb"
)

func main() {
     camera := "10.1.0.180"
     
     resp, err := virb.SnapPicture(camera)
     if err != nil {
        panic(err)
     }

     fmt.Printf("%+v\n", *resp)
}

Calls that take arguments are slightly more involved, but should still be straightforward. Here’s what it takes to start live streaming from the camera:

package main

import (
	"fmt"
	"github.com/scottlaird/virb"
)

func main() {
     camera := "10.1.0.180"
     streamType := "rtp"
     maxResolution := 0
     active := "1"
     
     resp, err := virb.LivePreview(camera, streamType, maxResolution, active)
     if err != nil {
         panic(err)
     }

     if resp.Result == 1 {
         fmt.Printf("The live stream URL is %s\n", resp.Url)
     } else {
         fmt.Printf("Live stream failed with error %d\n", resp.Result)
     }
}