eadd0d74f7
- CONTRIBUTING.md: Updated title and git clone URL - .github/CONTRIBUTING.md: Updated title, paths, and references - QUICKSTART.md: Updated intro - BUILDING.md: Updated title - docs/ARCHITECTURE.md: Updated title and descriptions - docs/PROJECT_SUMMARY.md: Updated title, description, and structure - docs/IMPLEMENTATION_SUMMARY.md: Updated docker example - server/README.md: Updated cd command and link text - cmd/onvif-diagnostics/README.md: Updated cd command Note: Kept 'go-onvif' as manufacturer identifier in code (server/types.go, cmd/onvif-server/main.go) and in code comments (examples/) for descriptive purposes.
440 lines
12 KiB
Markdown
440 lines
12 KiB
Markdown
# 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 "go-onvif")
|
|
-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.
|