diff --git a/examples/onvif_client/README.md b/examples/onvif_client/README.md new file mode 100644 index 00000000..b4ae3383 --- /dev/null +++ b/examples/onvif_client/README.md @@ -0,0 +1,5 @@ +## Example + +```shell +go run examples/onvif_client/main.go http://admin:password@192.168.10.90 GetAudioEncoderConfigurations +``` \ No newline at end of file diff --git a/examples/onvif_client/main.go b/examples/onvif_client/main.go index 03dd12ba..724d3252 100644 --- a/examples/onvif_client/main.go +++ b/examples/onvif_client/main.go @@ -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) } } diff --git a/internal/onvif/onvif.go b/internal/onvif/onvif.go index 0d0319a7..6dfa633a 100644 --- a/internal/onvif/onvif.go +++ b/internal/onvif/onvif.go @@ -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 } diff --git a/pkg/onvif/server.go b/pkg/onvif/server.go index db0bb2fb..54272798 100644 --- a/pkg/onvif/server.go +++ b/pkg/onvif/server.go @@ -179,18 +179,35 @@ func appendProfile(e *Envelope, tag, name string) { `) } +func GetVideoSourceConfigurationsResponse(names []string) []byte { + e := NewEnvelope() + e.Append(` +`) + for _, name := range names { + appendProfile(e, "Configurations", name) + } + e.Append(``) + return e.Bytes() +} + func GetVideoSourceConfigurationResponse(name string) []byte { e := NewEnvelope() e.Append(` - - VSC - `, name, ` - - -`) +`) + appendVideoSourceConfiguration(e, "Configuration", name) + e.Append(``) return e.Bytes() } +func appendVideoSourceConfiguration(e *Envelope, tag, name string) { + e.Append(` + VSC + `, name, ` + + +`) +} + func GetVideoSourcesResponse(names []string) []byte { e := NewEnvelope() e.Append(` @@ -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{ Fixedonvif://www.onvif.org/Profile/Streaming Fixedonvif://www.onvif.org/type/Network_Video_Transmitter `, + + MediaGetVideoEncoderConfigurations: ` + + VEC + H264 + 19201080 + + +`, + + MediaGetAudioEncoderConfigurations: ``, + MediaGetAudioSources: ``, + MediaGetAudioSourceConfigurations: ``, }