# Quick Start Guide Get up and running with onvif-go in 5 minutes! ## Installation ```bash go get github.com/0x524a/onvif-go ``` ## Step 1: Discover Cameras Find ONVIF cameras on your network: ```go 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()) } } ``` ### Discover on Specific Network Interface If you have multiple network interfaces, specify which one to use: ```go import "github.com/0x524a/onvif-go/discovery" // Option 1: Discover on specific interface by name opts := &discovery.DiscoverOptions{ NetworkInterface: "eth0", // Use Ethernet } devices, err := discovery.DiscoverWithOptions(ctx, 5*time.Second, opts) // Option 2: Discover using IP address opts := &discovery.DiscoverOptions{ NetworkInterface: "192.168.1.100", } devices, err := discovery.DiscoverWithOptions(ctx, 5*time.Second, opts) // Option 3: List available interfaces interfaces, err := discovery.ListNetworkInterfaces() for _, iface := range interfaces { fmt.Printf("%s: %v (Multicast: %v)\n", iface.Name, iface.Addresses, iface.Multicast) } ``` For more details, see [NETWORK_INTERFACE_GUIDE.md](discovery/NETWORK_INTERFACE_GUIDE.md). ## Step 2: Connect to Camera Create a client and get basic information. The endpoint can be specified in multiple formats: ```go 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: ```go // 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: ```go 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: ```go // 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: ```go 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 1. **Explore Examples**: Check out the `examples/` directory for more detailed use cases 2. **Read Documentation**: Visit [pkg.go.dev](https://pkg.go.dev/github.com/0x524a/onvif-go) 3. **Review Architecture**: See [ARCHITECTURE.md](ARCHITECTURE.md) for design details 4. **Check Issues**: Look at [GitHub Issues](https://github.com/0x524a/onvif-go/issues) for known issues ## Common Patterns ### Error Handling ```go 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 ```go ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() result, err := client.SomeOperation(ctx) ``` ### Checking Service Support ```go 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 1. **Always Initialize**: Call `client.Initialize(ctx)` before using service-specific methods 2. **Use Timeouts**: Always use contexts with timeouts for network operations 3. **Reuse Clients**: Create one client per camera and reuse it 4. **Check Capabilities**: Use `GetCapabilities()` to check what the camera supports 5. **Handle Errors**: Check for `ErrServiceNotSupported` when 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 - [ONVIF Official Site](https://www.onvif.org) - [ONVIF Core Specification](https://www.onvif.org/specs/core/ONVIF-Core-Specification.pdf) - [ONVIF Device Test Tool](https://www.onvif.org/tools/) Happy coding! 🎥📹