node-red-contrib-hik-media-buffer 1.2.6 → 1.2.8

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-download.js CHANGED
@@ -62,25 +62,45 @@ module.exports = function(RED) {
62
62
  return;
63
63
  }
64
64
 
65
- // Pulizia date per l'NVR
66
- const pulisciDataNVR = (dataStr) => {
67
- let d = dataStr.replace(' ', 'T');
68
- d = d.replace(/[-:]/g, '')
69
- .split('.')[0]
70
- .replace('Z', '');
71
-
72
- if (d.includes('T') && d.split('T')[1].length === 4) {
73
- d += '00';
74
- }
75
- return d;
76
- };
65
+ // 🌟 1. FORMATTAZIONE DELLE DATE IN BASE ALLA PORTA (Bivio Logico)
66
+ let startTimeNVR, endTimeNVR, playbackURIGrezzo, payloadDownload;
67
+
68
+ const isPort85 = (port.toString() === "85");
69
+
70
+ if (isPort85) {
71
+ // Formato specifico DVR Porta 85: AAAA-MM-GGTHH:MM:SS (Senza Z, con trattini e due punti)
72
+ const formattaDataDVR = (dataStr) => {
73
+ let d = dataStr.replace(' ', 'T').split('.')[0].replace('Z', '');
74
+ if (d.includes('T') && d.split('T')[1].length === 5) {
75
+ d += ':00';
76
+ }
77
+ return d;
78
+ };
79
+ startTimeNVR = formattaDataDVR(startTimeRaw);
80
+ endTimeNVR = formattaDataDVR(endTimeRaw);
81
+
82
+ // RTSP con porta e XML senza namespace
83
+ const trackId = targetChannels[0] + "01"; // Default temporaneo per comporre l'URI prima del ciclo
84
+ playbackURIGrezzo = `rtsp://${host}:${port}/Streaming/tracks/TRACK_PLACEHOLDER/?starttime=${startTimeNVR}&endtime=${endTimeNVR}`;
85
+ } else {
86
+ // Formato classico NVR (Senza trattini e senza due punti)
87
+ const pulisciDataNVR = (dataStr) => {
88
+ let d = dataStr.replace(' ', 'T').replace(/[-:]/g, '').split('.')[0].replace('Z', '');
89
+ if (d.includes('T') && d.split('T')[1].length === 4) {
90
+ d += '00';
91
+ }
92
+ return d;
93
+ };
94
+ startTimeNVR = pulisciDataNVR(startTimeRaw);
95
+ endTimeNVR = pulisciDataNVR(endTimeRaw);
77
96
 
78
- const startTimeNVR = pulisciDataNVR(startTimeRaw);
79
- const endTimeNVR = pulisciDataNVR(endTimeRaw);
97
+ // RTSP senza porta
98
+ playbackURIGrezzo = `rtsp://${host}/Streaming/tracks/TRACK_PLACEHOLDER/?starttime=${startTimeNVR}&endtime=${endTimeNVR}`;
99
+ }
80
100
 
