node-red-contrib-hik-media-buffer 1.1.90 → 1.1.91
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 +20 -6
- package/package.json +1 -1
package/hik-media-buffer.js
CHANGED
|
@@ -144,14 +144,19 @@ module.exports = function(RED) {
|
|
|
144
144
|
searchXml = `<?xml version="1.0" encoding="utf-8"?><CMSearchDescription><searchID>23D1C3CB-8C68-41C0-8A89-2BCF5765B5D2</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><searchResultPostion>0</searchResultPostion><metadataList><metadataDescriptor>recordType.meta.hikvision.com/${evento}</metadataDescriptor></metadataList></CMSearchDescription>`.trim();
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
//
|
|
147
|
+
// Salviamo l'XML su un file temporaneo per non far incazzare la shell con i caratteri < e >
|
|
148
|
+
const tempXmlPath = path.join(baseStorage, `search_${t.id}_${timestamp}.xml`);
|
|
149
|
+
fs.writeFileSync(tempXmlPath, searchXml, 'utf8');
|
|
150
|
+
|
|
151
|
+
node.warn(`[DEBUG] Eseguo ricerca traccia ${t.id} tramite cURL via file temporaneo...`);
|
|
152
|
+
|
|
153
|
+
// Usiamo -d "@path" così cURL si legge il file da solo senza passare i simboli alla shell
|
|
148
154
|
const targetUrl = `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt/search`;
|
|
149
|
-
const curlCommand = `curl -s -X POST --digest -u "${node.user}:${node.pass}" -H "Content-Type: application/xml; charset=UTF-8" -d
|
|
155
|
+
const curlCommand = `curl -s -X POST --digest -u "${node.user}:${node.pass}" -H "Content-Type: application/xml; charset=UTF-8" -d "@${tempXmlPath}" "${targetUrl}"`;
|
|
150
156
|
|
|
151
157
|
let xmlResponse = await new Promise((resolve) => {
|
|
152
158
|
exec(curlCommand, (err, stdout, stderr) => {
|
|
153
159
|
if (err) {
|
|
154
|
-
// STAMPIAMO IL VERO ERRORE DI LINUX/MIKROTIK
|
|
155
160
|
node.error(`[CRASH cURL]: ${err.message} | STDERR: ${stderr}`);
|
|
156
161
|
resolve(null);
|
|
157
162
|
} else {
|
|
@@ -160,7 +165,9 @@ module.exports = function(RED) {
|
|
|
160
165
|
});
|
|
161
166
|
});
|
|
162
167
|
|
|
163
|
-
//
|
|
168
|
+
// Cancelliamo subito il file XML temporaneo di ricerca
|
|
169
|
+
try { if (fs.existsSync(tempXmlPath)) fs.unlinkSync(tempXmlPath); } catch(e){}
|
|
170
|
+
|
|
164
171
|
node.warn(`[DEBUG NVR RESP] Risposta grezza per traccia ${t.id}:`);
|
|
165
172
|
node.warn(xmlResponse);
|
|
166
173
|
|
|
@@ -176,18 +183,25 @@ module.exports = function(RED) {
|
|
|
176
183
|
const rawUri = uriMatch[1].replace(/&/g, '&');
|
|
177
184
|
const downXml = `<?xml version="1.0" encoding="UTF-8"?><downloadRequest><playbackURI>${rawUri.replace(/&/g, '&')}</playbackURI></downloadRequest>`.trim();
|
|
178
185
|
|
|
186
|
+
// Facciamo lo stesso giochetto del file temporaneo anche per il download
|
|
187
|
+
const tempDownXmlPath = path.join(baseStorage, `down_${t.id}_${timestamp}.xml`);
|
|
188
|
+
fs.writeFileSync(tempDownXmlPath, downXml, 'utf8');
|
|
189
|
+
|
|
179
190
|
const fullImgPath = path.join(baseStorage, `img_${timestamp}.jpg`);
|
|
180
191
|
const rawPath = path.join(baseStorage, `raw_${timestamp}.mp4`);
|
|
181
192
|
const targetFilePath = (t.id === trackI) ? fullImgPath : rawPath;
|
|
182
193
|
|
|
183
|
-
// cURL gestisce anche il download binario immenso salvando direttamente su file (-o)
|
|
184
194
|
const downUrl = `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt/download`;
|
|
185
|
-
const curlDownCommand = `curl -s -X POST --digest -u "${node.user}:${node.pass}" -H "Content-Type: application/xml; charset=UTF-8" -d
|
|
195
|
+
const curlDownCommand = `curl -s -X POST --digest -u "${node.user}:${node.pass}" -H "Content-Type: application/xml; charset=UTF-8" -d "@${tempDownXmlPath}" "${downUrl}" -o "${targetFilePath}"`;
|
|
186
196
|
|
|
197
|
+
node.warn(`[DEBUG] Eseguo download traccia ${t.id} tramite cURL via file temporaneo...`);
|
|
187
198
|
await new Promise((resolve) => {
|
|
188
199
|
exec(curlDownCommand, () => resolve());
|
|
189
200
|
});
|
|
190
201
|
|
|
202
|
+
// Cancelliamo il file XML del download
|
|
203
|
+
try { if (fs.existsSync(tempDownXmlPath)) fs.unlinkSync(tempDownXmlPath); } catch(e){}
|
|
204
|
+
|
|
191
205
|
if (fs.existsSync(targetFilePath) && fs.statSync(targetFilePath).size > 0) {
|
|
192
206
|
if (t.id === trackI) {
|
|
193
207
|
output.foto_base64 = fs.readFileSync(fullImgPath, { encoding: 'base64' });
|