node-red-contrib-hik-media-buffer 1.1.138 → 1.1.139
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 +23 -10
- package/package.json +1 -1
package/hik-media-buffer.js
CHANGED
|
@@ -216,6 +216,7 @@ module.exports = function(RED) {
|
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
// 3. 💾 EFFETTUIAMO LA GET DI DOWNLOAD SE ABBIAMO GENERATO L'URI
|
|
219
|
+
// 3. 💾 EFFETTUIAMO LA GET DI DOWNLOAD CON VALUTAZIONE STREAM (Evita i Parse Error)
|
|
219
220
|
if (playbackURIGrezzo) {
|
|
220
221
|
const playbackURIXml = playbackURIGrezzo.replace(/&/g, '&');
|
|
221
222
|
|
|
@@ -224,26 +225,38 @@ module.exports = function(RED) {
|
|
|
224
225
|
<playbackURI>${playbackURIXml}</playbackURI>
|
|
225
226
|
</downloadRequest>`;
|
|
226
227
|
|
|
227
|
-
node.warn(`[HIK DOWNLOAD] Invio Body XML:\n${payloadDownload}`);
|
|
228
|
+
node.warn(`[HIK DOWNLOAD] Invio Body XML (Stream Mode):\n${payloadDownload}`);
|
|
228
229
|
|
|
230
|
+
// 🌟 CAMBIAMENTO CHIAVE: Chiediamo un 'stream' invece di 'arraybuffer'
|
|
229
231
|
const resDownVideo = await nvrAuth.request({
|
|
230
232
|
method: 'GET',
|
|
231
233
|
url: `${node.protocol}://${node.host}:${node.port}/ISAPI/ContentMgmt/download`,
|
|
232
234
|
data: payloadDownload,
|
|
233
235
|
headers: { "Content-Type": "application/xml" },
|
|
234
|
-
responseType: '
|
|
235
|
-
|
|
236
|
-
maxBodyLength: Infinity,
|
|
237
|
-
insecureHTTPParser: true,
|
|
236
|
+
responseType: 'stream',
|
|
237
|
+
insecureHTTPParser: true,
|
|
238
238
|
httpsAgent: node.protocol === "https" ? httpsAgent : undefined
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
-
let bufferVideo = Buffer.from(resDownVideo.data);
|
|
242
|
-
if (bufferVideo.slice(0, 4).toString() === 'IMKH') bufferVideo = bufferVideo.slice(40);
|
|
243
|
-
|
|
244
241
|
const rawPath = path.join(baseStorage, `raw_${timestamp}_ch${channelID}.mp4`);
|
|
245
242
|
const fixedPath = path.join(baseStorage, `hik_v_${channelID}_${timestamp}.mp4`);
|
|
246
|
-
|
|
243
|
+
|
|
244
|
+
// Usiamo un WriteStream per salvare i byte man mano che arrivano dalla rete
|
|
245
|
+
const writer = fs.createWriteStream(rawPath);
|
|
246
|
+
resDownVideo.data.pipe(writer);
|
|
247
|
+
|
|
248
|
+
await new Promise((resolve, reject) => {
|
|
249
|
+
writer.on('finish', resolve);
|
|
250
|
+
writer.on('error', reject);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// Una volta finito di scrivere il file grezzo, controlliamo la testata IMKH e passiamo a FFMPEG
|
|
254
|
+
let videoBuffer = fs.readFileSync(rawPath);
|
|
255
|
+
if (videoBuffer.slice(0, 4).toString() === 'IMKH') {
|
|
256
|
+
// Rimuoviamo i 40 byte di intestazione proprietaria Hikvision se presenti
|
|
257
|
+
videoBuffer = videoBuffer.slice(40);
|
|
258
|
+
fs.writeFileSync(rawPath, videoBuffer);
|
|
259
|
+
}
|
|
247
260
|
|
|
248
261
|
await new Promise((resolve) => {
|
|
249
262
|
exec(`ffmpeg -y -i "${rawPath}" -c copy -movflags +faststart "${fixedPath}"`, (err) => {
|
|
@@ -258,7 +271,7 @@ module.exports = function(RED) {
|
|
|
258
271
|
});
|
|
259
272
|
});
|
|
260
273
|
}
|
|
261
|
-
|
|
274
|
+
|
|
262
275
|
if (output.foto_base64 || output.video_base64) {
|
|
263
276
|
node.send({ payload: output });
|
|
264
277
|
setTimeout(() => {
|