fix: proxy MJPEG stream through NextNVR to avoid cross-origin blocking
This commit is contained in:
parent
f248b796c6
commit
b68171f370
3 changed files with 40 additions and 3 deletions
36
api.go
36
api.go
|
|
@ -4,6 +4,7 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -118,7 +119,40 @@ func (s *Server) handleConfig(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
// handleScan triggers ONVIF network discovery.
|
||||
// handleStream proxies MJPEG streams from go2rtc to avoid cross-origin issues.
|
||||
// GET /stream/{cam_id}?type=sub (default: sub stream via go2rtc)
|
||||
func (s *Server) handleStream(w http.ResponseWriter, r *http.Request) {
|
||||
camID := strings.TrimPrefix(r.URL.Path, "/stream/")
|
||||
if camID == "" {
|
||||
http.Error(w, "camera ID required", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
streamType := r.URL.Query().Get("type")
|
||||
if streamType == "" {
|
||||
streamType = "sub"
|
||||
}
|
||||
|
||||
go2rtcURL := "http://127.0.0.1:1984/api/stream.mjpeg?src=" + camID + "_" + streamType
|
||||
|
||||
resp, err := http.Get(go2rtcURL)
|
||||
if err != nil {
|
||||
http.Error(w, "stream unavailable", http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Copy headers from go2rtc.
|
||||
for k, v := range resp.Header {
|
||||
for _, vv := range v {
|
||||
w.Header().Add(k, vv)
|
||||
}
|
||||
}
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
|
||||
// Stream the MJPEG data directly to the client.
|
||||
io.Copy(w, resp.Body)
|
||||
}
|
||||
// POST /api/scan
|
||||
// Body: {"method":"range","from":"192.168.1.200","to":"192.168.1.210","username":"admin","password":"..."}
|
||||
func (s *Server) handleScan(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
|||
|
|
@ -106,9 +106,9 @@ function updateFocus() {
|
|||
const cam = cameras[focusIdx];
|
||||
document.getElementById('focus-title').textContent = cam.name;
|
||||
document.getElementById('focus-time').textContent = new Date().toLocaleTimeString() + ' live';
|
||||
// go2rtc MJPEG stream — real live video via <img> tag, works in all browsers.
|
||||
// go2rtc MJPEG stream proxied through NextNVR — same origin, no CORS issues.
|
||||
const img = document.getElementById('focus-video');
|
||||
img.src = `http://${location.hostname}:1984/api/stream.mjpeg?src=${cam.id}_sub`;
|
||||
img.src = `/stream/${cam.id}?type=sub&t=${Date.now()}`;
|
||||
}
|
||||
function renderThumbs() {
|
||||
const strip = document.getElementById('focus-thumbs');
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ func (s *Server) registerRoutes() {
|
|||
s.mux.HandleFunc("/api/status", s.handleStatus)
|
||||
s.mux.HandleFunc("/api/recordings", s.handleRecordings)
|
||||
|
||||
// Live MJPEG stream proxy — proxied through NextNVR to avoid cross-origin issues.
|
||||
s.mux.HandleFunc("/stream/", s.handleStream)
|
||||
|
||||
// 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))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue