node-red-contrib-hik-media-buffer 1.1.47 → 1.1.49
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/hik-media-buffer.js +24 -18
- package/package.json +1 -1
package/hik-media-buffer.js
CHANGED
|
@@ -22,9 +22,7 @@ module.exports = function(RED) {
|
|
|
22
22
|
let isClosing = false;
|
|
23
23
|
let lastTriggerTime = {};
|
|
24
24
|
let nvrOnline = true;
|
|
25
|
-
|
|
26
25
|
let statoCanale = {};
|
|
27
|
-
let ultimoAllarmeTempo = {};
|
|
28
26
|
|
|
29
27
|
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
|
30
28
|
|
|
@@ -80,6 +78,7 @@ module.exports = function(RED) {
|
|
|
80
78
|
while ((matchBlocco = bloccoRegex.exec(xmlData)) !== null) {
|
|
81
79
|
const bloccoContenuto = matchBlocco[1];
|
|
82
80
|
|
|
81
|
+
// FISSO: Corretto il nome della variabile bloccoContenuto (prima c'era un typo che rompeva il nodo)
|
|
83
82
|
const idMatch = bloccoContenuto.match(/<id>(\d+)<\/id>/i);
|
|
84
83
|
const statusMatch = bloccoContenuto.match(/<status>([^<]+)</i);
|
|
85
84
|
|
|
@@ -120,20 +119,20 @@ module.exports = function(RED) {
|
|
|
120
119
|
|
|
121
120
|
const heartbeatInterval = setInterval(checkCameras, 30000);
|
|
122
121
|
|
|
123
|
-
// --- DOWNLOAD MULTIMEDIALE
|
|
122
|
+
// --- DOWNLOAD MULTIMEDIALE BASATO SULL'ISPEZIONA REALE DELL'NVR ---
|
|
124
123
|
async function downloadMedia(evento, channelID) {
|
|
125
124
|
const nowTime = Date.now();
|
|
126
125
|
if (!lastTriggerTime[channelID]) lastTriggerTime[channelID] = 0;
|
|
127
126
|
if (nowTime - lastTriggerTime[channelID] < 5000) return;
|
|
128
127
|
lastTriggerTime[channelID] = nowTime;
|
|
129
128
|
|
|
130
|
-
// ISTANZIAMO camAuth SULL'NVR: Risolve il problema delle credenziali vuote nel vecchio blocco
|
|
131
129
|
const camAuth = new AxiosDigestAuth({ username: node.user, password: node.pass });
|
|
132
130
|
|
|
133
131
|
const referenceTime = new Date();
|
|
134
132
|
const timestamp = Math.floor(referenceTime.getTime() / 1000);
|
|
135
|
-
|
|
136
|
-
const
|
|
133
|
+
|
|
134
|
+
const startTime = toHikDate(new Date(referenceTime.getTime() - (20 * 1000)));
|
|
135
|
+
const endTime = toHikDate(new Date(referenceTime.getTime() + (20 * 1000)));
|
|
137
136
|
|
|
138
137
|
node.status({fill:"yellow", shape:"dot", text:`Download Cam ${channelID}...`});
|
|
139
138
|
const nomeCamera = await getCameraName(channelID);
|
|
@@ -141,12 +140,20 @@ module.exports = function(RED) {
|
|
|
141
140
|
await new Promise(resolve => setTimeout(resolve, 6000));
|
|
142
141
|
const baseUrl = `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt`;
|
|
143
142
|
|
|
143
|
+
let eventoNVR = "FieldDetection";
|
|
144
|
+
for (let e of EventList) {
|
|
145
|
+
if (evento.toLowerCase() === e.toLowerCase()) {
|
|
146
|
+
eventoNVR = e;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
144
151
|
let output = {
|
|
145
152
|
tipo_messaggio: "evento",
|
|
146
153
|
nome_cliente: node.name,
|
|
147
154
|
nome_telecamera: nomeCamera,
|
|
148
155
|
ip_telecamera: node.host,
|
|
149
|
-
tipo_evento:
|
|
156
|
+
tipo_evento: eventoNVR,
|
|
150
157
|
timestamp_epoch: timestamp,
|
|
151
158
|
stato_telecamera: "ONLINE",
|
|
152
159
|
channel: channelID.toString(),
|
|
@@ -155,16 +162,19 @@ module.exports = function(RED) {
|
|
|
155
162
|
};
|
|
156
163
|
|
|
157
164
|
const parsedChannel = parseInt(channelID, 10);
|
|
158
|
-
const trackVideo = (parsedChannel * 100) + 1; //
|
|
159
|
-
const trackFoto = (parsedChannel * 100) + 3; //
|
|
165
|
+
const trackVideo = (parsedChannel * 100) + 1; // Canale 2 -> 201
|
|
166
|
+
const trackFoto = (parsedChannel * 100) + 3; // Canale 2 -> 203
|
|
160
167
|
|
|
161
|
-
const tracks = [
|
|
168
|
+
const tracks = [
|
|
169
|
+
{ id: trackVideo.toString(), isFoto: false },
|
|
170
|
+
{ id: trackFoto.toString(), isFoto: true }
|
|
171
|
+
];
|
|
162
172
|
let fileDaCancellare = [];
|
|
163
173
|
|
|
164
174
|
try {
|
|
165
175
|
for (let t of tracks) {
|
|
166
|
-
//
|
|
167
|
-
const searchXml = `<?xml version="1.0" encoding="utf-8"?><CMSearchDescription><searchID>LAST_EVENT</searchID><trackIDList><trackID>${t.id}</trackID></trackIDList><timeSpanList><timeSpan><startTime>${startTime}</startTime><endTime>${endTime}</endTime></timeSpan></timeSpanList><maxResults>
|
|
176
|
+
// FISSO: Logica XML clonata al 100% dal tuo ispeziona NVR reale
|
|
177
|
+
const searchXml = `<?xml version="1.0" encoding="utf-8"?><CMSearchDescription><searchID>LAST_EVENT</searchID><trackIDList><trackID>${t.id}</trackID></trackIDList><timeSpanList><timeSpan><startTime>${startTime}</startTime><endTime>${endTime}</endTime></timeSpan></timeSpanList><contentTypeList><contentType>metadata</contentType></contentTypeList><maxResults>30</maxResults><metadataList><metadataDescriptor>recordType.meta.hikvision.com/${eventoNVR}</metadataDescriptor></metadataList></CMSearchDescription>`;
|
|
168
178
|
|
|
169
179
|
const resSearch = await camAuth.request({
|
|
170
180
|
method: 'POST', url: `${baseUrl}/search`, data: searchXml, headers: { "Content-Type": "application/xml" }
|
|
@@ -183,14 +193,12 @@ module.exports = function(RED) {
|
|
|
183
193
|
});
|
|
184
194
|
|
|
185
195
|
let buffer = Buffer.from(resDown.data);
|
|
186
|
-
if (t.
|
|
187
|
-
// SALVA FOTO IN LOCALE
|
|
196
|
+
if (t.isFoto) {
|
|
188
197
|
const fullImgPath = path.join(baseStorage, `img_${timestamp}.jpg`);
|
|
189
198
|
fs.writeFileSync(fullImgPath, buffer);
|
|
190
199
|
output.foto_base64 = fs.readFileSync(fullImgPath, { encoding: 'base64' });
|
|
191
200
|
fileDaCancellare.push(fullImgPath);
|
|
192
201
|
} else {
|
|
193
|
-
// SALVA VIDEO IN LOCALE
|
|
194
202
|
if (buffer.slice(0, 4).toString() === 'IMKH') buffer = buffer.slice(40);
|
|
195
203
|
const rawPath = path.join(baseStorage, `raw_${timestamp}.mp4`);
|
|
196
204
|
const fixedPath = path.join(baseStorage, `hik_v_${channelID}_${timestamp}.mp4`);
|
|
@@ -245,9 +253,7 @@ module.exports = function(RED) {
|
|
|
245
253
|
if (chMatch) {
|
|
246
254
|
let ev = "Unknown";
|
|
247
255
|
for (let e of EventList) { if (data.includes(e.toLowerCase())) { ev = e; break; } }
|
|
248
|
-
|
|
249
|
-
if (ev === "Unknown") return; // Ignora heartbeat o altri eventi non mappati
|
|
250
|
-
|
|
256
|
+
if (ev === "Unknown") return;
|
|
251
257
|
downloadMedia(ev, chMatch[1]);
|
|
252
258
|
}
|
|
253
259
|
}
|