Improve ONVIF server #1304

This commit is contained in:
Alex X
2025-03-09 16:26:10 +03:00
parent 944e6f5569
commit b6934922fa
4 changed files with 60 additions and 17 deletions

View File

@@ -0,0 +1,5 @@
## Example
```shell
go run examples/onvif_client/main.go http://admin:password@192.168.10.90 GetAudioEncoderConfigurations
```

View File

@@ -2,7 +2,6 @@ package main
import (
"log"
"net"
"net/url"
"os"
@@ -41,7 +40,13 @@ func main() {
onvif.DeviceGetSystemDateAndTime,
onvif.DeviceSystemReboot:
b, err = client.DeviceRequest(operation)
case onvif.MediaGetProfiles, onvif.MediaGetVideoSources:
case onvif.MediaGetProfiles,
onvif.MediaGetVideoEncoderConfigurations,
onvif.MediaGetVideoSources,
onvif.MediaGetVideoSourceConfigurations,
onvif.MediaGetAudioEncoderConfigurations,
onvif.MediaGetAudioSources,
onvif.MediaGetAudioSourceConfigurations:
b, err = client.MediaRequest(operation)
case onvif.MediaGetProfile:
b, err = client.GetProfile(token)
@@ -64,9 +69,7 @@ func main() {
log.Fatal(err)
}
host, _, _ := net.SplitHostPort(u.Host)
if err = os.WriteFile(host+"_"+operation+".xml", b, 0644); err != nil {
if err = os.WriteFile(u.Hostname()+"_"+operation+".xml", b, 0644); err != nil {
log.Printf("%s\n", err)
}
}

View File

@@ -72,7 +72,11 @@ func onvifDeviceService(w http.ResponseWriter, r *http.Request) {
onvif.DeviceGetNetworkDefaultGateway,
onvif.DeviceGetNetworkProtocols,
onvif.DeviceGetNTP,
onvif.DeviceGetScopes:
onvif.DeviceGetScopes,
onvif.MediaGetVideoEncoderConfigurations,
onvif.MediaGetAudioEncoderConfigurations,
onvif.MediaGetAudioSources,
onvif.MediaGetAudioSourceConfigurations:
b = onvif.StaticResponse(operation)
case onvif.DeviceGetCapabilities:
@@ -109,6 +113,10 @@ func onvifDeviceService(w http.ResponseWriter, r *http.Request) {
token := onvif.FindTagValue(b, "ProfileToken")
b = onvif.GetProfileResponse(token)
case onvif.MediaGetVideoSourceConfigurations:
// important for Happytime Onvif Client
b = onvif.GetVideoSourceConfigurationsResponse(streams.GetAllNames())
case onvif.MediaGetVideoSourceConfiguration:
token := onvif.FindTagValue(b, "ConfigurationToken")
b = onvif.GetVideoSourceConfigurationResponse(token)
@@ -129,6 +137,7 @@ func onvifDeviceService(w http.ResponseWriter, r *http.Request) {
default:
http.Error(w, "unsupported operation", http.StatusBadRequest)
log.Warn().Msgf("[onvif] unsupported operation: %s", operation)
log.Debug().Msgf("[onvif] unsupported request:\n%s", b)
return
}

View File

@@ -179,16 +179,33 @@ func appendProfile(e *Envelope, tag, name string) {
`)
}
func GetVideoSourceConfigurationsResponse(names []string) []byte {
e := NewEnvelope()
e.Append(`<trt:GetVideoSourceConfigurationsResponse>
`)
for _, name := range names {
appendProfile(e, "Configurations", name)
}
e.Append(`</trt:GetVideoSourceConfigurationsResponse>`)
return e.Bytes()
}
func GetVideoSourceConfigurationResponse(name string) []byte {
e := NewEnvelope()
e.Append(`<trt:GetVideoSourceConfigurationResponse>
<trt:Configuration token="`, name, `">
`)
appendVideoSourceConfiguration(e, "Configuration", name)
e.Append(`</trt:GetVideoSourceConfigurationResponse>`)
return e.Bytes()
}
func appendVideoSourceConfiguration(e *Envelope, tag, name string) {
e.Append(`<trt:`, tag, ` token="`, name, `" fixed="true">
<tt:Name>VSC</tt:Name>
<tt:SourceToken>`, name, `</tt:SourceToken>
<tt:Bounds x="0" y="0" width="1920" height="1080"></tt:Bounds>
</trt:Configuration>
</trt:GetVideoSourceConfigurationResponse>`)
return e.Bytes()
</trt:`, tag, `>
`)
}
func GetVideoSourcesResponse(names []string) []byte {
@@ -226,11 +243,7 @@ func StaticResponse(operation string) []byte {
e := NewEnvelope()
e.Append(responses[operation])
b := e.Bytes()
if operation == DeviceGetNetworkInterfaces {
println()
}
return b
return e.Bytes()
}
var responses = map[string]string{
@@ -249,4 +262,17 @@ var responses = map[string]string{
<tds:Scopes><tt:ScopeDef>Fixed</tt:ScopeDef><tt:ScopeItem>onvif://www.onvif.org/Profile/Streaming</tt:ScopeItem></tds:Scopes>
<tds:Scopes><tt:ScopeDef>Fixed</tt:ScopeDef><tt:ScopeItem>onvif://www.onvif.org/type/Network_Video_Transmitter</tt:ScopeItem></tds:Scopes>
</tds:GetScopesResponse>`,
MediaGetVideoEncoderConfigurations: `<trt:GetVideoEncoderConfigurationsResponse>
<tt:VideoEncoderConfiguration token="vec">
<tt:Name>VEC</tt:Name>
<tt:Encoding>H264</tt:Encoding>
<tt:Resolution><tt:Width>1920</tt:Width><tt:Height>1080</tt:Height></tt:Resolution>
<tt:RateControl />
</tt:VideoEncoderConfiguration>
</trt:GetVideoEncoderConfigurationsResponse>`,
MediaGetAudioEncoderConfigurations: `<trt:GetAudioEncoderConfigurationsResponse />`,
MediaGetAudioSources: `<trt:GetAudioSourcesResponse />`,
MediaGetAudioSourceConfigurations: `<trt:GetAudioSourceConfigurationsResponse />`,
}