Merge pull request #1991 from FIGIO55/onvif_info

Adding onvif name and hardware in info field of onvif discovery
This commit is contained in:
Alex X
2026-01-18 07:55:20 +03:00
committed by GitHub
2 changed files with 40 additions and 17 deletions
+10 -6
View File
@@ -166,21 +166,21 @@ func apiOnvif(w http.ResponseWriter, r *http.Request) {
var items []*api.Source var items []*api.Source
if src == "" { if src == "" {
urls, err := onvif.DiscoveryStreamingURLs() devices, err := onvif.DiscoveryStreamingDevices()
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
for _, rawURL := range urls { for _, device := range devices {
u, err := url.Parse(rawURL) u, err := url.Parse(device.URL)
if err != nil { if err != nil {
log.Warn().Str("url", rawURL).Msg("[onvif] broken") log.Warn().Str("url", device.URL).Msg("[onvif] broken")
continue continue
} }
if u.Scheme != "http" { if u.Scheme != "http" {
log.Warn().Str("url", rawURL).Msg("[onvif] unsupported") log.Warn().Str("url", device.URL).Msg("[onvif] unsupported")
continue continue
} }
@@ -191,7 +191,11 @@ func apiOnvif(w http.ResponseWriter, r *http.Request) {
u.Path = "" u.Path = ""
} }
items = append(items, &api.Source{Name: u.Host, URL: u.String()}) items = append(items, &api.Source{
Name: u.Host,
URL: u.String(),
Info: device.Name + " " + device.Hardware,
})
} }
} else { } else {
client, err := onvif.NewClient(src) client, err := onvif.NewClient(src)
+30 -11
View File
@@ -12,6 +12,12 @@ import (
"github.com/AlexxIT/go2rtc/pkg/core" "github.com/AlexxIT/go2rtc/pkg/core"
) )
type DiscoveryDevice struct {
URL string
Name string
Hardware string
}
func FindTagValue(b []byte, tag string) string { func FindTagValue(b []byte, tag string) string {
re := regexp.MustCompile(`(?s)<(?:\w+:)?` + tag + `\b[^>]*>([^<]+)`) re := regexp.MustCompile(`(?s)<(?:\w+:)?` + tag + `\b[^>]*>([^<]+)`)
m := re.FindSubmatch(b) m := re.FindSubmatch(b)
@@ -27,7 +33,8 @@ func UUID() string {
return s[:8] + "-" + s[8:12] + "-" + s[12:16] + "-" + s[16:20] + "-" + s[20:] return s[:8] + "-" + s[8:12] + "-" + s[12:16] + "-" + s[16:20] + "-" + s[20:]
} }
func DiscoveryStreamingURLs() ([]string, error) { // DiscoveryStreamingDevices return list of tuple (onvif_url, name, hardware)
func DiscoveryStreamingDevices() ([]DiscoveryDevice, error) {
conn, err := net.ListenUDP("udp4", nil) conn, err := net.ListenUDP("udp4", nil)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -61,11 +68,9 @@ func DiscoveryStreamingURLs() ([]string, error) {
return nil, err return nil, err
} }
if err = conn.SetReadDeadline(time.Now().Add(time.Second * 3)); err != nil { _ = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
return nil, err
}
var urls []string var devices []DiscoveryDevice
b := make([]byte, 8192) b := make([]byte, 8192)
for { for {
@@ -81,21 +86,35 @@ func DiscoveryStreamingURLs() ([]string, error) {
continue continue
} }
url := FindTagValue(b[:n], "XAddrs") device := DiscoveryDevice{
if url == "" { URL: FindTagValue(b[:n], "XAddrs"),
}
if device.URL == "" {
continue continue
} }
// fix some buggy cameras // fix some buggy cameras
// <wsdd:XAddrs>http://0.0.0.0:8080/onvif/device_service</wsdd:XAddrs> // <wsdd:XAddrs>http://0.0.0.0:8080/onvif/device_service</wsdd:XAddrs>
if strings.HasPrefix(url, "http://0.0.0.0") { if s, ok := strings.CutPrefix(device.URL, "http://0.0.0.0"); ok {
url = "http://" + addr.IP.String() + url[14:] device.URL = "http://" + addr.IP.String() + s
} }
urls = append(urls, url) // try to find the camera name and model (hardware)
scopes := FindTagValue(b[:n], "Scopes")
device.Name = findScope(scopes, "onvif://www.onvif.org/name/")
device.Hardware = findScope(scopes, "onvif://www.onvif.org/hardware/")
devices = append(devices, device)
} }
return urls, nil return devices, nil
}
func findScope(s, prefix string) string {
s = core.Between(s, prefix, " ")
s, _ = url.QueryUnescape(s)
return s
} }
func atoi(s string) int { func atoi(s string) int {