256 lines
8.3 KiB
Go
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")
|
|
}
|