iobroker.agent-dvr 0.1.0 → 0.2.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 +289 -175
- package/README.md +226 -90
- package/admin/assets/index-ulvdM37k.js +685 -0
- package/admin/i18n/de.json +3 -7
- package/admin/i18n/en.json +131 -135
- package/admin/i18n/es.json +3 -7
- package/admin/i18n/fr.json +3 -7
- package/admin/i18n/it.json +3 -7
- package/admin/i18n/nl.json +3 -7
- package/admin/i18n/pl.json +3 -7
- package/admin/i18n/pt.json +3 -7
- package/admin/i18n/ru.json +3 -7
- package/admin/i18n/uk.json +3 -7
- package/admin/i18n/zh-cn.json +3 -7
- package/admin/index_m.html +27 -0
- package/build/main.js +152 -103
- package/build/main.js.map +2 -2
- package/io-package.json +16 -17
- package/lib/web.js +52 -5
- package/package.json +1 -1
- package/www/flv.min.js +7534 -0
- package/www/index.html +382 -99
- package/admin/custom/go2rtcMapping.js +0 -169
- package/admin/jsonConfig.json +0 -822
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.2.0",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.2.0": {
|
|
7
|
+
"en": "feat: dashboard camera filter badges with localStorage persistence\nfeat: FLV/MP4 stream auto-reconnect after network error (5 s delay)\nfeat: go2rtc WebSocket auto-reconnect after unexpected disconnect (5 s delay)\nfeat: go2rtc stall detection — retry if stream stays black after 10 s\nfix: cameraStreams missing from io-package.json native defaults (settings not saved)\nfix: adminUI.config \"custom\" → \"materialize\" (404 on adapter settings page)\nfix: remove resolution overlay on FLV stream load\nfix: remove CDN fallback for flv.js — local copy only\nfix: remove AgentDVR/go2rtc section headers from dashboard grid\nfix: cfgGo2rtcMapping_tt tooltip corrected in all 11 languages\nfix: plain setTimeout() replaced by this.setTimeout() (E5005)\nfix: remove obsolete jsonConfig.json — settings handled by React admin (W5046)\nchore: exclude admin/ directory from ESLint to prevent OOM in CI\ndocs: rewrite README and README.de with all tabs and settings documented",
|
|
8
|
+
"de": "Funktion: Filter-Badges für Dashcams mit Speicherung im lokalen Speicher\nFunktion: Automatische Wiederverbindung des FLV/MP4-Streams nach Netzwerkfehlern (5 Sekunden Verzögerung)\nFunktion: Automatische Wiederverbindung von go2rtc-WebSockets nach unerwarteter Trennung (5 Sekunden Verzögerung)\nFunktion: go2rtc-Stall-Erkennung – Wiederholungsversuch, falls der Stream nach 10 Sekunden schwarz bleibt\nBehoben: cameraStreams fehlen in den nativen Standardeinstellungen von io-package.json (Einstellungen werden nicht gespeichert)\nBehebung: adminUI.config \"custom\" → \"materialize\" (404 auf der Adaptereinstellungsseite)\nBehoben: Auflösungsüberlagerung beim Laden des FLV-Streams entfernt\nBehebung: CDN-Fallback für flv.js entfernen – nur lokale Kopie\nBehebung: Entfernen der Abschnittsüberschriften AgentDVR/go2rtc aus dem Dashboard-Raster\nBehoben: Tooltip für cfgGo2rtcMapping_tt in allen 11 Sprachen korrigiert.\nBehebung: Die einfache setTimeout()-Funktion wurde durch this.setTimeout() ersetzt (E5005)\nBehebung: Entfernen der veralteten Datei jsonConfig.json – Einstellungen werden vom React-Admin verwaltet (W5046)\nAufgabe: Das Verzeichnis „admin/“ von ESLint ausschließen, um einen Speichermangel in der CI zu verhindern.\nDokumentation: README und README.de neu schreiben und alle Tabs und Einstellungen dokumentieren",
|
|
9
|
+
"ru": "особенность: значки фильтров с видеорегистратора с сохранением в локальном хранилище.\nФункция: автоматическое переподключение потока FLV/MP4 после ошибки сети (задержка 5 с).\nФункция: автоматическое переподключение WebSocket через go2rtc после неожиданного разрыва соединения (задержка 5 с).\nФункция: обнаружение зависаний go2rtc — повторная попытка, если поток остается черным через 10 секунд.\nИсправление: в настройках по умолчанию файла io-package.json отсутствуют параметры cameraStreams (настройки не сохраняются).\nИсправление: в файле adminUI.config \"custom\" → \"materialize\" (ошибка 404 на странице настроек адаптера)\nИсправление: удалено наложение разрешения при загрузке FLV-потока.\nИсправление: удален резервный вариант CDN для flv.js — только локальная копия\nИсправление: удалены заголовки раздела AgentDVR/go2rtc из сетки панели мониторинга.\nИсправлено: подсказка cfgGo2rtcMapping_tt исправлена на всех 11 языках.\nИсправление: обычный setTimeout() заменен на this.setTimeout() (E5005)\nИсправление: удален устаревший файл jsonConfig.json — настройки обрабатываются администрацией React (W5046)\nЗадача: исключить каталог admin/ из ESLint, чтобы предотвратить ошибку нехватки памяти в CI.\nДокументация: переписать файлы README и README.de, добавив документацию по всем вкладкам и настройкам.",
|
|
10
|
+
"pt": "Recurso: ícones de filtro da câmera do painel com persistência no localStorage.\nFuncionalidade: reconexão automática de fluxos FLV/MP4 após erro de rede (atraso de 5 segundos)\nFuncionalidade: reconexão automática do WebSocket go2rtc após desconexão inesperada (atraso de 5 segundos)\nRecurso: detecção de interrupção do go2rtc — tente novamente se o fluxo permanecer preto após 10 segundos.\nCorreção: cameraStreams ausente das configurações padrão nativas do io-package.json (configurações não salvas)\nCorreção: adminUI.config \"custom\" → \"materialize\" (404 na página de configurações do adaptador)\nCorreção: remover a sobreposição de resolução no carregamento do fluxo FLV.\nCorreção: remover o fallback de CDN para flv.js — somente cópia local.\nCorreção: remover os cabeçalhos da seção AgentDVR/go2rtc da grade do painel de controle.\nCorreção: a dica de ferramenta cfgGo2rtcMapping_tt foi corrigida em todos os 11 idiomas.\nCorreção: setTimeout() simples substituído por this.setTimeout() (E5005)\nCorreção: remover o arquivo jsonConfig.json obsoleto — configurações gerenciadas pelo administrador do React (W5046)\nTarefa: excluir o diretório admin/ do ESLint para evitar falta de memória (OOM) na integração contínua (CI).\ndocs: reescrever o README e o README.de com todas as abas e configurações documentadas.",
|
|
11
|
+
"nl": "Feature: dashboardcamerafilterbadges met persistentie in LocalStorage.\nFunctie: Automatische herverbinding met FLV/MP4-stream na netwerkfout (vertraging van 5 seconden)\nfeat: go2rtc WebSocket automatisch opnieuw verbinden na onverwachte onderbreking (vertraging van 5 seconden)\nfeat: go2rtc-detectie van vastlopen — probeer het opnieuw als de stream na 10 seconden zwart blijft.\nOpgelost: cameraStreams ontbreken in de native defaults van io-package.json (instellingen worden niet opgeslagen)\nOplossing: adminUI.config \"custom\" → \"materialize\" (404 op de pagina met adapterinstellingen)\nOplossing: verwijder de resolutie-overlay bij het laden van FLV-streams.\nOplossing: verwijder de CDN-fallback voor flv.js — alleen voor lokale kopieën\nOplossing: verwijder de kopteksten van de secties AgentDVR/go2rtc uit het dashboardraster.\nOpgelost: de tooltip van cfgGo2rtcMapping_tt is in alle 11 talen gecorrigeerd.\nfix: plain setTimeout() vervangen door this.setTimeout() (E5005)\nOplossing: verwijder het verouderde jsonConfig.json-bestand — instellingen worden beheerd door React admin (W5046)\nTaak: sluit de map admin/ uit van ESLint om geheugenproblemen (OOM) in de CI te voorkomen.\ndocs: herschrijf README en README.de met alle tabbladen en instellingen gedocumenteerd",
|
|
12
|
+
"fr": "fonctionnalité : badges de filtre de caméra de tableau de bord avec persistance dans le stockage local\nFonctionnalité : reconnexion automatique du flux FLV/MP4 après une erreur réseau (délai de 5 s)\nFonctionnalité : reconnexion automatique WebSocket go2rtc après une déconnexion inattendue (délai de 5 s)\nFonctionnalité : détection de blocage go2rtc — nouvelle tentative si le flux reste noir après 10 s\nCorrection : les flux de caméra étaient absents des valeurs par défaut natives du fichier io-package.json (paramètres non enregistrés).\nCorrection : adminUI.config « custom » → « materialize » (erreur 404 sur la page des paramètres de l’adaptateur)\nCorrection : suppression de la superposition de résolution lors du chargement du flux FLV\nCorrection : suppression du CDN de secours pour flv.js — copie locale uniquement\nCorrection : suppression des en-têtes de section AgentDVR/go2rtc de la grille du tableau de bord\nCorrection : l'infobulle de cfgGo2rtcMapping_tt a été corrigée dans les 11 langues.\nCorrection : la méthode setTimeout() classique a été remplacée par this.setTimeout() (E5005)\nCorrection : suppression du fichier jsonConfig.json obsolète — paramètres gérés par l’interface d’administration React (W5046)\nTâche : exclure le répertoire admin/ d’ESLint pour éviter les erreurs de mémoire insuffisante dans l’intégration continue.\nDocumentation : réécrire les fichiers README et README.de en documentant tous les onglets et paramètres.",
|
|
13
|
+
"it": "Caratteristica: badge filtro per fotocamera da cruscotto con persistenza in localStorage\nCaratteristica: Riconnessione automatica del flusso FLV/MP4 dopo un errore di rete (ritardo di 5 secondi)\nfeat: go2rtc WebSocket riconnessione automatica dopo disconnessione imprevista (ritardo di 5 s)\nfeat: go2rtc stall detection — riprova se lo stream rimane nero dopo 10 s\nCorrezione: cameraStreams mancante dalle impostazioni predefinite native di io-package.json (impostazioni non salvate)\nCorrezione: adminUI.config \"custom\" → \"materialize\" (errore 404 nella pagina delle impostazioni dell'adattatore)\nCorrezione: rimuovere la sovrapposizione di risoluzione durante il caricamento del flusso FLV\nCorrezione: rimosso il fallback CDN per flv.js — solo copia locale\nCorrezione: rimuovere le intestazioni di sezione AgentDVR/go2rtc dalla griglia del pannello di controllo\nCorrezione: tooltip di cfgGo2rtcMapping_tt corretto in tutte le 11 lingue\nCorrezione: setTimeout() semplice sostituito da this.setTimeout() (E5005)\nCorrezione: rimozione del file jsonConfig.json obsoleto — impostazioni gestite dall'amministratore di React (W5046)\ncompito: escludere la directory admin/ da ESLint per prevenire errori di memoria insufficiente (OOM) in CI\nDocumentazione: riscrivere README e README.de con tutte le schede e le impostazioni documentate.",
|
|
14
|
+
"es": "Característica: insignias de filtro de cámara de tablero con persistencia de almacenamiento local\nCaracterística: Reconexión automática de la transmisión FLV/MP4 tras un error de red (retraso de 5 s).\nfeat: reconexión automática de go2rtc WebSocket tras una desconexión inesperada (retraso de 5 s)\nfeat: detección de bloqueo de go2rtc: reintentar si la transmisión permanece en negro después de 10 s\nCorrección: falta cameraStreams en la configuración predeterminada nativa de io-package.json (la configuración no se guarda).\nCorrección: adminUI.config \"custom\" → \"materialize\" (error 404 en la página de configuración del adaptador)\nCorrección: eliminar la superposición de resolución en la carga de la transmisión FLV\nCorrección: eliminar la reserva de CDN para flv.js; solo copia local.\nCorrección: eliminar los encabezados de sección AgentDVR/go2rtc de la cuadrícula del panel de control.\nCorrección: Se ha corregido la información sobre herramientas de cfgGo2rtcMapping_tt en los 11 idiomas.\nCorrección: setTimeout() simple reemplazado por this.setTimeout() (E5005)\nCorrección: eliminar el archivo jsonConfig.json obsoleto; la configuración la gestiona el administrador de React (W5046).\nTarea: excluir el directorio admin/ de ESLint para evitar errores de memoria insuficiente (OOM) en CI.\ndocs: reescribir README y README.de con todas las pestañas y configuraciones documentadas.",
|
|
15
|
+
"pl": "wyczyn: odznaki filtrów kamery na desce rozdzielczej z trwałością localStorage\nwyczyn: automatyczne ponowne łączenie się strumienia FLV/MP4 po błędzie sieci (opóźnienie 5 s)\nfeat: go2rtc WebSocket – automatyczne ponowne łączenie po nieoczekiwanym rozłączeniu (5 s opóźnienia)\nwyczyn: wykrywanie przestoju go2rtc — spróbuj ponownie, jeśli strumień pozostanie czarny po 10 s\nnaprawiono: brak strumieni cameraStreams w domyślnych ustawieniach natywnych pliku io-package.json (ustawienia nie zostały zapisane)\nnaprawiono: adminUI.config „custom” → „materialize” (404 na stronie ustawień adaptera)\nnaprawiono: usuń nakładkę rozdzielczości podczas ładowania strumienia FLV\nnaprawiono: usunięto zapasowy CDN dla flv.js — tylko lokalna kopia\nnaprawiono: usunięcie nagłówków sekcji AgentDVR/go2rtc z siatki pulpitu nawigacyjnego\nnaprawiono: poprawiono podpowiedź cfgGo2rtcMapping_tt we wszystkich 11 językach\nnaprawiono: proste setTimeout() zastąpiono przez this.setTimeout() (E5005)\nnaprawiono: usunięto przestarzały plik jsonConfig.json — ustawienia obsługiwane przez administratora React (W5046)\nchore: wyklucz katalog admin/ z ESLint, aby zapobiec brakowi pamięci w CI\ndokumenty: przepisz pliki README i README.de, dokumentując wszystkie karty i ustawienia",
|
|
16
|
+
"uk": "подвиг: значки фільтрів камери на приладовій панелі з локальним сховищем\nфункція: автоматичне перепідключення потоку FLV/MP4 після помилки мережі (затримка 5 секунд)\nфункція: автоматичне перепідключення go2rtc WebSocket після неочікуваного відключення (затримка 5 секунд)\nфункція: виявлення зупинки go2rtc — повторна спроба, якщо потік залишається чорним після 10 секунд\nвиправлення: cameraStreams відсутні в рідних налаштуваннях io-package.json за замовчуванням (налаштування не збережено)\nвиправлення: adminUI.config \"custom\" → \"materialize\" (404 на сторінці налаштувань адаптера)\nвиправлення: видалено накладання роздільної здатності під час завантаження потоку FLV\nвиправлення: видалено резервну CDN-мережу для flv.js — лише локальна копія\nвиправлення: видалено заголовки розділів AgentDVR/go2rtc із сітки панелі інструментів\nвиправлення: підказку cfgGo2rtcMapping_tt виправлено всіма 11 мовами\nвиправлення: звичайний setTimeout() замінено на this.setTimeout() (E5005)\nвиправлення: видалено застарілий jsonConfig.json — налаштування, що обробляються адміністратором React (W5046)\nзавдання: виключити каталог admin/ з ESLint, щоб запобігти OOM у CI\nдокументація: переписати README та README.de з документацією всіх вкладок та налаштувань",
|
|
17
|
+
"zh-cn": "功能:行车记录仪滤镜徽章,支持本地存储持久化\n功能:FLV/MP4 视频流在网络错误后自动重连(延迟 5 秒)\n功能:go2rtc WebSocket 在意外断开连接后自动重连(延迟 5 秒)\n功能:go2rtc 卡顿检测——如果视频流在 10 秒后仍然黑屏,则重试\n修复:io-package.json 原生默认值中缺少 cameraStreams(设置未保存)\n修复:adminUI.config \"custom\" → \"materialize\"(适配器设置页面显示 404 错误)\n修复:移除 FLV 流加载时的分辨率叠加层\n修复:移除 flv.js 的 CDN 回退方案,仅保留本地副本。\n修复:从仪表盘网格中移除 AgentDVR/go2rtc 部分标题\n修复:已修正所有 11 种语言的 cfgGo2rtcMapping_tt 工具提示\n修复:将普通的 setTimeout() 替换为 this.setTimeout() (E5005)\n修复:移除过时的 jsonConfig.json 文件——该设置由 React 管理后台处理 (W5046)\n任务:将 admin/ 目录从 ESLint 中排除,以防止 CI 中出现内存溢出 (OOM)。\n文档:重写 README 和 README.de,并记录所有选项卡和设置。"
|
|
18
|
+
},
|
|
6
19
|
"0.1.0": {
|
|
7
20
|
"en": "feat: add full i18n to live dashboard — all UI strings translated into 11 languages\nfix: add missing sm/md/lg/xl size attributes to go2rtcMapping table in jsonConfig.json (E5507)\nfix: translate missing admin i18n keys into 9 languages (E5606)",
|
|
8
21
|
"de": "Feature: Vollständige Internationalisierung (i18n) im Live-Dashboard – alle UI-Texte in 11 Sprachen übersetzt\nBehebung: Fehlende Größenattribute sm/md/lg/xl zur go2rtcMapping-Tabelle in jsonConfig.json hinzufügen (E5507)\nBehebung: Fehlende i18n-Schlüssel für Administratoren in 9 Sprachen übersetzen (E5606)",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "konfiguracja zaufanego publikowania npm i poprawki wyników repocheckera",
|
|
81
94
|
"uk": "налаштування довіреної публікації npm та виправлення знахідок репочекера",
|
|
82
95
|
"zh-cn": "设置 npm 可信发布并修复 repochecker 问题"
|
|
83
|
-
},
|
|
84
|
-
"0.0.1": {
|
|
85
|
-
"en": "initial release",
|
|
86
|
-
"de": "Erstveröffentlichung",
|
|
87
|
-
"ru": "Начальная версия",
|
|
88
|
-
"pt": "lançamento inicial",
|
|
89
|
-
"nl": "Eerste uitgave",
|
|
90
|
-
"fr": "Première version",
|
|
91
|
-
"it": "Versione iniziale",
|
|
92
|
-
"es": "Versión inicial",
|
|
93
|
-
"pl": "Pierwsze wydanie",
|
|
94
|
-
"uk": "Початкова версія",
|
|
95
|
-
"zh-cn": "首次出版"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
"connectionType": "local",
|
|
148
148
|
"dataSource": "poll",
|
|
149
149
|
"adminUI": {
|
|
150
|
-
"config": "
|
|
150
|
+
"config": "materialize"
|
|
151
151
|
},
|
|
152
152
|
"dependencies": [
|
|
153
153
|
{
|
|
@@ -218,9 +218,8 @@
|
|
|
218
218
|
"widgetColorAccent": "#8ab4f8",
|
|
219
219
|
"widgetColorModalBg": "#1c1c1e",
|
|
220
220
|
"widgetBorderRadius": 8,
|
|
221
|
-
"go2rtcEnabled": false,
|
|
222
221
|
"go2rtcUrl": "",
|
|
223
|
-
"
|
|
222
|
+
"cameraStreams": {},
|
|
224
223
|
"dashColorBg": "#080b0f",
|
|
225
224
|
"dashColorSurface": "#0d1117",
|
|
226
225
|
"dashColorAccent": "#2563eb",
|
package/lib/web.js
CHANGED
|
@@ -42,13 +42,15 @@ class AgentDvrWeb {
|
|
|
42
42
|
adapter.getForeignStatesAsync(ns + '.cam_*.status.recording'),
|
|
43
43
|
adapter.getForeignStatesAsync(ns + '.cam_*.status.detected'),
|
|
44
44
|
adapter.getForeignStatesAsync(ns + '.cam_*.status.alerted'),
|
|
45
|
-
|
|
45
|
+
adapter.getForeignStatesAsync(ns + '.cam_*.data.width'),
|
|
46
|
+
adapter.getForeignStatesAsync(ns + '.cam_*.data.height'),
|
|
47
|
+
]).then(([nameStates, mjpegStates, snapStates, onlineStates, ptzStates, recStates, detStates, alertStates, widthStates, heightStates]) => {
|
|
46
48
|
const cameras = {};
|
|
47
49
|
|
|
48
50
|
Object.entries(nameStates || {}).forEach(([id, state]) => {
|
|
49
51
|
const rel = id.slice(ns.length + 1);
|
|
50
52
|
const camKey = rel.split('.')[0];
|
|
51
|
-
const m = camKey.match(/^cam_(\d+)
|
|
53
|
+
const m = camKey.match(/^cam_(\d+)/);
|
|
52
54
|
cameras[camKey] = {
|
|
53
55
|
name: (state && state.val != null) ? String(state.val) : camKey,
|
|
54
56
|
oid: m ? m[1] : null,
|
|
@@ -106,6 +108,23 @@ class AgentDvrWeb {
|
|
|
106
108
|
});
|
|
107
109
|
}
|
|
108
110
|
|
|
111
|
+
// Build aspect from data.width / data.height states written by flattenWrite.
|
|
112
|
+
// Reading from ioBroker states is reliable regardless of whether the web
|
|
113
|
+
// extension runs in the same process as the main adapter.
|
|
114
|
+
const wMap = {}, hMap = {};
|
|
115
|
+
Object.entries(widthStates || {}).forEach(([id, s]) => {
|
|
116
|
+
const k = id.slice(ns.length + 1).split('.')[0];
|
|
117
|
+
if (s && typeof s.val === 'number') wMap[k] = s.val;
|
|
118
|
+
});
|
|
119
|
+
Object.entries(heightStates || {}).forEach(([id, s]) => {
|
|
120
|
+
const k = id.slice(ns.length + 1).split('.')[0];
|
|
121
|
+
if (s && typeof s.val === 'number') hMap[k] = s.val;
|
|
122
|
+
});
|
|
123
|
+
Object.entries(cameras).forEach(([k, cam]) => {
|
|
124
|
+
const w = wMap[k], h = hMap[k];
|
|
125
|
+
cam.aspect = (w >= 100 && h >= 100 && w / h >= 0.3 && w / h <= 4) ? w + '/' + h : '';
|
|
126
|
+
});
|
|
127
|
+
|
|
109
128
|
res.setHeader('Content-Type', 'application/json');
|
|
110
129
|
res.end(JSON.stringify({ instance: ns, base, cameras }));
|
|
111
130
|
}).catch(err => {
|
|
@@ -132,15 +151,41 @@ class AgentDvrWeb {
|
|
|
132
151
|
dashColorOnline: native.dashColorOnline || '#22c55e',
|
|
133
152
|
dashColorOffline: native.dashColorOffline || '#ef4444',
|
|
134
153
|
dashTagPosition: native.dashTagPosition || 'top-right',
|
|
135
|
-
|
|
154
|
+
dashStreamType: native.dashStreamType || 'mjpeg',
|
|
136
155
|
go2rtcUrl: native.go2rtcUrl || '',
|
|
137
156
|
go2rtcMapping: Array.isArray(native.go2rtcMapping) ? native.go2rtcMapping : [],
|
|
157
|
+
cameraStreams: (native.cameraStreams && typeof native.cameraStreams === 'object') ? native.cameraStreams : {},
|
|
158
|
+
dashLiveSource: native.dashLiveSource || 'agentdvr',
|
|
138
159
|
}));
|
|
139
160
|
});
|
|
140
161
|
|
|
162
|
+
// ── FLV stream proxy (avoids browser CORS block for flv.js XHR) ────────
|
|
163
|
+
app.get('/' + ROUTE + '/api/stream', (req, res) => {
|
|
164
|
+
const base = (native.ip && native.port) ? 'http://' + native.ip + ':' + native.port : '';
|
|
165
|
+
if (!base) { res.status(503).end('AgentDVR not configured'); return; }
|
|
166
|
+
const oid = String(req.query.oid || '');
|
|
167
|
+
if (!oid || !/^\d+$/.test(oid)) { res.status(400).end('invalid oid'); return; }
|
|
168
|
+
const size = String(req.query.size || '');
|
|
169
|
+
const sizeStr = /^\d{1,5}x\d{1,5}$/.test(size) ? '&size=' + size : '';
|
|
170
|
+
const url = base + '/video.mp4?oid=' + oid + sizeStr;
|
|
171
|
+
let target;
|
|
172
|
+
try { target = new URL(url); } catch (_) { res.status(500).end(); return; }
|
|
173
|
+
const mod = target.protocol === 'https:' ? https : http;
|
|
174
|
+
const upReq = mod.get(url, upstream => {
|
|
175
|
+
res.setHeader('Content-Type', 'video/x-flv');
|
|
176
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
177
|
+
res.setHeader('X-Accel-Buffering', 'no');
|
|
178
|
+
upstream.pipe(res);
|
|
179
|
+
upstream.on('error', () => { if (!res.headersSent) res.status(502).end(); else res.end(); });
|
|
180
|
+
});
|
|
181
|
+
upReq.setTimeout(8000, () => upReq.destroy());
|
|
182
|
+
upReq.on('error', () => { if (!res.headersSent) res.status(502).end(); else res.end(); });
|
|
183
|
+
req.on('close', () => { try { upReq.destroy(); } catch (_) {} });
|
|
184
|
+
});
|
|
185
|
+
|
|
141
186
|
// ── go2rtc streams proxy ─────────────────────────────────────────────
|
|
142
187
|
app.get('/' + ROUTE + '/api/go2rtc/streams', (req, res) => {
|
|
143
|
-
if (!native.
|
|
188
|
+
if (!native.go2rtcUrl) {
|
|
144
189
|
res.setHeader('Content-Type', 'application/json');
|
|
145
190
|
res.end('{"streams":[]}');
|
|
146
191
|
return;
|
|
@@ -235,6 +280,8 @@ class AgentDvrWeb {
|
|
|
235
280
|
if (err) { res.status(404).end('Not found'); return; }
|
|
236
281
|
const ext = path.extname(file).toLowerCase();
|
|
237
282
|
res.setHeader('Content-Type', MIME[ext] || 'application/octet-stream');
|
|
283
|
+
// HTML must never be cached so updates are visible immediately
|
|
284
|
+
if (ext === '.html') res.setHeader('Cache-Control', 'no-store');
|
|
238
285
|
res.end(data);
|
|
239
286
|
});
|
|
240
287
|
});
|
|
@@ -244,7 +291,7 @@ class AgentDvrWeb {
|
|
|
244
291
|
// ── WebSocket proxy for go2rtc (bypasses browser cross-origin block) ─
|
|
245
292
|
server.on('upgrade', (req, socket, head) => {
|
|
246
293
|
if (!(req.url || '').startsWith('/' + ROUTE + '/api/ws')) return;
|
|
247
|
-
if (!native.
|
|
294
|
+
if (!native.go2rtcUrl) {
|
|
248
295
|
socket.write('HTTP/1.1 503 Service Unavailable\r\n\r\n');
|
|
249
296
|
socket.destroy();
|
|
250
297
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.agent-dvr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.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",
|