Add onvif name and hardware in info field of onvif discovery

This commit is contained in:
Davide Figini
2025-12-19 15:08:23 +01:00
parent 753d6617ab
commit bbb9466845
2 changed files with 42 additions and 10 deletions
+12 -6
View File
@@ -7,6 +7,7 @@ import (
"net/url"
"os"
"strconv"
"strings"
"time"
"github.com/AlexxIT/go2rtc/internal/api"
@@ -160,21 +161,21 @@ func apiOnvif(w http.ResponseWriter, r *http.Request) {
var items []*api.Source
if src == "" {
urls, err := onvif.DiscoveryStreamingURLs()
devices, err := onvif.DiscoveryStreamingDevices()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, rawURL := range urls {
u, err := url.Parse(rawURL)
for _, device := range devices {
u, err := url.Parse(device.URL)
if err != nil {
log.Warn().Str("url", rawURL).Msg("[onvif] broken")
log.Warn().Str("url", device.URL).Msg("[onvif] broken")
continue
}
if u.Scheme != "http" {
log.Warn().Str("url", rawURL).Msg("[onvif] unsupported")
log.Warn().Str("url", device.URL).Msg("[onvif] unsupported")
continue
}
@@ -185,7 +186,12 @@ func apiOnvif(w http.ResponseWriter, r *http.Request) {
u.Path = ""
}
items = append(items, &api.Source{Name: u.Host, URL: u.String()})
var info string
info = strings.TrimSpace(device.Name + " " + device.Hardware)
if info == "" {
info = "ONVIF Device"
}
items = append(items, &api.Source{Name: u.Host, URL: u.String(), Info: info})
}
} else {
client, err := onvif.NewClient(src)
+30 -4
View File
@@ -12,6 +12,12 @@ import (
"github.com/AlexxIT/go2rtc/pkg/core"
)
type DiscoveryDevice struct {
URL string
Name string
Hardware string
}
func FindTagValue(b []byte, tag string) string {
re := regexp.MustCompile(`(?s)<(?:\w+:)?` + tag + `\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:]
}
func DiscoveryStreamingURLs() ([]string, error) {
// return list of tuple (onvif_url, name, hardware)
func DiscoveryStreamingDevices() ([]DiscoveryDevice, error) {
conn, err := net.ListenUDP("udp4", nil)
if err != nil {
return nil, err
@@ -65,7 +72,7 @@ func DiscoveryStreamingURLs() ([]string, error) {
return nil, err
}
var urls []string
var devices []DiscoveryDevice
b := make([]byte, 8192)
for {
@@ -92,10 +99,29 @@ func DiscoveryStreamingURLs() ([]string, error) {
url = "http://" + addr.IP.String() + url[14:]
}
urls = append(urls, url)
// try to find the camera name and model (hardware)
scopes := FindTagValue(b[:n], "Scopes")
var name, hardware string
for _, scope := range strings.Split(scopes, " ") {
if strings.HasPrefix(scope, "onvif://www.onvif.org/name/") {
name = strings.TrimPrefix(scope, "onvif://www.onvif.org/name/")
} else if strings.HasPrefix(scope, "onvif://www.onvif.org/hardware/") {
hardware = strings.TrimPrefix(scope, "onvif://www.onvif.org/hardware/")
}
}
// Some cameras has the hardware copied into the name field or vice versa
// this is to avoid duplication
if name != "" && hardware != "" {
if strings.Contains(hardware, name) {
name = ""
} else if strings.Contains(name, hardware) {
hardware = ""
}
}
devices = append(devices, DiscoveryDevice{URL: url, Name: name, Hardware: hardware})
}
return urls, nil
return devices, nil
}
func atoi(s string) int {