Awesome Go

onvif-go

CategoryVideo
SubcategoryVideo
Stars41

ONVIF client, WS-Discovery and virtual camera server for IP cameras

About onvif-go

Modern, high-performance Go library for ONVIF IP camera integration - Control surveillance cameras, NVRs, and video devices with comprehensive ONVIF Profile S/T/G support. Includes both client and server implementations for complete ONVIF camera simulation and testing.


onvif-go is a Go library for IP cameras, NVRs and other devices that speak ONVIF. Use it to find cameras on the network, read their RTSP streams and snapshots, move PTZ cameras, change image settings and manage the device. It also includes a virtual camera server, so you can test code that depends on a camera without owning one.

  • Battle-tested: verified with multiple ONVIF-compliant cameras, including Hikvision, Dahua, Axis, Bosch and Reolink.
  • Client: over 200 typed operations across Device, Media, PTZ, Imaging, Events and Device I/O, with WS-Security digest authentication.
  • Discovery: find devices with WS-Discovery, or answer probes for your own.
  • Virtual cameras: a multi-lens camera simulator with stable identities that survive restarts.
  • Command-line tools: prebuilt binaries for discovery, diagnostics and scripting.
  • Small footprint: the library itself needs only google/uuid beyond the standard library. rtspeek and its RTSP stack are used by onvif-cli alone, for stream checks.

Install

go get github.com/0x524a/onvif-go

Requires Go 1.25 or newer. Prebuilt command-line tools are attached to every release.

Quick start

Find cameras

devices, err := discovery.Discover(ctx, 5*time.Second)
if err != nil {
    log.Fatal(err)
}

for _, d := range devices {
    fmt.Println(d.GetName(), d.GetDeviceEndpoint())
}

Connect and get a stream

[!TIP] The endpoint can be a full URL, host:port, or a bare IP address. A bare IP gets http:// and /onvif/device_service added.

client, err := onvif.NewClient(
    "192.168.1.100",
    onvif.WithCredentials("admin", "password"),
    onvif.WithTimeout(30*time.Second),
)
if err != nil {
    log.Fatal(err)
}

// Initialize asks the camera where its media, PTZ and imaging services are.
if err := client.Initialize(ctx); err != nil {
    log.Fatal(err)
}

profiles, err := client.GetProfiles(ctx)
if err != nil {
    log.Fatal(err)
}

uri, err := client.GetStreamURI(ctx, profiles[0].Token)
if err != nil {
    log.Fatal(err)
}

fmt.Println(uri.URI) // rtsp://192.168.1.100:554/...

Move a PTZ camera

velocity := &onvif.PTZSpeed{PanTilt: &onvif.Vector2D{X: 0.5, Y: 0}} // pan right
timeout := "PT2S"                                                     // for two seconds

err := client.ContinuousMove(ctx, token, velocity, &timeout)
err = client.Stop(ctx, token, true, true)

presets, err := client.GetPresets(ctx, token)
err = client.GotoPreset(ctx, token, presets[0].Token, nil)

[!NOTE] Every method takes a context.Context first, so timeouts and cancellation work everywhere.

More runnable snippets are in the Go docs and the examples directory.

Test without a camera

The server package is a virtual ONVIF camera with Device, Media, PTZ and Imaging services:

cfg := server.DefaultConfig()
cfg.Port = 0                      // let the OS pick a free port
cfg.EndpointSeed = "lobby-camera" // same identity on every start

srv, err := server.New(cfg)
if err != nil {
    log.Fatal(err)
}

go srv.Start(ctx)

Or from the shell:

go install github.com/0x524a/onvif-go/cmd/onvif-server@latest
onvif-server -profiles 3 -username admin -password admin -port 8080

[!TIP] To make it discoverable on the network, register srv.DiscoveryDevice() with a discovery.Responder. See the server README for configuration, stable identities and the WS-Discovery responder.

Captured responses from real cameras are replayed in the test suite through a mock server (testing/captures), so a fix for one camera is checked against the others. See the camera testing guide to add yours.

What it covers

ServiceMethodsIncludes
Device97Information, capabilities, network, users, certificates, Wi-Fi and 802.1X, storage, logs, firmware
Media82Profiles, RTSP and HTTP stream URIs, snapshots, video, audio and metadata configuration
PTZ13Continuous, absolute and relative moves, presets, home position, status
Imaging7Brightness, contrast, exposure, focus, white balance, wide dynamic range
Events12Subscriptions and pull points
Device I/O14Relays, digital inputs, video outputs
DiscoveryProbe the network or answer probes, by interface or by unicast address

The full list, with signatures and descriptions, is the API reference, generated from the source. Device Management status is tracked in DEVICE_API_STATUS.md.

Command-line tools

ToolUse it to
onvif-cliDiscover cameras and read or change settings, interactively or with one-shot flags for scripts (-op info, -op stream, -op discover). See non-interactive mode.
onvif-diagnosticsTest a real camera and capture its raw SOAP, then turn the capture into a regression test. See XML debugging.
onvif-serverRun virtual cameras from the shell.
onvif-quickDiscover, connect and try PTZ in a few keystrokes.
generate-testsGenerate a replay test from a captured archive.
go install github.com/0x524a/onvif-go/cmd/onvif-cli@latest
onvif-cli -endpoint http://camera/onvif/device_service -username admin -password pass -op info

On a machine with several network interfaces, pick the one to probe from with -i eth0, or in code with discovery.DiscoverOptions{NetworkInterface: "eth0"}. See network interface selection.

Compatibility

  • Go: 1.25 or newer; CI also runs the latest release.
  • ONVIF: Profile S, T and G operations.
  • Cameras: verified with multiple ONVIF-compliant cameras, including Hikvision, Dahua, Axis, Bosch, Reolink and others. Responses captured from Axis, Bosch and Reolink devices are also replayed in the automated test suite. If yours misbehaves, please open an issue; a capture from it (see the camera testing guide) is the most useful thing you can attach.

Documentation

Contributing

Contributions are welcome. For anything larger than a fix, please open an issue first. See CONTRIBUTING.md for the workflow, and run make check before you push.

Acknowledgements

onvif-go stands on other people's work:

  • gortsplib and mediacommon by the bluenviron project: the RTSP client and media-format library behind the stream inspection in onvif-cli, through rtspeek.
  • Pion: the RTP, RTCP, SDP and SRTP libraries that gortsplib builds on.
  • google/uuid: the identifiers behind the virtual cameras' stable endpoint references.
  • use-go/onvif, the earlier Go ONVIF library that inspired this one, and the specifications published by ONVIF.org.

The licenses of everything compiled into the library and the tools are reproduced in THIRD_PARTY_NOTICES.md, which also ships in every release archive.

Star history

If you find this project useful, please consider giving it a star! ⭐

License

MIT, see LICENSE.


Frequently Asked Questions

What is onvif-go?

onvif-go is a Video library for the Go programming language. ONVIF client, WS-Discovery and virtual camera server for IP cameras

How do I install onvif-go?

Install onvif-go with the Go module system using `go get 0x524a/onvif-go`. Check the repository for the current installation instructions.

What category does onvif-go belong to?

onvif-go is listed under Video, specifically Video.

← Back to Video