iobroker.agent-dvr 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.de.md +3 -0
- package/README.md +3 -0
- package/admin/assets/index-B13Ujb6j.js +685 -0
- package/admin/assets/index-D7I0OIPq.js +685 -0
- package/admin/i18n/de.json +5 -2
- package/admin/i18n/en.json +5 -2
- package/admin/i18n/es.json +5 -2
- package/admin/i18n/fr.json +5 -2
- package/admin/i18n/it.json +5 -2
- package/admin/i18n/nl.json +5 -2
- package/admin/i18n/pl.json +5 -2
- package/admin/i18n/pt.json +5 -2
- package/admin/i18n/ru.json +5 -2
- package/admin/i18n/uk.json +5 -2
- package/admin/i18n/zh-cn.json +5 -2
- package/admin/index_m.html +1 -1
- package/io-package.json +14 -14
- package/lib/web.js +62 -0
- package/package.json +1 -1
package/admin/i18n/de.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Lade Kameras und Streams…",
|
|
136
136
|
"cfgCameraColumn": "AgentDVR Kamera",
|
|
137
137
|
"cfgStreamSourceColumn": "Stream-Quelle",
|
|
138
|
-
"reload": "Neu laden"
|
|
139
|
-
|
|
138
|
+
"reload": "Neu laden",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "MJPEG-Proxy",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "MJPEG- und Snapshot-URLs über ioBroker leiten (nur im MJPEG-Stream-Modus nötig — FLV und go2rtc laufen immer über ioBroker)"
|
|
142
|
+
}
|
package/admin/i18n/en.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Loading cameras and streams…",
|
|
136
136
|
"cfgCameraColumn": "AgentDVR Camera",
|
|
137
137
|
"cfgStreamSourceColumn": "Stream Source",
|
|
138
|
-
"reload": "Reload"
|
|
139
|
-
|
|
138
|
+
"reload": "Reload",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "MJPEG proxy",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Route MJPEG and snapshot URLs through ioBroker (only needed for MJPEG stream mode — FLV and go2rtc are always proxied)"
|
|
142
|
+
}
|
package/admin/i18n/es.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Cargando cámaras y streams…",
|
|
136
136
|
"cfgCameraColumn": "Cámara AgentDVR",
|
|
137
137
|
"cfgStreamSourceColumn": "Fuente de stream",
|
|
138
|
-
"reload": "Recargar"
|
|
139
|
-
|
|
138
|
+
"reload": "Recargar",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "Proxy MJPEG",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Enrutar MJPEG y snapshots a través de ioBroker (solo en modo MJPEG — FLV y go2rtc siempre se enrutan)"
|
|
142
|
+
}
|
package/admin/i18n/fr.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Chargement des caméras et des flux…",
|
|
136
136
|
"cfgCameraColumn": "Caméra AgentDVR",
|
|
137
137
|
"cfgStreamSourceColumn": "Source du flux",
|
|
138
|
-
"reload": "Recharger"
|
|
139
|
-
|
|
138
|
+
"reload": "Recharger",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "Proxy MJPEG",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Acheminer MJPEG et instantanés via ioBroker (uniquement en mode MJPEG — FLV et go2rtc sont toujours proxied)"
|
|
142
|
+
}
|
package/admin/i18n/it.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Caricamento telecamere e stream…",
|
|
136
136
|
"cfgCameraColumn": "Telecamera AgentDVR",
|
|
137
137
|
"cfgStreamSourceColumn": "Sorgente stream",
|
|
138
|
-
"reload": "Ricarica"
|
|
139
|
-
|
|
138
|
+
"reload": "Ricarica",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "Proxy MJPEG",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Instradare MJPEG e snapshot tramite ioBroker (solo in modalità MJPEG — FLV e go2rtc sono sempre proxied)"
|
|
142
|
+
}
|
package/admin/i18n/nl.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Camera's en streams laden…",
|
|
136
136
|
"cfgCameraColumn": "AgentDVR Camera",
|
|
137
137
|
"cfgStreamSourceColumn": "Streambron",
|
|
138
|
-
"reload": "Herladen"
|
|
139
|
-
|
|
138
|
+
"reload": "Herladen",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "MJPEG-proxy",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "MJPEG- en snapshot-URLs via ioBroker routen (alleen nodig in MJPEG-modus — FLV en go2rtc worden altijd geproxied)"
|
|
142
|
+
}
|
package/admin/i18n/pl.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Ładowanie kamer i strumieni…",
|
|
136
136
|
"cfgCameraColumn": "Kamera AgentDVR",
|
|
137
137
|
"cfgStreamSourceColumn": "Źródło strumienia",
|
|
138
|
-
"reload": "Odśwież"
|
|
139
|
-
|
|
138
|
+
"reload": "Odśwież",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "Proxy MJPEG",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Kieruj MJPEG i migawki przez ioBroker (tylko w trybie MJPEG — FLV i go2rtc są zawsze proxied)"
|
|
142
|
+
}
|
package/admin/i18n/pt.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Carregando câmeras e streams…",
|
|
136
136
|
"cfgCameraColumn": "Câmera AgentDVR",
|
|
137
137
|
"cfgStreamSourceColumn": "Fonte de stream",
|
|
138
|
-
"reload": "Recarregar"
|
|
139
|
-
|
|
138
|
+
"reload": "Recarregar",
|
|
139
|
+
"hdrProxy": "Proxy",
|
|
140
|
+
"cfgEnableStreamProxy": "Proxy MJPEG",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Rotear MJPEG e snapshots pelo ioBroker (necessário apenas no modo MJPEG — FLV e go2rtc já são sempre proxied)"
|
|
142
|
+
}
|
package/admin/i18n/ru.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Загрузка камер и потоков…",
|
|
136
136
|
"cfgCameraColumn": "Камера AgentDVR",
|
|
137
137
|
"cfgStreamSourceColumn": "Источник потока",
|
|
138
|
-
"reload": "Обновить"
|
|
139
|
-
|
|
138
|
+
"reload": "Обновить",
|
|
139
|
+
"hdrProxy": "Прокси",
|
|
140
|
+
"cfgEnableStreamProxy": "MJPEG-прокси",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Маршрутизировать MJPEG и снимки через ioBroker (только для режима MJPEG — FLV и go2rtc всегда проксируются)"
|
|
142
|
+
}
|
package/admin/i18n/uk.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "Завантаження камер і потоків…",
|
|
136
136
|
"cfgCameraColumn": "Камера AgentDVR",
|
|
137
137
|
"cfgStreamSourceColumn": "Джерело потоку",
|
|
138
|
-
"reload": "Оновити"
|
|
139
|
-
|
|
138
|
+
"reload": "Оновити",
|
|
139
|
+
"hdrProxy": "Проксі",
|
|
140
|
+
"cfgEnableStreamProxy": "MJPEG-проксі",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "Маршрутизувати MJPEG і знімки через ioBroker (лише для режиму MJPEG — FLV і go2rtc завжди проксіюються)"
|
|
142
|
+
}
|
package/admin/i18n/zh-cn.json
CHANGED
|
@@ -135,5 +135,8 @@
|
|
|
135
135
|
"loadingCamerasAndStreams": "正在加载摄像头和流…",
|
|
136
136
|
"cfgCameraColumn": "AgentDVR 摄像头",
|
|
137
137
|
"cfgStreamSourceColumn": "流来源",
|
|
138
|
-
"reload": "重新加载"
|
|
139
|
-
|
|
138
|
+
"reload": "重新加载",
|
|
139
|
+
"hdrProxy": "代理",
|
|
140
|
+
"cfgEnableStreamProxy": "MJPEG 代理",
|
|
141
|
+
"cfgEnableStreamProxy_tt": "通过 ioBroker 路由 MJPEG 和快照(仅 MJPEG 模式需要 — FLV 和 go2rtc 始终通过代理)"
|
|
142
|
+
}
|
package/admin/index_m.html
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
};
|
|
19
19
|
document.head.appendChild(script);
|
|
20
20
|
</script>
|
|
21
|
-
<script type="module" crossorigin src="./assets/index-
|
|
21
|
+
<script type="module" crossorigin src="./assets/index-B13Ujb6j.js"></script>
|
|
22
22
|
</head>
|
|
23
23
|
<body>
|
|
24
24
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "agent-dvr",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.4.0": {
|
|
7
|
+
"en": "Optional MJPEG and snapshot stream proxy through ioBroker (browser needs only one connection)",
|
|
8
|
+
"de": "Optionaler MJPEG- und Snapshot-Stream-Proxy über ioBroker (Browser benötigt nur eine Verbindung)",
|
|
9
|
+
"ru": "Опциональный прокси потоков MJPEG и снимков через ioBroker",
|
|
10
|
+
"pt": "Proxy opcional de streams MJPEG e snapshots pelo ioBroker",
|
|
11
|
+
"nl": "Optionele MJPEG- en snapshot-proxy via ioBroker",
|
|
12
|
+
"fr": "Proxy optionnel pour les flux MJPEG et snapshots via ioBroker",
|
|
13
|
+
"it": "Proxy opzionale per stream MJPEG e snapshot tramite ioBroker",
|
|
14
|
+
"es": "Proxy opcional de flujos MJPEG e instantáneas a través de ioBroker",
|
|
15
|
+
"pl": "Opcjonalny proxy strumieni MJPEG i migawek przez ioBroker",
|
|
16
|
+
"zh-cn": "可选的 MJPEG 和快照流代理(通过 ioBroker)",
|
|
17
|
+
"uk": "Опціональний проксі потоків MJPEG і знімків через ioBroker"
|
|
18
|
+
},
|
|
6
19
|
"0.3.0": {
|
|
7
20
|
"en": "New control buttons (scheduleOn/Off, detectorOn/Off, sensitivityMin/Max/Gain), audio URL states for microphones, native browser fullscreen in dashboard, collapsible tag filter, auto-hide header",
|
|
8
21
|
"de": "Neue Steuertasten (scheduleOn/Off, detectorOn/Off, Empfindlichkeit), Audio-URL-Zustände für Mikrofone, nativer Browser-Vollbild im Dashboard, ausklappbarer Tag-Filter, Auto-Hide-Header",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "dodano dokumentację Live Dashboard i go2rtc WebRTC do README",
|
|
81
94
|
"uk": "додано документацію Live Dashboard і go2rtc WebRTC до README",
|
|
82
95
|
"zh-cn": "README 中新增 Live Dashboard 和 go2rtc WebRTC 文档"
|
|
83
|
-
},
|
|
84
|
-
"0.0.5": {
|
|
85
|
-
"en": "go2rtc WebRTC integration (admin table mapping, ioBroker WS proxy); auto-delete stale cameras; fix recording prev/next order",
|
|
86
|
-
"de": "go2rtc WebRTC-Integration (Admin-Tabellen-Mapping, ioBroker WS-Proxy); gelöschte Kameras werden automatisch entfernt; Vor/Zurück-Reihenfolge bei Aufnahmen korrigiert",
|
|
87
|
-
"ru": "интеграция go2rtc WebRTC (таблица в admin, WS-прокси через ioBroker); автоудаление устаревших камер; исправлен порядок кнопок Пред/След для записей",
|
|
88
|
-
"pt": "integração go2rtc WebRTC (tabela no admin, proxy WS via ioBroker); remoção automática de câmeras obsoletas; ordem anterior/próximo nas gravações corrigida",
|
|
89
|
-
"nl": "go2rtc WebRTC-integratie (admintabel, ioBroker WS-proxy); automatisch verwijderen van verouderde camera's; volgorde vorige/volgende opnames gecorrigeerd",
|
|
90
|
-
"fr": "intégration go2rtc WebRTC (table admin, proxy WS ioBroker); suppression automatique des caméras obsolètes; ordre précédent/suivant des enregistrements corrigé",
|
|
91
|
-
"it": "integrazione go2rtc WebRTC (tabella admin, proxy WS ioBroker); eliminazione automatica telecamere obsolete; ordine precedente/successivo registrazioni corretto",
|
|
92
|
-
"es": "integración go2rtc WebRTC (tabla en admin, proxy WS ioBroker); eliminación automática de cámaras obsoletas; orden anterior/siguiente en grabaciones corregido",
|
|
93
|
-
"pl": "integracja go2rtc WebRTC (tabela w admin, proxy WS ioBroker); automatyczne usuwanie nieaktywnych kamer; poprawiona kolejność poprzedni/następny nagrań",
|
|
94
|
-
"uk": "інтеграція go2rtc WebRTC (таблиця в admin, WS-проксі через ioBroker); автовидалення застарілих камер; виправлено порядок кнопок Попередній/Наступний для записів",
|
|
95
|
-
"zh-cn": "go2rtc WebRTC 集成(管理表格映射,ioBroker WS 代理);自动删除过时摄像头;修正录像上一个/下一个顺序"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/lib/web.js
CHANGED
|
@@ -28,6 +28,11 @@ class AgentDvrWeb {
|
|
|
28
28
|
const ns = instanceSettings ? instanceSettings._id.replace('system.adapter.', '') : 'agent-dvr.0';
|
|
29
29
|
const native = (instanceSettings && instanceSettings.native) ? instanceSettings.native : {};
|
|
30
30
|
|
|
31
|
+
// Cache auth header for proxy endpoints
|
|
32
|
+
this._authHeader = (native.user || native.pass)
|
|
33
|
+
? 'Basic ' + Buffer.from((native.user || '') + ':' + (native.pass || '')).toString('base64')
|
|
34
|
+
: null;
|
|
35
|
+
|
|
31
36
|
// ── REST API ─────────────────────────────────────────────────────────
|
|
32
37
|
// Must be registered before the static file handler (Express matches in order)
|
|
33
38
|
app.get('/' + ROUTE + '/api/cameras', (req, res) => {
|
|
@@ -108,6 +113,16 @@ class AgentDvrWeb {
|
|
|
108
113
|
});
|
|
109
114
|
}
|
|
110
115
|
|
|
116
|
+
// Replace stream URLs with proxy URLs when enableStreamProxy is on
|
|
117
|
+
if (native.enableStreamProxy) {
|
|
118
|
+
Object.values(cameras).forEach(cam => {
|
|
119
|
+
if (cam.oid) {
|
|
120
|
+
cam.mjpegUrl = '/' + ROUTE + '/api/mjpeg?oid=' + cam.oid;
|
|
121
|
+
cam.snapshotUrl = '/' + ROUTE + '/api/snap?oid=' + cam.oid;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
111
126
|
// Build aspect from data.width / data.height states written by flattenWrite.
|
|
112
127
|
// Reading from ioBroker states is reliable regardless of whether the web
|
|
113
128
|
// extension runs in the same process as the main adapter.
|
|
@@ -159,6 +174,53 @@ class AgentDvrWeb {
|
|
|
159
174
|
}));
|
|
160
175
|
});
|
|
161
176
|
|
|
177
|
+
// ── MJPEG stream proxy (optional: enableStreamProxy) ─────────────────
|
|
178
|
+
app.get('/' + ROUTE + '/api/mjpeg', (req, res) => {
|
|
179
|
+
const base = (native.ip && native.port) ? 'http://' + native.ip + ':' + native.port : '';
|
|
180
|
+
if (!base) { res.status(503).end('AgentDVR not configured'); return; }
|
|
181
|
+
const oid = String(req.query.oid || '');
|
|
182
|
+
if (!oid || !/^\d+$/.test(oid)) { res.status(400).end('invalid oid'); return; }
|
|
183
|
+
const url = base + '/video.mjpg?oid=' + oid;
|
|
184
|
+
let target;
|
|
185
|
+
try { target = new URL(url); } catch (_) { res.status(500).end(); return; }
|
|
186
|
+
const mod = target.protocol === 'https:' ? https : http;
|
|
187
|
+
const headers = {};
|
|
188
|
+
if (this._authHeader) headers['Authorization'] = this._authHeader;
|
|
189
|
+
const upReq = mod.get({ hostname: target.hostname, port: target.port, path: target.pathname + target.search, headers }, upstream => {
|
|
190
|
+
res.setHeader('Content-Type', upstream.headers['content-type'] || 'multipart/x-mixed-replace');
|
|
191
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
192
|
+
res.setHeader('X-Accel-Buffering', 'no');
|
|
193
|
+
upstream.pipe(res);
|
|
194
|
+
upstream.on('error', () => { if (!res.headersSent) res.status(502).end(); else res.end(); });
|
|
195
|
+
});
|
|
196
|
+
upReq.setTimeout(0); // no timeout for infinite MJPEG stream
|
|
197
|
+
upReq.on('error', () => { if (!res.headersSent) res.status(502).end(); else res.end(); });
|
|
198
|
+
req.on('close', () => { try { upReq.destroy(); } catch (_) {} });
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// ── Snapshot proxy (optional: enableStreamProxy) ──────────────────────
|
|
202
|
+
app.get('/' + ROUTE + '/api/snap', (req, res) => {
|
|
203
|
+
const base = (native.ip && native.port) ? 'http://' + native.ip + ':' + native.port : '';
|
|
204
|
+
if (!base) { res.status(503).end('AgentDVR not configured'); return; }
|
|
205
|
+
const oid = String(req.query.oid || '');
|
|
206
|
+
if (!oid || !/^\d+$/.test(oid)) { res.status(400).end('invalid oid'); return; }
|
|
207
|
+
const url = base + '/grab.jpg?oid=' + oid;
|
|
208
|
+
let target;
|
|
209
|
+
try { target = new URL(url); } catch (_) { res.status(500).end(); return; }
|
|
210
|
+
const mod = target.protocol === 'https:' ? https : http;
|
|
211
|
+
const headers = {};
|
|
212
|
+
if (this._authHeader) headers['Authorization'] = this._authHeader;
|
|
213
|
+
const upReq = mod.get({ hostname: target.hostname, port: target.port, path: target.pathname + target.search, headers }, upstream => {
|
|
214
|
+
res.setHeader('Content-Type', upstream.headers['content-type'] || 'image/jpeg');
|
|
215
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
216
|
+
upstream.pipe(res);
|
|
217
|
+
upstream.on('error', () => { if (!res.headersSent) res.status(502).end(); else res.end(); });
|
|
218
|
+
});
|
|
219
|
+
upReq.setTimeout(8000, () => upReq.destroy());
|
|
220
|
+
upReq.on('error', () => { if (!res.headersSent) res.status(502).end(); else res.end(); });
|
|
221
|
+
req.on('close', () => { try { upReq.destroy(); } catch (_) {} });
|
|
222
|
+
});
|
|
223
|
+
|
|
162
224
|
// ── FLV stream proxy (avoids browser CORS block for flv.js XHR) ────────
|
|
163
225
|
app.get('/' + ROUTE + '/api/stream', (req, res) => {
|
|
164
226
|
const base = (native.ip && native.port) ? 'http://' + native.ip + ':' + native.port : '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.agent-dvr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Connects ioBroker to AgentDVR: auto-discovers cameras, mirrors all device values as data points, delivers real-time triggers on new recordings, and generates a responsive HTML gallery with optional search and tag filtering.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "ipod86",
|