From faf954a59d793fd6f85039147124fe07a305e7e2 Mon Sep 17 00:00:00 2001 From: cclohmar Date: Wed, 5 Aug 2026 14:42:09 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20go2rtc=20proxied=20through=20NextNVR=20?= =?UTF-8?q?=E2=80=94=20no=20port=201984=20forwarding=20needed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 ++------- public/app.js | 2 +- server.go | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1f4767c..650f416 100644 --- a/README.md +++ b/README.md @@ -52,16 +52,11 @@ Once done, open the web interface in your browser (the script prints the URL). To access NextNVR from outside your home network: 1. **Dynamic DNS** — use a free provider like DuckDNS, No-IP, or Cloudflare to get a domain name (e.g. `myhouse.duckdns.org`) -2. **Port forwarding** — in your router settings, forward these ports to the NextNVR server: - -| Port | Service | Required | -|------|---------|----------| -| `8080` | Web UI | Yes | -| `1984` | Live streaming | **Yes — live view won't work without it** | +2. **Port forwarding** — in your router settings, forward port `8080` to the NextNVR server Then access your cameras from anywhere: `http://myhouse.duckdns.org:8080` -> ⚠️ For production use, put NextNVR behind a reverse proxy (like Zoraxy or Nginx) with HTTPS to secure your connection. +> ⚠️ For production use, put NextNVR behind a reverse proxy (like Zoraxy or Nginx) with HTTPS. Only port 443 needs to be forwarded — live streams are proxied through NextNVR automatically. --- diff --git a/public/app.js b/public/app.js index 677181e..ee796e1 100644 --- a/public/app.js +++ b/public/app.js @@ -96,7 +96,7 @@ function renderLiveGrid() { function openFocus(cam) { const overlay = document.getElementById('focus-overlay'); overlay.classList.remove('hidden'); - document.getElementById('focus-frame').src = `http://${location.hostname}:1984/stream.html?src=${cam.id}_sub`; + document.getElementById('focus-frame').src = `/go2rtc/stream.html?src=${cam.id}_sub`; } document.getElementById('focus-close').addEventListener('click', () => { document.getElementById('focus-overlay').classList.add('hidden'); diff --git a/server.go b/server.go index 56c41da..25585fe 100644 --- a/server.go +++ b/server.go @@ -8,6 +8,8 @@ import ( "io/fs" "log" "net/http" + "net/http/httputil" + "net/url" "strings" ) @@ -53,6 +55,13 @@ func (s *Server) Close() { } } +// go2rtcProxy returns a reverse proxy to go2rtc on port 1984. +// Used to avoid mixed-content blocking when NextNVR is behind HTTPS. +func (s *Server) go2rtcProxy() http.Handler { + target, _ := url.Parse("http://127.0.0.1:1984") + return httputil.NewSingleHostReverseProxy(target) +} + // registerRoutes sets up all API and static file routes. func (s *Server) registerRoutes() { // API endpoints. @@ -66,6 +75,11 @@ func (s *Server) registerRoutes() { // Live MJPEG stream proxy — proxied through NextNVR to avoid cross-origin issues. s.mux.HandleFunc("/stream/", s.handleStream) + // go2rtc reverse proxy — serves the go2rtc web UI and API through NextNVR. + // This avoids mixed-content blocking when NextNVR is behind HTTPS. + s.mux.Handle("/go2rtc/", http.StripPrefix("/go2rtc", + s.go2rtcProxy())) + // Static file server for recordings (actual video files on disk). s.mux.Handle("/recordings/", http.StripPrefix("/recordings/", http.FileServer(http.Dir(s.config.Storage.RecordingsPath))))