# ONVIF Server - Virtual IP Camera Simulator A complete ONVIF-compliant server implementation that simulates multi-lens IP cameras with full support for Device, Media, PTZ, and Imaging services. ## Features ### ๐ŸŽฅ Multi-Lens Camera Support - **Multiple Video Profiles**: Support for up to 10 independent camera profiles - **Different Resolutions**: From 640x480 to 4K (3840x2160) - **Configurable Framerates**: 25, 30, 60 fps - **Multiple Encodings**: H.264, H.265, MPEG4, JPEG ### ๐ŸŽฎ PTZ Control - **Continuous Movement**: Smooth pan, tilt, and zoom control - **Absolute Positioning**: Move to specific coordinates - **Relative Movement**: Move relative to current position - **Preset Positions**: Save and recall camera positions - **Status Monitoring**: Real-time PTZ state information ### ๐Ÿ“ท Imaging Control - **Brightness, Contrast, Saturation**: Full color control - **Exposure Settings**: Auto/Manual modes with gain control - **Focus Control**: Auto-focus and manual focus positioning - **White Balance**: Auto/Manual white balance adjustment - **Wide Dynamic Range (WDR)**: Enhanced contrast in challenging lighting - **IR Cut Filter**: Day/Night mode control ### ๐ŸŒ ONVIF Services - โœ… **Device Service**: Device information, capabilities, system time - โœ… **Media Service**: Profiles, stream URIs (RTSP), snapshots - โœ… **PTZ Service**: Full PTZ control and preset management - โœ… **Imaging Service**: Complete imaging settings control - โณ **Events Service**: (Planned) ### ๐Ÿ” Security - **WS-Security Authentication**: UsernameToken with password digest - **Configurable Credentials**: Custom username/password - **SOAP Message Security**: Nonce and timestamp validation ## Installation ```bash # Clone the repository (if not already done) git clone https://github.com/0x524a/onvif-go cd onvif-go # Build the server CLI go build -o onvif-server ./cmd/onvif-server # Or install globally go install ./cmd/onvif-server ``` ## Quick Start ### Basic Usage Start the server with default settings (3 camera profiles): ```bash ./onvif-server ``` The server will start on `http://0.0.0.0:8080` with: - Username: `admin` - Password: `admin` - 3 camera profiles with different resolutions - PTZ and Imaging services enabled ### Custom Configuration ```bash # Custom credentials and port ./onvif-server -username myuser -password mypass -port 9000 # More camera profiles ./onvif-server -profiles 5 # Disable PTZ ./onvif-server -ptz=false # Custom device information ./onvif-server -manufacturer "Acme Corp" -model "SuperCam 5000" ``` ### Command-Line Options ``` -host string Server host address (default "0.0.0.0") -port int Server port (default 8080) -username string Authentication username (default "admin") -password string Authentication password (default "admin") -manufacturer string Device manufacturer (default "onvif-go") -model string Device model (default "Virtual Multi-Lens Camera") -firmware string Firmware version (default "1.0.0") -serial string Serial number (default "SN-12345678") -profiles int Number of camera profiles (1-10) (default 3) -ptz Enable PTZ support (default true) -imaging Enable Imaging support (default true) -events Enable Events support (default false) -info Show server info and exit -version Show version and exit ``` ## Using the Server Library ### Simple Example ```go package main import ( "context" "log" "time" "github.com/0x524a/onvif-go/server" ) func main() { // Use default configuration config := server.DefaultConfig() // Or customize config.Port = 9000 config.Username = "myuser" config.Password = "mypass" // Create server srv, err := server.New(config) if err != nil { log.Fatal(err) } // Start server ctx := context.Background() if err := srv.Start(ctx); err != nil { log.Fatal(err) } } ``` ### Custom Multi-Lens Camera ```go package main import ( "context" "log" "time" "github.com/0x524a/onvif-go/server" ) func main() { config := &server.Config{ Host: "0.0.0.0", Port: 8080, BasePath: "/onvif", Timeout: 30 * time.Second, DeviceInfo: server.DeviceInfo{ Manufacturer: "MultiCam Systems", Model: "MC-3000 Pro", FirmwareVersion: "2.5.1", SerialNumber: "MC3000-001234", HardwareID: "HW-MC3000", }, Username: "admin", Password: "SecurePass123", SupportPTZ: true, SupportImaging: true, SupportEvents: false, Profiles: []server.ProfileConfig{ { Token: "profile_main_4k", Name: "Main Camera 4K", VideoSource: server.VideoSourceConfig{ Token: "video_source_main", Name: "Main Camera", Resolution: server.Resolution{Width: 3840, Height: 2160}, Framerate: 30, }, VideoEncoder: server.VideoEncoderConfig{ Encoding: "H264", Resolution: server.Resolution{Width: 3840, Height: 2160}, Quality: 90, Framerate: 30, Bitrate: 20480, // 20 Mbps GovLength: 30, }, PTZ: &server.PTZConfig{ NodeToken: "ptz_main", PanRange: server.Range{Min: -180, Max: 180}, TiltRange: server.Range{Min: -90, Max: 90}, ZoomRange: server.Range{Min: 0, Max: 10}, SupportsContinuous: true, SupportsAbsolute: true, SupportsRelative: true, Presets: []server.Preset{ {Token: "preset_home", Name: "Home", Position: server.PTZPosition{Pan: 0, Tilt: 0, Zoom: 0}}, {Token: "preset_entrance", Name: "Entrance", Position: server.PTZPosition{Pan: -45, Tilt: -20, Zoom: 3}}, }, }, Snapshot: server.SnapshotConfig{ Enabled: true, Resolution: server.Resolution{Width: 3840, Height: 2160}, Quality: 95, }, }, // Add more profiles... }, } srv, err := server.New(config) if err != nil { log.Fatal(err) } ctx := context.Background() if err := srv.Start(ctx); err != nil { log.Fatal(err) } } ``` ## Testing with ONVIF Client You can test the server with the included ONVIF client library: ```go package main import ( "context" "fmt" "log" "time" "github.com/0x524a/onvif-go" ) func main() { // Connect to the server client, err := onvif.NewClient( "http://localhost:8080/onvif/device_service", onvif.WithCredentials("admin", "admin"), onvif.WithTimeout(30*time.Second), ) if err != nil { log.Fatal(err) } ctx := context.Background() // Get device information info, err := client.GetDeviceInformation(ctx) if err != nil { log.Fatal(err) } fmt.Printf("Device: %s %s\n", info.Manufacturer, info.Model) // Initialize to discover services if err := client.Initialize(ctx); err != nil { log.Fatal(err) } // Get media profiles profiles, err := client.GetProfiles(ctx) if err != nil { log.Fatal(err) } fmt.Printf("Found %d profiles:\n", len(profiles)) for i, profile := range profiles { fmt.Printf(" [%d] %s\n", i+1, profile.Name) // Get stream URI streamURI, err := client.GetStreamURI(ctx, profile.Token) if err != nil { log.Fatal(err) } fmt.Printf(" Stream: %s\n", streamURI.URI) } // PTZ control (if available) if len(profiles) > 0 && profiles[0].PTZConfiguration != nil { profileToken := profiles[0].Token // Get PTZ status status, err := client.GetStatus(ctx, profileToken) if err != nil { log.Fatal(err) } fmt.Printf("PTZ Position: Pan=%.2f, Tilt=%.2f, Zoom=%.2f\n", status.Position.PanTilt.X, status.Position.PanTilt.Y, status.Position.Zoom.X) // Move to home position position := &onvif.PTZVector{ PanTilt: &onvif.Vector2D{X: 0.0, Y: 0.0}, Zoom: &onvif.Vector1D{X: 0.0}, } if err := client.AbsoluteMove(ctx, profileToken, position, nil); err != nil { log.Fatal(err) } fmt.Println("Moved to home position") } } ``` ## Examples See the [examples/onvif-server](../../examples/onvif-server) directory for a complete multi-lens camera configuration example. ```bash # Run the example cd examples/onvif-server go run main.go ``` This example demonstrates: - 4 different camera profiles (4K main, wide-angle, telephoto, low-light) - PTZ control with multiple presets - Different resolutions and framerates - Custom device information ## Use Cases ### ๐Ÿงช Testing & Development - Test ONVIF client implementations - Simulate multi-camera setups - Develop video management systems - Integration testing without physical cameras ### ๐Ÿ“š Learning & Education - Understand ONVIF protocol - Learn SOAP web services - Study IP camera architectures - Prototype camera systems ### ๐ŸŽญ Demonstrations - Demo video surveillance solutions - Showcase camera management software - Present multi-camera scenarios - Trade show demonstrations ### ๐Ÿ”ฌ Research & Prototyping - Computer vision research - Video analytics development - Stream processing pipelines - AI/ML model training ## Architecture The server is built with a modular architecture: ``` server/ โ”œโ”€โ”€ types.go # Core data types and configuration โ”œโ”€โ”€ server.go # Main server implementation โ”œโ”€โ”€ device.go # Device service handlers โ”œโ”€โ”€ media.go # Media service handlers โ”œโ”€โ”€ ptz.go # PTZ service handlers โ”œโ”€โ”€ imaging.go # Imaging service handlers โ””โ”€โ”€ soap/ โ””โ”€โ”€ handler.go # SOAP message handling ``` ### Key Components 1. **Server Core**: HTTP server, request routing, lifecycle management 2. **SOAP Handler**: SOAP message parsing, authentication, response formatting 3. **Service Handlers**: Device, Media, PTZ, Imaging service implementations 4. **State Management**: PTZ positions, imaging settings, stream configurations ## RTSP Streaming The server provides RTSP URIs for each profile: ``` rtsp://localhost:8554/stream0 # Profile 0 rtsp://localhost:8554/stream1 # Profile 1 rtsp://localhost:8554/stream2 # Profile 2 ... ``` **Note**: The current implementation returns RTSP URIs but does not include an actual RTSP server. To provide real video streams, integrate with: - [RTSPtoWeb](https://github.com/deepch/RTSPtoWeb) - [MediaMTX](https://github.com/bluenviron/mediamtx) - [FFmpeg RTSP server](https://ffmpeg.org/) - Custom RTSP implementation ## Roadmap - [ ] **Events Service**: Event subscription and notification - [ ] **Recording Service**: Recording management - [ ] **Analytics Service**: Video analytics support - [ ] **Actual RTSP Streaming**: Integrated RTSP server with test patterns - [ ] **Web UI**: Browser-based configuration and monitoring - [ ] **Docker Support**: Containerized deployment - [ ] **Configuration Files**: YAML/JSON configuration support - [ ] **WS-Discovery**: Automatic device discovery on network - [ ] **TLS Support**: HTTPS and secure RTSP - [ ] **Audio Support**: Audio streaming and configuration ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## License This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details. ## Acknowledgments - Built on top of the [onvif-go](https://github.com/0x524a/onvif-go) client library - ONVIF specifications from [ONVIF.org](https://www.onvif.org) - Inspired by the need for flexible camera simulation in development workflows --- **Note**: This is a virtual camera server for testing and development. It simulates ONVIF protocol responses but does not capture or stream real video unless integrated with an RTSP server.