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 } } }