node-red-contrib-hik-media-buffer 1.1.138 → 1.1.140
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 +37 -9
- package/package.json +1 -1
package/hik-media-buffer.js
CHANGED
|
@@ -224,26 +224,54 @@ module.exports = function(RED) {
|
|
|
224
224
|
<playbackURI>${playbackURIXml}</playbackURI>
|
|
225
225
|
</downloadRequest>`;
|
|
226
226
|
|
|
227
|
-
node.warn(`[HIK DOWNLOAD] Invio Body XML:\n${payloadDownload}`);
|
|
227
|
+
node.warn(`[HIK DOWNLOAD] Invio Body XML (Stream Mode):\n${payloadDownload}`);
|
|
228
228
|
|
|
229
|
+
// 🌟 CAMBIAMENTO CHIAVE: Chiediamo un 'stream' invece di 'arraybuffer'
|
|
229
230
|
const resDownVideo = await nvrAuth.request({
|
|
230
231
|
method: 'GET',
|
|
231
232
|
url: `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt/download`,
|
|
232
233
|
data: payloadDownload,
|
|
233
234
|
headers: { "Content-Type": "application/xml" },
|
|
234
|
-
responseType: '
|
|
235
|
-
|
|
236
|
-
maxBodyLength: Infinity,
|
|
237
|
-
insecureHTTPParser: true,
|
|
235
|
+
responseType: 'stream',
|
|
236
|
+
insecureHTTPParser: true,
|
|
238
237
|
httpsAgent: node.protocol === "https" ? httpsAgent : undefined
|
|
239
238
|
});
|
|
240
239
|
|
|
241
|
-
let bufferVideo = Buffer.from(resDownVideo.data);
|
|
242
|
-
if (bufferVideo.slice(0, 4).toString() === 'IMKH') bufferVideo = bufferVideo.slice(40);
|
|
243
|
-
|
|
244
240
|
const rawPath = path.join(baseStorage, `raw_${timestamp}_ch${channelID}.mp4`);
|
|
245
241
|
const fixedPath = path.join(baseStorage, `hik_v_${channelID}_${timestamp}.mp4`);
|
|
246
|
-
|
|
242
|
+
|
|
243
|
+
const writer = fs.createWriteStream(rawPath);
|
|
244
|
+
|
|
245
|
+
resDownVideo.data.pipe(writer);
|
|
246
|
+
|
|
247
|
+
// 🌟 BLOCCO DI SICUREZZA: Aspettiamo la reale chiusura del flusso di rete dell'NVR
|
|
248
|
+
await new Promise((resolve, reject) => {
|
|
249
|
+
resDownVideo.data.on('end', () => {
|
|
250
|
+
setTimeout(() => {
|
|
251
|
+
writer.end();
|
|
252
|
+
resolve();
|
|
253
|
+
}, 500);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
resDownVideo.data.on('error', (err) => {
|
|
257
|
+
writer.end();
|
|
258
|
+
reject(err);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
writer.on('error', (err) => {
|
|
262
|
+
reject(err);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Leggiamo il file finale completo per controllare la testata IMKH
|
|
267
|
+
let videoBuffer = fs.readFileSync(rawPath);
|
|
268
|
+
if (videoBuffer.slice(0, 4).toString() === 'IMKH') {
|
|
269
|
+
videoBuffer = videoBuffer.slice(40);
|
|
270
|
+
fs.writeFileSync(rawPath, videoBuffer);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const stats = fs.statSync(rawPath);
|
|
274
|
+
node.warn(`[HIK DOWNLOAD OK] File scaricato. Dimensione: ${(stats.size / 1024).toFixed(1)} KB`);
|
|
247
275
|
|
|
248
276
|
await new Promise((resolve) => {
|
|
249
277
|
exec(`ffmpeg -y -i "${rawPath}" -c copy -movflags +faststart "${fixedPath}"`, (err) => {
|