7.9 KiB
7.9 KiB
Quick Start Guide
Get up and running with go-onvif in 5 minutes!
Installation
go get github.com/0x524a/onvif-go
Step 1: Discover Cameras
Find ONVIF cameras on your network:
package main
import (
"context"
"fmt"
"time"
"github.com/0x524a/onvif-go/discovery"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
devices, err := discovery.Discover(ctx, 5*time.Second)
if err != nil {
panic(err)
}
for _, device := range devices {
fmt.Printf("Found: %s at %s\n",
device.GetName(),
device.GetDeviceEndpoint())
}
}
Step 2: Connect to Camera
Create a client and get basic information. The endpoint can be specified in multiple formats:
package main
import (
"context"
"fmt"
"time"
"github.com/0x524a/onvif-go"
)
func main() {
// Create client - endpoint accepts multiple formats:
// - Simple IP: "192.168.1.100"
// - IP with port: "192.168.1.100:8080"
// - Full URL: "http://192.168.1.100/onvif/device_service"
client, err := onvif.NewClient(
"192.168.1.100", // Simple IP address works!
onvif.WithCredentials("admin", "password"),
onvif.WithTimeout(30*time.Second),
)
if err != nil {
panic(err)
}
ctx := context.Background()
// Get device info
info, err := client.GetDeviceInformation(ctx)
if err != nil {
panic(err)
}
fmt.Printf("Camera: %s %s (Firmware: %s)\n",
info.Manufacturer,
info.Model,
info.FirmwareVersion)
}
Step 3: Get Stream URL
Retrieve RTSP stream URLs:
// Initialize client (discovers service endpoints)
if err := client.Initialize(ctx); err != nil {
panic(err)
}
// Get profiles
profiles, err := client.GetProfiles(ctx)
if err != nil {
panic(err)
}
// Get stream URI for first profile
if len(profiles) > 0 {
streamURI, err := client.GetStreamURI(ctx, profiles[0].Token)
if err != nil {
panic(err)
}
fmt.Printf("Stream URL: %s\n", streamURI.URI)
// Example: rtsp://192.168.1.100/stream1
}
Step 4: Control PTZ
Move the camera:
profileToken := profiles[0].Token
// Move right for 2 seconds
velocity := &onvif.PTZSpeed{
PanTilt: &onvif.Vector2D{X: 0.5, Y: 0.0},
}
timeout := "PT2S"
client.ContinuousMove(ctx, profileToken, velocity, &timeout)
time.Sleep(2 * time.Second)
// Stop movement
client.Stop(ctx, profileToken, true, false)
// Go to home position
homePosition := &onvif.PTZVector{
PanTilt: &onvif.Vector2D{X: 0.0, Y: 0.0},
}
client.AbsoluteMove(ctx, profileToken, homePosition, nil)
Step 5: Adjust Image Settings
Modify camera imaging settings:
// Get video source token
videoSourceToken := profiles[0].VideoSourceConfiguration.SourceToken
// Get current settings
settings, err := client.GetImagingSettings(ctx, videoSourceToken)
if err != nil {
panic(err)
}
// Modify brightness and contrast
brightness := 60.0
settings.Brightness = &brightness
contrast := 55.0
settings.Contrast = &contrast
// Apply settings
err = client.SetImagingSettings(ctx, videoSourceToken, settings, true)
if err != nil {
panic(err)
}
fmt.Println("Imaging settings updated!")
Complete Example
Here's a complete program that does everything:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/0x524a/onvif-go"
)
func main() {
// Configuration
endpoint := "http://192.168.1.100/onvif/device_service"
username := "admin"
password := "password"
// Create client
client, err := onvif.NewClient(
endpoint,
onvif.WithCredentials(username, password),
onvif.WithTimeout(30*time.Second),
)
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Get device information
fmt.Println("Getting device information...")
info, err := client.GetDeviceInformation(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Camera: %s %s\n", info.Manufacturer, info.Model)
// Initialize client
fmt.Println("\nInitializing client...")
if err := client.Initialize(ctx); err != nil {
log.Fatal(err)
}
// Get profiles
fmt.Println("Getting media profiles...")
profiles, err := client.GetProfiles(ctx)
if err != nil {
log.Fatal(err)
}
if len(profiles) == 0 {
log.Fatal("No profiles found")
}
profile := profiles[0]
fmt.Printf("Using profile: %s\n", profile.Name)
// Get stream URI
streamURI, err := client.GetStreamURI(ctx, profile.Token)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Stream URI: %s\n", streamURI.URI)
// Get snapshot URI
snapshotURI, err := client.GetSnapshotURI(ctx, profile.Token)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Snapshot URI: %s\n", snapshotURI.URI)
// PTZ control (if supported)
fmt.Println("\nTesting PTZ control...")
status, err := client.GetStatus(ctx, profile.Token)
if err != nil {
fmt.Printf("PTZ not supported or error: %v\n", err)
} else {
fmt.Println("PTZ is supported!")
if status.Position != nil && status.Position.PanTilt != nil {
fmt.Printf("Current position: X=%.2f, Y=%.2f\n",
status.Position.PanTilt.X,
status.Position.PanTilt.Y)
}
}
fmt.Println("\nSetup complete!")
}
Next Steps
- Explore Examples: Check out the
examples/directory for more detailed use cases - Read Documentation: Visit pkg.go.dev
- Review Architecture: See ARCHITECTURE.md for design details
- Check Issues: Look at GitHub Issues for known issues
Common Patterns
Error Handling
info, err := client.GetDeviceInformation(ctx)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) {
// Handle timeout
} else if onvif.IsONVIFError(err) {
// Handle SOAP fault
} else {
// Handle other errors
}
return err
}
Context with Timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := client.SomeOperation(ctx)
Checking Service Support
status, err := client.GetStatus(ctx, profileToken)
if errors.Is(err, onvif.ErrServiceNotSupported) {
fmt.Println("PTZ not supported on this camera")
} else if err != nil {
return err
}
Tips & Tricks
- Always Initialize: Call
client.Initialize(ctx)before using service-specific methods - Use Timeouts: Always use contexts with timeouts for network operations
- Reuse Clients: Create one client per camera and reuse it
- Check Capabilities: Use
GetCapabilities()to check what the camera supports - Handle Errors: Check for
ErrServiceNotSupportedwhen using optional services
Troubleshooting
Camera Not Found During Discovery
- Check network connectivity
- Ensure camera is on the same subnet
- Verify ONVIF is enabled on the camera
- Check firewall settings (UDP port 3702)
Authentication Failed
- Verify username and password
- Check if camera requires admin privileges
- Some cameras need authentication enabled
Connection Timeout
- Increase timeout duration
- Check network latency
- Verify endpoint URL is correct
- Test with ping/curl first
Service Not Supported
- Check camera capabilities with
GetCapabilities() - Update camera firmware if needed
- Some features require specific ONVIF profiles
Additional Resources
Happy coding! 🎥📹