chore: update golangci-lint configuration and improve CI workflow documentation
- Increased thresholds for funlen and lll linters to accommodate complex functions. - Added exclusions for dupl linter in specific files and directories to reduce false positives. - Updated CI workflow documentation to clarify triggers and requirements for SonarCloud analysis. - Removed unnecessary linter directives in several files for improved readability.
This commit is contained in:
@@ -21,7 +21,7 @@ fmt → lint → test → sonarcloud
|
|||||||
| **fmt** | Format check using `gofmt -s` | - |
|
| **fmt** | Format check using `gofmt -s` | - |
|
||||||
| **lint** | Static analysis with `go vet` and `golangci-lint` | fmt |
|
| **lint** | Static analysis with `go vet` and `golangci-lint` | fmt |
|
||||||
| **test** | Unit tests with race detector + coverage | lint |
|
| **test** | Unit tests with race detector + coverage | lint |
|
||||||
| **sonarcloud** | Code quality & security analysis | test |
|
| **sonarcloud** | Code quality & security analysis (push to master only) | test |
|
||||||
| **build** | Build verification for all packages | test |
|
| **build** | Build verification for all packages | test |
|
||||||
| **ci-success** | Final status check | all |
|
| **ci-success** | Final status check | all |
|
||||||
|
|
||||||
@@ -33,8 +33,21 @@ fmt → lint → test → sonarcloud
|
|||||||
- ✅ Concurrency control (cancels in-progress runs)
|
- ✅ Concurrency control (cancels in-progress runs)
|
||||||
|
|
||||||
**Triggers:**
|
**Triggers:**
|
||||||
- Push to `master`, `main`, `develop`
|
- Push to `master`, `main`
|
||||||
- Pull requests to `master`, `main`, `develop`
|
- All pull requests targeting `master`, `main`
|
||||||
|
|
||||||
|
**Required for PR Merge:**
|
||||||
|
All stages must pass before a PR can be merged. Configure branch protection rules in GitHub:
|
||||||
|
1. Go to **Settings → Branches → Branch protection rules**
|
||||||
|
2. Add rule for `master`
|
||||||
|
3. Enable **Require status checks to pass before merging**
|
||||||
|
4. Select these required checks:
|
||||||
|
- `Format Check`
|
||||||
|
- `Lint`
|
||||||
|
- `Test & Coverage`
|
||||||
|
- `SonarCloud Analysis`
|
||||||
|
- `Build Verification`
|
||||||
|
- `CI Success`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -113,7 +126,8 @@ Dependency vulnerability review.
|
|||||||
│ ▼ ▼ │
|
│ ▼ ▼ │
|
||||||
│ ┌────────────┐ ┌───────────┐ │
|
│ ┌────────────┐ ┌───────────┐ │
|
||||||
│ │ SONARCLOUD │ │ BUILD │ │
|
│ │ SONARCLOUD │ │ BUILD │ │
|
||||||
│ └────────────┘ └───────────┘ │
|
│ │ (push only)│ └───────────┘ │
|
||||||
|
│ └────────────┘ │ │
|
||||||
│ │ │ │
|
│ │ │ │
|
||||||
│ └─────────┬─────────┘ │
|
│ └─────────┬─────────┘ │
|
||||||
│ ▼ │
|
│ ▼ │
|
||||||
@@ -124,6 +138,7 @@ Dependency vulnerability review.
|
|||||||
└─────────────────────────────────────────────────────────────────┘
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
❌ If any stage fails, the pipeline stops immediately (fail-fast)
|
❌ If any stage fails, the pipeline stops immediately (fail-fast)
|
||||||
|
ℹ️ SonarCloud only runs on push to master/main (skipped for PRs)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ name: CI
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [master, main, develop]
|
branches: [master, main]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [master, main, develop]
|
branches: [master, main]
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
@@ -12,7 +13,7 @@ permissions:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -138,14 +139,18 @@ jobs:
|
|||||||
files: ./coverage.out
|
files: ./coverage.out
|
||||||
flags: unittests
|
flags: unittests
|
||||||
name: codecov-onvif-go
|
name: codecov-onvif-go
|
||||||
fail_ci_if_error: true
|
# Don't fail on PRs from forks where token may not be available
|
||||||
|
fail_ci_if_error: ${{ github.event_name == 'push' }}
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
||||||
# Stage 4: SonarCloud Analysis (depends on test)
|
# Stage 4: SonarCloud Analysis (depends on test)
|
||||||
|
# Only runs on push to master/main when SONAR_TOKEN is available
|
||||||
|
# Skipped for PRs from forks where secrets are not accessible
|
||||||
sonarcloud:
|
sonarcloud:
|
||||||
name: SonarCloud Analysis
|
name: SonarCloud Analysis
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: test
|
needs: test
|
||||||
|
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main') && github.repository == '0x524a/onvif-go'
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -235,10 +240,14 @@ jobs:
|
|||||||
echo "❌ Tests failed"
|
echo "❌ Tests failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
if [[ "${{ needs.sonarcloud.result }}" != "success" ]]; then
|
# SonarCloud is optional - only fails if it ran and failed (not if skipped)
|
||||||
|
if [[ "${{ needs.sonarcloud.result }}" == "failure" ]]; then
|
||||||
echo "❌ SonarCloud analysis failed"
|
echo "❌ SonarCloud analysis failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ "${{ needs.sonarcloud.result }}" == "skipped" ]]; then
|
||||||
|
echo "ℹ️ SonarCloud analysis skipped (only runs on push to master/main)"
|
||||||
|
fi
|
||||||
if [[ "${{ needs.build.result }}" != "success" ]]; then
|
if [[ "${{ needs.build.result }}" != "success" ]]; then
|
||||||
echo "❌ Build verification failed"
|
echo "❌ Build verification failed"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
+14
-3
@@ -53,11 +53,11 @@ linters-settings:
|
|||||||
min-complexity: 15
|
min-complexity: 15
|
||||||
|
|
||||||
funlen:
|
funlen:
|
||||||
lines: 100
|
lines: 120
|
||||||
statements: 50
|
statements: 60
|
||||||
|
|
||||||
lll:
|
lll:
|
||||||
line-length: 120
|
line-length: 150
|
||||||
|
|
||||||
gocritic:
|
gocritic:
|
||||||
enabled-tags:
|
enabled-tags:
|
||||||
@@ -99,6 +99,7 @@ issues:
|
|||||||
- funlen
|
- funlen
|
||||||
- gocyclo
|
- gocyclo
|
||||||
- gocognit
|
- gocognit
|
||||||
|
- dupl
|
||||||
|
|
||||||
# Exclude known false positives
|
# Exclude known false positives
|
||||||
- text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|.*Write|.*Read|.*Printf?|.*Fprintf?) is not checked"
|
- text: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|.*Write|.*Read|.*Printf?|.*Fprintf?) is not checked"
|
||||||
@@ -109,6 +110,16 @@ issues:
|
|||||||
- path: _test\.go
|
- path: _test\.go
|
||||||
linters:
|
linters:
|
||||||
- lll
|
- lll
|
||||||
|
|
||||||
|
# Exclude dupl from ONVIF API files - similar patterns are expected
|
||||||
|
- path: (media|device|ptz|imaging|device_security|device_additional)\.go
|
||||||
|
linters:
|
||||||
|
- dupl
|
||||||
|
|
||||||
|
# Exclude dupl from cmd directories
|
||||||
|
- path: cmd/
|
||||||
|
linters:
|
||||||
|
- dupl
|
||||||
|
|
||||||
max-issues-per-linter: 50
|
max-issues-per-linter: 50
|
||||||
max-same-issues: 10
|
max-same-issues: 10
|
||||||
|
|||||||
@@ -135,7 +135,6 @@ type AdditionalTest struct {
|
|||||||
Code string
|
Code string
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:funlen // Main function has many statements due to test generation logic
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func ImageToASCII(imageData []byte, config ASCIIConfig) (string, error) {
|
|||||||
|
|
||||||
// imageToASCIIFromImage is the core conversion function.
|
// imageToASCIIFromImage is the core conversion function.
|
||||||
//
|
//
|
||||||
//nolint:gocyclo,lll // Image to ASCII conversion has high complexity due to multiple pixel processing paths
|
//nolint:gocyclo // Image to ASCII conversion has high complexity due to multiple pixel processing paths
|
||||||
func imageToASCIIFromImage(img image.Image, config ASCIIConfig, format string) (string, error) { //nolint:unparam // format reserved for future use
|
func imageToASCIIFromImage(img image.Image, config ASCIIConfig, format string) (string, error) { //nolint:unparam // format reserved for future use
|
||||||
// Validate configuration
|
// Validate configuration
|
||||||
if config.Width <= 0 {
|
if config.Width <= 0 {
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ const (
|
|||||||
ptzSpeed = 0.5
|
ptzSpeed = 0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:funlen // Main function has many statements due to server setup and configuration
|
|
||||||
func main() {
|
func main() {
|
||||||
// Define command-line flags
|
// Define command-line flags
|
||||||
host := flag.String("host", "0.0.0.0", "Server host address")
|
host := flag.String("host", "0.0.0.0", "Server host address")
|
||||||
@@ -39,7 +38,7 @@ func main() {
|
|||||||
firmware := flag.String("firmware", "1.0.0", "Firmware version")
|
firmware := flag.String("firmware", "1.0.0", "Firmware version")
|
||||||
serial := flag.String("serial", "SN-12345678", "Serial number")
|
serial := flag.String("serial", "SN-12345678", "Serial number")
|
||||||
profiles := flag.Int(
|
profiles := flag.Int(
|
||||||
"profiles", maxWorkers, "Number of camera profiles (1-10)", //nolint:mnd // Default profile count is reasonable
|
"profiles", maxWorkers, "Number of camera profiles (1-10)",
|
||||||
)
|
)
|
||||||
ptz := flag.Bool("ptz", true, "Enable PTZ support")
|
ptz := flag.Bool("ptz", true, "Enable PTZ support")
|
||||||
imaging := flag.Bool("imaging", true, "Enable Imaging support")
|
imaging := flag.Bool("imaging", true, "Enable Imaging support")
|
||||||
@@ -217,7 +216,7 @@ func buildConfig(host string, port int, username, password, manufacturer, model,
|
|||||||
Token: fmt.Sprintf("preset_%d_1", i),
|
Token: fmt.Sprintf("preset_%d_1", i),
|
||||||
Name: "Entrance",
|
Name: "Entrance",
|
||||||
Position: server.PTZPosition{
|
Position: server.PTZPosition{
|
||||||
Pan: -45, Tilt: -10, Zoom: template.ptzZoomMax * ptzSpeed, //nolint:mnd // Preset position values
|
Pan: -45, Tilt: -10, Zoom: template.ptzZoomMax * ptzSpeed,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-6
@@ -142,9 +142,7 @@ func (c *Client) GetIPAddressFilter(ctx context.Context) (*IPAddressFilter, erro
|
|||||||
return filter, nil
|
return filter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetIPAddressFilter sets the IP address filter settings on a device
|
// SetIPAddressFilter sets the IP address filter settings on a device.
|
||||||
//
|
|
||||||
//nolint:dupl // Similar structure to AddIPAddressFilter but different operation
|
|
||||||
func (c *Client) SetIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
func (c *Client) SetIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
||||||
type SetIPAddressFilter struct {
|
type SetIPAddressFilter struct {
|
||||||
XMLName xml.Name `xml:"tds:SetIPAddressFilter"`
|
XMLName xml.Name `xml:"tds:SetIPAddressFilter"`
|
||||||
@@ -197,9 +195,7 @@ func (c *Client) SetIPAddressFilter(ctx context.Context, filter *IPAddressFilter
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddIPAddressFilter adds an IP filter address to a device
|
// AddIPAddressFilter adds an IP filter address to a device.
|
||||||
//
|
|
||||||
//nolint:dupl // Similar structure to SetIPAddressFilter but different operation
|
|
||||||
func (c *Client) AddIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
func (c *Client) AddIPAddressFilter(ctx context.Context, filter *IPAddressFilter) error {
|
||||||
type AddIPAddressFilter struct {
|
type AddIPAddressFilter struct {
|
||||||
XMLName xml.Name `xml:"tds:AddIPAddressFilter"`
|
XMLName xml.Name `xml:"tds:AddIPAddressFilter"`
|
||||||
|
|||||||
@@ -2491,8 +2491,6 @@ func (c *Client) GetAudioSourceConfigurations(ctx context.Context) ([]*AudioSour
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetVideoEncoderConfigurations retrieves all video encoder configurations.
|
// GetVideoEncoderConfigurations retrieves all video encoder configurations.
|
||||||
//
|
|
||||||
//nolint:funlen // GetVideoEncoderConfigurations has many statements due to parsing complex encoder configurations
|
|
||||||
func (c *Client) GetVideoEncoderConfigurations(ctx context.Context) ([]*VideoEncoderConfiguration, error) {
|
func (c *Client) GetVideoEncoderConfigurations(ctx context.Context) ([]*VideoEncoderConfiguration, error) {
|
||||||
endpoint := c.mediaEndpoint
|
endpoint := c.mediaEndpoint
|
||||||
if endpoint == "" {
|
if endpoint == "" {
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ func TestHandleGetOptions(t *testing.T) {
|
|||||||
|
|
||||||
// TestHandleMove - DISABLED due to SOAP namespace requirements.
|
// TestHandleMove - DISABLED due to SOAP namespace requirements.
|
||||||
//
|
//
|
||||||
//nolint:unused,thelper // Disabled test function kept for reference
|
//nolint:unused // Disabled test function kept for reference
|
||||||
func _DisabledTestHandleMove(t *testing.T) {
|
func _DisabledTestHandleMove(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := createTestConfig()
|
config := createTestConfig()
|
||||||
|
|||||||
+9
-12
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
// These handlers are better tested through the SOAP handler in integration tests.
|
// These handlers are better tested through the SOAP handler in integration tests.
|
||||||
//
|
//
|
||||||
//nolint:unused,thelper // Disabled test function kept for reference
|
//nolint:unused // Disabled test function kept for reference
|
||||||
func _DisabledTestHandleGetPresets(t *testing.T) {
|
func _DisabledTestHandleGetPresets(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := createTestConfig()
|
config := createTestConfig()
|
||||||
@@ -79,7 +79,7 @@ func TestHandleGotoPreset(t *testing.T) {
|
|||||||
|
|
||||||
// TestHandleGetStatus - DISABLED due to SOAP namespace requirements.
|
// TestHandleGetStatus - DISABLED due to SOAP namespace requirements.
|
||||||
//
|
//
|
||||||
//nolint:unused,thelper // Disabled test function kept for reference
|
//nolint:unused // Disabled test function kept for reference
|
||||||
func _DisabledTestHandleGetStatus(t *testing.T) {
|
func _DisabledTestHandleGetStatus(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := createTestConfig()
|
config := createTestConfig()
|
||||||
@@ -115,10 +115,9 @@ func _DisabledTestHandleGetStatus(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestHandleAbsoluteMove - DISABLED due to SOAP namespace requirements
|
// TestHandleAbsoluteMove - DISABLED due to SOAP namespace requirements.
|
||||||
//
|
//
|
||||||
//nolint:dupl // Disabled test functions have similar structure
|
//nolint:unused // Disabled test function kept for reference
|
||||||
//nolint:unused,thelper // Disabled test function kept for reference
|
|
||||||
func _DisabledTestHandleAbsoluteMove(t *testing.T) {
|
func _DisabledTestHandleAbsoluteMove(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := createTestConfig()
|
config := createTestConfig()
|
||||||
@@ -159,10 +158,9 @@ func _DisabledTestHandleAbsoluteMove(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestHandleRelativeMove - DISABLED due to SOAP namespace requirements
|
// TestHandleRelativeMove - DISABLED due to SOAP namespace requirements.
|
||||||
//
|
//
|
||||||
//nolint:dupl // Disabled test functions have similar structure
|
//nolint:unused // Disabled test function kept for reference
|
||||||
//nolint:unused,thelper // Disabled test function kept for reference
|
|
||||||
func _DisabledTestHandleRelativeMove(t *testing.T) {
|
func _DisabledTestHandleRelativeMove(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := createTestConfig()
|
config := createTestConfig()
|
||||||
@@ -203,10 +201,9 @@ func _DisabledTestHandleRelativeMove(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestHandleContinuousMove - DISABLED due to SOAP namespace requirements
|
// TestHandleContinuousMove - DISABLED due to SOAP namespace requirements.
|
||||||
//
|
//
|
||||||
//nolint:dupl // Disabled test functions have similar structure
|
//nolint:unused // Disabled test function kept for reference
|
||||||
//nolint:unused,thelper // Disabled test function kept for reference
|
|
||||||
func _DisabledTestHandleContinuousMove(t *testing.T) {
|
func _DisabledTestHandleContinuousMove(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := createTestConfig()
|
config := createTestConfig()
|
||||||
@@ -249,7 +246,7 @@ func _DisabledTestHandleContinuousMove(t *testing.T) {
|
|||||||
|
|
||||||
// TestHandleStop - DISABLED due to SOAP namespace requirements.
|
// TestHandleStop - DISABLED due to SOAP namespace requirements.
|
||||||
//
|
//
|
||||||
//nolint:unused,thelper // Disabled test function kept for reference
|
//nolint:unused // Disabled test function kept for reference
|
||||||
func _DisabledTestHandleStop(t *testing.T) {
|
func _DisabledTestHandleStop(t *testing.T) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
config := createTestConfig()
|
config := createTestConfig()
|
||||||
|
|||||||
+32
-29
@@ -8,6 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
defaultPort = 8080
|
||||||
defaultTimeoutSec = 30
|
defaultTimeoutSec = 30
|
||||||
defaultWidth = 1920
|
defaultWidth = 1920
|
||||||
defaultHeight = 1080
|
defaultHeight = 1080
|
||||||
@@ -250,10 +251,12 @@ type WDRSettings struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DefaultConfig returns a default server configuration with a multi-lens camera setup.
|
// DefaultConfig returns a default server configuration with a multi-lens camera setup.
|
||||||
func DefaultConfig() *Config { //nolint:funlen // DefaultConfig has many statements due to comprehensive default configuration
|
//
|
||||||
|
//nolint:funlen // DefaultConfig has many statements due to comprehensive default configuration
|
||||||
|
func DefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Host: "0.0.0.0",
|
Host: "0.0.0.0",
|
||||||
Port: 8080, //nolint:mnd // Default HTTP port
|
Port: defaultPort,
|
||||||
BasePath: "/onvif",
|
BasePath: "/onvif",
|
||||||
Timeout: defaultTimeoutSec * time.Second,
|
Timeout: defaultTimeoutSec * time.Second,
|
||||||
DeviceInfo: DeviceInfo{
|
DeviceInfo: DeviceInfo{
|
||||||
@@ -302,14 +305,14 @@ func DefaultConfig() *Config { //nolint:funlen // DefaultConfig has many stateme
|
|||||||
{Token: "preset_0", Name: "Home", Position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 0}},
|
{Token: "preset_0", Name: "Home", Position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 0}},
|
||||||
{
|
{
|
||||||
Token: "preset_1", Name: "Entrance",
|
Token: "preset_1", Name: "Entrance",
|
||||||
Position: PTZPosition{Pan: -45, Tilt: -10, Zoom: defaultPTZSpeed}, //nolint:mnd // Preset position
|
Position: PTZPosition{Pan: -45, Tilt: -10, Zoom: defaultPTZSpeed},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Snapshot: SnapshotConfig{
|
Snapshot: SnapshotConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight}, //nolint:mnd // Default resolution
|
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight},
|
||||||
Quality: highQuality, //nolint:mnd // High quality
|
Quality: highQuality,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -318,22 +321,22 @@ func DefaultConfig() *Config { //nolint:funlen // DefaultConfig has many stateme
|
|||||||
VideoSource: VideoSourceConfig{
|
VideoSource: VideoSourceConfig{
|
||||||
Token: "video_source_1",
|
Token: "video_source_1",
|
||||||
Name: "Wide Angle Camera",
|
Name: "Wide Angle Camera",
|
||||||
Resolution: Resolution{Width: mediumWidth, Height: mediumHeight}, //nolint:mnd // Medium resolution
|
Resolution: Resolution{Width: mediumWidth, Height: mediumHeight},
|
||||||
Framerate: defaultFramerate, //nolint:mnd // Default framerate
|
Framerate: defaultFramerate,
|
||||||
Bounds: Bounds{X: 0, Y: 0, Width: mediumWidth, Height: mediumHeight}, //nolint:mnd // Medium bounds
|
Bounds: Bounds{X: 0, Y: 0, Width: mediumWidth, Height: mediumHeight},
|
||||||
},
|
},
|
||||||
VideoEncoder: VideoEncoderConfig{
|
VideoEncoder: VideoEncoderConfig{
|
||||||
Encoding: "H264",
|
Encoding: "H264",
|
||||||
Resolution: Resolution{Width: mediumWidth, Height: mediumHeight}, //nolint:mnd // Medium resolution
|
Resolution: Resolution{Width: mediumWidth, Height: mediumHeight},
|
||||||
Quality: mediumQuality, //nolint:mnd // Medium quality
|
Quality: mediumQuality,
|
||||||
Framerate: defaultFramerate, //nolint:mnd // Default framerate
|
Framerate: defaultFramerate,
|
||||||
Bitrate: mediumBitrate, //nolint:mnd // Medium bitrate
|
Bitrate: mediumBitrate,
|
||||||
GovLength: defaultFramerate, //nolint:mnd // Default gov length
|
GovLength: defaultFramerate,
|
||||||
},
|
},
|
||||||
Snapshot: SnapshotConfig{
|
Snapshot: SnapshotConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Resolution: Resolution{Width: mediumWidth, Height: mediumHeight}, //nolint:mnd // Medium resolution
|
Resolution: Resolution{Width: mediumWidth, Height: mediumHeight},
|
||||||
Quality: defaultQuality, //nolint:mnd // Default quality
|
Quality: defaultQuality,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -342,25 +345,25 @@ func DefaultConfig() *Config { //nolint:funlen // DefaultConfig has many stateme
|
|||||||
VideoSource: VideoSourceConfig{
|
VideoSource: VideoSourceConfig{
|
||||||
Token: "video_source_2",
|
Token: "video_source_2",
|
||||||
Name: "Telephoto Camera",
|
Name: "Telephoto Camera",
|
||||||
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight}, //nolint:mnd // Default resolution
|
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight},
|
||||||
Framerate: lowFramerate, //nolint:mnd // Low framerate
|
Framerate: lowFramerate,
|
||||||
Bounds: Bounds{X: 0, Y: 0, Width: defaultWidth, Height: defaultHeight}, //nolint:mnd // Default bounds
|
Bounds: Bounds{X: 0, Y: 0, Width: defaultWidth, Height: defaultHeight},
|
||||||
},
|
},
|
||||||
VideoEncoder: VideoEncoderConfig{
|
VideoEncoder: VideoEncoderConfig{
|
||||||
Encoding: "H264",
|
Encoding: "H264",
|
||||||
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight}, //nolint:mnd // Default resolution
|
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight},
|
||||||
Quality: highQuality, //nolint:mnd // High quality
|
Quality: highQuality,
|
||||||
Framerate: lowFramerate, //nolint:mnd // Low framerate
|
Framerate: lowFramerate,
|
||||||
Bitrate: highBitrate, //nolint:mnd // High bitrate
|
Bitrate: highBitrate,
|
||||||
GovLength: lowFramerate, //nolint:mnd // Low framerate
|
GovLength: lowFramerate,
|
||||||
},
|
},
|
||||||
PTZ: &PTZConfig{
|
PTZ: &PTZConfig{
|
||||||
NodeToken: "ptz_node_2",
|
NodeToken: "ptz_node_2",
|
||||||
PanRange: Range{Min: -maxPan, Max: maxPan},
|
PanRange: Range{Min: -maxPan, Max: maxPan},
|
||||||
TiltRange: Range{Min: -maxTilt, Max: maxTilt},
|
TiltRange: Range{Min: -maxTilt, Max: maxTilt},
|
||||||
ZoomRange: Range{Min: 0, Max: maxZoom}, //nolint:mnd // Max zoom
|
ZoomRange: Range{Min: 0, Max: maxZoom},
|
||||||
DefaultSpeed: PTZSpeed{
|
DefaultSpeed: PTZSpeed{
|
||||||
Pan: lowPTZSpeed, Tilt: lowPTZSpeed, Zoom: lowPTZSpeed, //nolint:mnd // Low PTZ speed
|
Pan: lowPTZSpeed, Tilt: lowPTZSpeed, Zoom: lowPTZSpeed,
|
||||||
},
|
},
|
||||||
SupportsContinuous: true,
|
SupportsContinuous: true,
|
||||||
SupportsAbsolute: true,
|
SupportsAbsolute: true,
|
||||||
@@ -369,14 +372,14 @@ func DefaultConfig() *Config { //nolint:funlen // DefaultConfig has many stateme
|
|||||||
{Token: "preset_2_0", Name: "Home", Position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 0}},
|
{Token: "preset_2_0", Name: "Home", Position: PTZPosition{Pan: 0, Tilt: 0, Zoom: 0}},
|
||||||
{
|
{
|
||||||
Token: "preset_2_1", Name: "Zoom In",
|
Token: "preset_2_1", Name: "Zoom In",
|
||||||
Position: PTZPosition{Pan: 0, Tilt: 0, Zoom: presetZoom}, //nolint:mnd // Preset zoom
|
Position: PTZPosition{Pan: 0, Tilt: 0, Zoom: presetZoom},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Snapshot: SnapshotConfig{
|
Snapshot: SnapshotConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight}, //nolint:mnd // Default resolution
|
Resolution: Resolution{Width: defaultWidth, Height: defaultHeight},
|
||||||
Quality: highQuality, //nolint:mnd // High quality
|
Quality: highQuality,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -393,7 +396,7 @@ func (c *Config) ServiceEndpoints(host string) map[string]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var baseURL string
|
var baseURL string
|
||||||
const httpPort = 80 //nolint:mnd // Standard HTTP port
|
const httpPort = 80
|
||||||
if c.Port == httpPort {
|
if c.Port == httpPort {
|
||||||
baseURL = "http://" + host + c.BasePath
|
baseURL = "http://" + host + c.BasePath
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user