81
- // Creazione cartella C:\download\YYYY-MM-DD
101
+ // Creazione cartella di salvataggio C:\download\YYYY-MM-DD
82
102
  const dataGiorno = startTimeRaw.substring(0, 10).replace(/\//g, '-');
83
- const baseDir = "C:\\download";
103
+ const baseDir = process.platform === "win32" ? "C:\\download" : "/home/allsystem/download";
84
104
  const targetDir = path.join(baseDir, dataGiorno);
85
105
 
86
106
  try {
@@ -95,6 +115,7 @@ module.exports = function(RED) {
95
115
 
96
116
  const digest = new DigestAuthClass({ username: user, password: pass });
97
117
 
118
+ // 🌟 2. CICLO DI DOWNLOAD
98
119
  for (let index = 0; index < targetChannels.length; index++) {
99
120
  const ch = targetChannels[index];
100
121
  const trackId = ch + "01";
@@ -105,17 +126,24 @@ module.exports = function(RED) {
105
126
  text: `Download Ch ${ch} (${index + 1}/${targetChannels.length})...`
106
127
  });
107
128
 
108
- // 🌟 1. GENERIAMO L'URI DI PLAYBACK ESATTAMENTE COME RICHIESTO
109
- const playbackURIGrezzo = `rtsp://${host}:${port}/Streaming/tracks/${trackId}/?starttime=${startTimeNVR}&endtime=${endTimeNVR}`;
110
- const playbackURIXml = playbackURIGrezzo.replace(/&/g, '&amp;');
129
+ // Sostituiamo il placeholder con la traccia corrente del ciclo
130
+ const uriCorrente = playbackURIGrezzo.replace('TRACK_PLACEHOLDER', trackId);
131
+ const playbackURIXml = uriCorrente.replace(/&/g, '&amp;');
111
132
 
112
- const payloadDownload = `<?xml version="1.0" encoding="UTF-8"?>
113
- <downloadRequest>
114
- <playbackURI>${playbackURIXml}</playbackURI>
115
- </downloadRequest>`;
133
+ // Costruiamo l'XML a seconda del tipo di macchina
134
+ if (isPort85) {
135
+ payloadDownload = `<?xml version="1.0" encoding="UTF-8"?>
136
+ <downloadRequest>
137
+ <playbackURI>${playbackURIXml}</playbackURI>
138
+ </downloadRequest>`;
139
+ } else {
140
+ payloadDownload = `<?xml version="1.0" encoding="UTF-8"?>
141
+ <downloadRequest version="1.0" xmlns="http://www.isapi.org/ver20/XMLSchema">
142
+ <playbackURI>${playbackURIXml}</playbackURI>
143
+ </downloadRequest>`;
144
+ }
116
145
 
117
146
  try {
118
- // 🌟 2. GET DI DOWNLOAD CON PAYLOAD XML E RESPONSE 'STREAM'
119
147
  const response = await digest.request({
120
148
  method: 'GET',
121
149
  url: `${protocol}://${host}:${port}/ISAPI/ContentMgmt/download`,
@@ -130,11 +158,17 @@ module.exports = function(RED) {
130
158
  if (response.status === 200 || response.status === 206) {
131
159
  const nomeCondominio = (msg.nvr_name || node.name || 'NVR').replace(/[^a-zA-Z0-9]/g, '_');
132
160
  const oraInizio = startTimeNVR.split('T')[1] || startTimeNVR;
133
- const finalFileName = `${nomeCondominio}_Cam${ch}_${oraInizio}.mp4`;
161
+ const finalFileName = `${nomeCondominio}_Cam${ch}_${oraInizio.replace(/:/g, '')}.mp4`;
134
162
  const finalFilePath = path.join(targetDir, finalFileName);
135
163
 
136
- // 🌟 3. SALVATAGGIO TRAMITE STREAM (Ottimizzato per file grandi)
137
164
  const writer = fs.createWriteStream(finalFilePath);
165
+ const videoChunks = [];
166
+
167
+ // Ascoltiamo i dati in arrivo dallo stream per salvarli anche in memoria
168
+ response.data.on('data', (chunk) => {
169
+ videoChunks.push(chunk);
170
+ });
171
+
138
172
  response.data.pipe(writer);
139
173
 
140
174
  await new Promise((resolve, reject) => {
@@ -147,8 +181,11 @@ module.exports = function(RED) {
147
181
 
148
182
  node.log(`File salvato in: ${finalFilePath}`);
149
183
 
184
+ const videoBuffer = Buffer.concat(videoChunks);
185
+
150
186
  let outMsg = RED.util.cloneMessage(msg);
151
- outMsg.payload = finalFilePath;
187
+ outMsg.payload = videoBuffer;
188
+ outMsg.localFilePath = finalFilePath;
152
189
  outMsg.channel = ch;
153
190
  outMsg.filename = finalFileName;
154
191
  node.send(outMsg);
@@ -213,7 +213,7 @@ module.exports = function(RED) {
213
213
 
214
214
  playbackURIGrezzo = `rtsp://${node.host}:${node.port}/Streaming/tracks/${videoTrackID}/?starttime=${startClip}&endtime=${endClip}`;
215
215
  }
216
- }
216
+ }hik
217
217
 
218
218
  // 3. 💾 EFFETTUIAMO LA GET DI DOWNLOAD SE ABBIAMO GENERATO L'URI
219
219
  if (playbackURIGrezzo) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-hik-media-buffer",
3
- "version": "1.2.6",
3
+ "version": "1.2.8",
4
4
  "description": "Ottiene buffer video e immagine da camere Hikvision via ISAPI",
5
5
  "keywords": [
6
6
  "node-red",