Files

86 lines
2.2 KiB
Go

package onvif
import (
"encoding/xml"
"fmt"
"strings"
)
type profileEnvelope struct {
Profiles []struct {
Token string `xml:"token,attr"`
Name string `xml:"Name"`
Encoder struct {
Encoding string `xml:"Encoding"`
Resolution struct {
Width int `xml:"Width"`
Height int `xml:"Height"`
} `xml:"Resolution"`
} `xml:"VideoEncoderConfiguration"`
} `xml:"Body>GetProfilesResponse>Profiles"`
}
func ParseProfiles(data []byte) ([]Profile, error) {
var envelope profileEnvelope
if err := xml.Unmarshal(data, &envelope); err != nil {
return nil, fmt.Errorf("parse ONVIF profiles: %w", err)
}
if len(envelope.Profiles) == 0 {
return nil, fmt.Errorf("no_profiles")
}
result := make([]Profile, 0, len(envelope.Profiles))
for _, value := range envelope.Profiles {
result = append(result, Profile{Token: value.Token, Name: value.Name, Width: value.Encoder.Resolution.Width, Height: value.Encoder.Resolution.Height, Encoding: value.Encoder.Encoding})
}
return result, nil
}
func ParseStreamURI(data []byte) (string, error) {
decoder := xml.NewDecoder(strings.NewReader(string(data)))
for {
token, err := decoder.Token()
if err != nil {
return "", fmt.Errorf("stream_uri_not_found")
}
start, ok := token.(xml.StartElement)
if ok && start.Name.Local == "Uri" {
var value string
if err := decoder.DecodeElement(&value, &start); err != nil {
return "", err
}
if strings.Contains(value, "@") {
return "", fmt.Errorf("stream_uri_contains_credentials")
}
return value, nil
}
}
}
func ParseMediaServiceAddress(data []byte) (string, error) {
decoder := xml.NewDecoder(strings.NewReader(string(data)))
mediaDepth := 0
for {
token, err := decoder.Token()
if err != nil {
return "", fmt.Errorf("media_service_not_found")
}
switch value := token.(type) {
case xml.StartElement:
if value.Name.Local == "Media" {
mediaDepth++
continue
}
if mediaDepth > 0 && value.Name.Local == "XAddr" {
var address string
if err := decoder.DecodeElement(&address, &value); err != nil {
return "", err
}
return strings.TrimSpace(address), nil
}
case xml.EndElement:
if value.Name.Local == "Media" && mediaDepth > 0 {
mediaDepth--
}
}
}
}