package main import ( "context" "fmt" "log" "time" "github.com/0x524a/onvif-go" "github.com/0x524a/onvif-go/discovery" ) func main() { fmt.Println("šŸ” Discovering ONVIF cameras on the network...") fmt.Println("This may take a few seconds...") fmt.Println() ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() devices, err := discovery.Discover(ctx, 10*time.Second) if err != nil { log.Fatalf("āŒ Discovery failed: %v", err) } if len(devices) == 0 { fmt.Println("āŒ No ONVIF cameras found on the network") fmt.Println("šŸ’” Make sure:") fmt.Println(" - Camera is powered on and connected to the network") fmt.Println(" - ONVIF is enabled on the camera") fmt.Println(" - You're on the same network segment as the camera") fmt.Println(" - Camera IP 192.168.1.201 is reachable (try: ping 192.168.1.201)") return } fmt.Printf("āœ… Found %d camera(s):\n\n", len(devices)) var targetDevice *discovery.Device for i, device := range devices { fmt.Printf("šŸ“¹ Camera #%d:\n", i+1) fmt.Printf(" Endpoint: %s\n", device.GetDeviceEndpoint()) fmt.Printf(" Name: %s\n", device.GetName()) fmt.Printf(" Location: %s\n", device.GetLocation()) fmt.Printf(" Types: %v\n", device.Types) fmt.Printf(" XAddrs: %v\n", device.XAddrs) fmt.Println() // Check if this is our target camera (192.168.1.201) endpoint := device.GetDeviceEndpoint() if len(endpoint) > 7 { // Simple check if endpoint contains the IP if len(endpoint) > 20 && (endpoint[7:20] == "192.168.1.201" || endpoint[7:21] == "192.168.1.201:") { targetDevice = device } } } if targetDevice == nil { fmt.Println("āš ļø Camera at 192.168.1.201 was not discovered") fmt.Println("šŸ’” You can still try to connect manually with the correct endpoint") return } // Now try to connect to the discovered camera fmt.Printf("\nšŸŽÆ Found target camera at 192.168.1.201\n") fmt.Printf("Endpoint: %s\n", targetDevice.GetDeviceEndpoint()) fmt.Println() // Test connection with credentials username := "service" password := "Service.1234" fmt.Println("šŸ“” Connecting with credentials...") client, err := onvif.NewClient( targetDevice.GetDeviceEndpoint(), onvif.WithCredentials(username, password), onvif.WithTimeout(30*time.Second), ) if err != nil { log.Fatalf("āŒ Failed to create client: %v", err) } ctx2 := context.Background() // Get device information fmt.Println("šŸ” Retrieving device information...") info, err := client.GetDeviceInformation(ctx2) if err != nil { log.Fatalf("āŒ Failed to get device information: %v\n\nšŸ’” Possible issues:\n - Wrong username or password\n - Camera requires different authentication\n - Try username/password combinations like: admin/admin, admin/12345, etc.\n", err) } fmt.Printf("\nāœ… Device Information:\n") fmt.Printf(" Manufacturer: %s\n", info.Manufacturer) fmt.Printf(" Model: %s\n", info.Model) fmt.Printf(" Firmware: %s\n", info.FirmwareVersion) fmt.Printf(" Serial Number: %s\n", info.SerialNumber) fmt.Printf(" Hardware ID: %s\n", info.HardwareID) // Initialize client (discover service endpoints) fmt.Println("\nšŸ”§ Initializing client and discovering services...") if err := client.Initialize(ctx2); err != nil { log.Fatalf("āŒ Failed to initialize client: %v", err) } fmt.Println("āœ… Services discovered successfully") // Get capabilities fmt.Println("\nšŸŽÆ Getting device capabilities...") caps, err := client.GetCapabilities(ctx2) if err != nil { log.Printf("āš ļø Failed to get capabilities: %v", err) } else { fmt.Println("āœ… Supported Services:") if caps.Device != nil { fmt.Println(" āœ“ Device Service") } if caps.Media != nil { fmt.Println(" āœ“ Media Service (Streaming)") } if caps.PTZ != nil { fmt.Println(" āœ“ PTZ Service (Pan/Tilt/Zoom)") } if caps.Imaging != nil { fmt.Println(" āœ“ Imaging Service") } if caps.Events != nil { fmt.Println(" āœ“ Event Service") } if caps.Analytics != nil { fmt.Println(" āœ“ Analytics Service") } } // Get media profiles fmt.Println("\nšŸ“¹ Retrieving media profiles...") profiles, err := client.GetProfiles(ctx2) if err != nil { log.Fatalf("āŒ Failed to get profiles: %v", err) } fmt.Printf("\nāœ… Found %d profile(s):\n", len(profiles)) for i, profile := range profiles { fmt.Printf("\nšŸ“ŗ Profile #%d:\n", i+1) fmt.Printf(" Token: %s\n", profile.Token) fmt.Printf(" Name: %s\n", profile.Name) if profile.VideoEncoderConfiguration != nil { fmt.Printf(" Encoding: %s\n", profile.VideoEncoderConfiguration.Encoding) if profile.VideoEncoderConfiguration.Resolution != nil { fmt.Printf(" Resolution: %dx%d\n", profile.VideoEncoderConfiguration.Resolution.Width, profile.VideoEncoderConfiguration.Resolution.Height) } fmt.Printf(" Quality: %.1f\n", profile.VideoEncoderConfiguration.Quality) if profile.VideoEncoderConfiguration.RateControl != nil { fmt.Printf(" Frame Rate: %d fps\n", profile.VideoEncoderConfiguration.RateControl.FrameRateLimit) fmt.Printf(" Bitrate: %d kbps\n", profile.VideoEncoderConfiguration.RateControl.BitrateLimit) } } if profile.PTZConfiguration != nil { fmt.Printf(" PTZ: Enabled\n") } // Get stream URI streamURI, err := client.GetStreamURI(ctx2, profile.Token) if err != nil { fmt.Printf(" Stream URI: āŒ Error - %v\n", err) } else { fmt.Printf(" Stream URI: %s\n", streamURI.URI) fmt.Printf(" šŸ“± Use this URL in VLC or other RTSP player\n") } // Get snapshot URI snapshotURI, err := client.GetSnapshotURI(ctx2, profile.Token) if err != nil { fmt.Printf(" Snapshot URI: āŒ Error - %v\n", err) } else { fmt.Printf(" Snapshot URI: %s\n", snapshotURI.URI) fmt.Printf(" 🌐 You can open this URL in a browser\n") } } // Test PTZ if available if len(profiles) > 0 { fmt.Println("\nšŸŽ® Testing PTZ capabilities...") profileToken := profiles[0].Token status, err := client.GetStatus(ctx2, profileToken) 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: Pan=%.3f, Tilt=%.3f\n", status.Position.PanTilt.X, status.Position.PanTilt.Y) } if status.Position != nil && status.Position.Zoom != nil { fmt.Printf(" Current Zoom: %.3f\n", status.Position.Zoom.X) } // Get presets presets, err := client.GetPresets(ctx2, profileToken) if err != nil { fmt.Printf(" Presets: āŒ Error - %v\n", err) } else { fmt.Printf(" Available Presets: %d\n", len(presets)) for _, preset := range presets { fmt.Printf(" - %s (Token: %s)\n", preset.Name, preset.Token) } } } } // Test Imaging if available if len(profiles) > 0 && profiles[0].VideoSourceConfiguration != nil { fmt.Println("\nšŸŽØ Testing Imaging capabilities...") videoSourceToken := profiles[0].VideoSourceConfiguration.SourceToken settings, err := client.GetImagingSettings(ctx2, videoSourceToken) if err != nil { fmt.Printf("āš ļø Imaging settings not available: %v\n", err) } else { fmt.Println("āœ… Current Imaging Settings:") if settings.Brightness != nil { fmt.Printf(" Brightness: %.1f\n", *settings.Brightness) } if settings.Contrast != nil { fmt.Printf(" Contrast: %.1f\n", *settings.Contrast) } if settings.ColorSaturation != nil { fmt.Printf(" Saturation: %.1f\n", *settings.ColorSaturation) } if settings.Sharpness != nil { fmt.Printf(" Sharpness: %.1f\n", *settings.Sharpness) } if settings.Exposure != nil { fmt.Printf(" Exposure Mode: %s\n", settings.Exposure.Mode) } if settings.Focus != nil { fmt.Printf(" Focus Mode: %s\n", settings.Focus.AutoFocusMode) } if settings.WhiteBalance != nil { fmt.Printf(" White Balance: %s\n", settings.WhiteBalance.Mode) } } } fmt.Println("\nāœ… All tests completed successfully!") fmt.Println("\nšŸ’” Next steps:") fmt.Println(" - Use the stream URI in VLC to view the live feed") fmt.Println(" - Open the snapshot URI in a browser to see still images") fmt.Println(" - Use the PTZ controls to move the camera (if supported)") fmt.Println(" - Adjust imaging settings for better image quality") }