Files
onvif-go/examples/discover-and-test/main.go
T

256 lines
8.3 KiB
Go

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")
}