Add BUBBLE protocol support for XMeye/HiSilicon NVR/DVR cameras

Implemented comprehensive BUBBLE protocol support for Chinese NVR/DVR cameras (ZOSI, SANNCE, ANNKE, FLOUREON, XMeye). This proprietary protocol requires HTTP with embedded credentials and special handling.

Changes:
- Added BUBBLE entries to brand databases with main/sub stream support
- Extended URL placeholder system to support {channel} syntax
- Implemented BUBBLE-specific stream generation with credential embedding
- Added BUBBLE stream detection via Content-Type: video/bubble
- Updated Frigate/Go2RTC generators to convert BUBBLE URLs to bubble:// format
- Added BUBBLE patterns to popular stream database

Technical details:
- BUBBLE uses HTTP protocol with credentials in URL (bubble://user:pass@host:port/path)
- Supports dual streams: stream=0 (main) and stream=1 (sub)
- Requires video=copy parameter for optimal performance in go2rtc
- Detection prioritized before generic HTTP checks to ensure correct identification
This commit is contained in:
eduard256
2025-11-09 18:09:04 +03:00
parent 75afc987f4
commit 35293dec83
10 changed files with 266 additions and 10 deletions
+24
View File
@@ -176,6 +176,8 @@ func (b *Builder) replacePlaceholders(urlPath string, ctx BuildContext) string {
replacements := map[string]string{
"[CHANNEL]": strconv.Itoa(ctx.Channel),
"[channel]": strconv.Itoa(ctx.Channel),
"{channel}": strconv.Itoa(ctx.Channel), // BUBBLE protocol uses {channel}
"{CHANNEL}": strconv.Itoa(ctx.Channel),
"[WIDTH]": strconv.Itoa(ctx.Width),
"[width]": strconv.Itoa(ctx.Width),
"[HEIGHT]": strconv.Itoa(ctx.Height),
@@ -298,6 +300,28 @@ func (b *Builder) BuildURLsFromEntry(entry models.CameraEntry, ctx BuildContext)
}
switch entry.Protocol {
case "bubble":
// BUBBLE protocol: proprietary Chinese NVR/DVR protocol
// Always use HTTP with embedded credentials
if ctx.Username != "" && ctx.Password != "" {
// Build HTTP URL with credentials embedded
ctxHTTP := ctx
ctxHTTP.Protocol = "http"
baseURL := b.BuildURL(entry, ctxHTTP)
// Parse and add credentials to URL
if u, err := url.Parse(baseURL); err == nil {
u.User = url.UserPassword(ctx.Username, ctx.Password)
addURL(u.String())
}
} else {
// No credentials - try anyway (some cameras might work)
ctxHTTP := ctx
ctxHTTP.Protocol = "http"
addURL(b.BuildURL(entry, ctxHTTP))
}
case "rtsp", "rtsps":
// For RTSP: generate with and without credentials
if ctx.Username != "" && ctx.Password != "" {