onvif-go
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-clialone, 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 getshttp://and/onvif/device_serviceadded.
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.Contextfirst, 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 adiscovery.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
| Service | Methods | Includes |
|---|---|---|
| Device | 97 | Information, capabilities, network, users, certificates, Wi-Fi and 802.1X, storage, logs, firmware |
| Media | 82 | Profiles, RTSP and HTTP stream URIs, snapshots, video, audio and metadata configuration |
| PTZ | 13 | Continuous, absolute and relative moves, presets, home position, status |
| Imaging | 7 | Brightness, contrast, exposure, focus, white balance, wide dynamic range |
| Events | 12 | Subscriptions and pull points |
| Device I/O | 14 | Relays, digital inputs, video outputs |
| Discovery | Probe 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
| Tool | Use it to |
|---|---|
onvif-cli | Discover 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-diagnostics | Test a real camera and capture its raw SOAP, then turn the capture into a regression test. See XML debugging. |
onvif-server | Run virtual cameras from the shell. |
onvif-quick | Discover, connect and try PTZ in a few keystrokes. |
generate-tests | Generate 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.