dashcam 1.3.27 → 1.3.29
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/bin/dashcam-background.js +2 -2
- package/bin/dashcam.js +48 -21
- package/lib/processManager.js +14 -17
- package/package.json +1 -1
|
@@ -217,7 +217,7 @@ async function runBackgroundRecording() {
|
|
|
217
217
|
process.on('SIGINT', () => handleShutdown('SIGINT'));
|
|
218
218
|
process.on('SIGTERM', () => handleShutdown('SIGTERM'));
|
|
219
219
|
|
|
220
|
-
// Keep the process alive - wait indefinitely for
|
|
220
|
+
// Keep the process alive - wait indefinitely for SIGKILL from stop command
|
|
221
221
|
logger.info('Background recording is now running. Waiting for stop signal...');
|
|
222
222
|
console.log('[Background] Waiting for stop signal...');
|
|
223
223
|
|
|
@@ -235,7 +235,7 @@ async function runBackgroundRecording() {
|
|
|
235
235
|
process.exit(1);
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
-
// Infinite loop - process will only exit via signal handlers
|
|
238
|
+
// Infinite loop - process will only exit via signal handlers or stop file
|
|
239
239
|
await new Promise(() => {});
|
|
240
240
|
}
|
|
241
241
|
|
package/bin/dashcam.js
CHANGED
|
@@ -469,36 +469,63 @@ program
|
|
|
469
469
|
console.log('Recording stopped successfully');
|
|
470
470
|
logger.debug('Stop result:', result);
|
|
471
471
|
|
|
472
|
-
//
|
|
473
|
-
|
|
474
|
-
|
|
472
|
+
// Reconstruct recording data from status and fix video with FFmpeg
|
|
473
|
+
console.log('Processing recording...');
|
|
474
|
+
logger.debug('Reconstructing recording data from status file');
|
|
475
475
|
|
|
476
|
-
|
|
477
|
-
const
|
|
478
|
-
const
|
|
479
|
-
let recordingResult = null;
|
|
480
|
-
let checkCount = 0;
|
|
476
|
+
const { fixVideoContainer } = await import('../lib/recorder.js');
|
|
477
|
+
const { applicationTracker } = await import('../lib/applicationTracker.js');
|
|
478
|
+
const { logsTrackerManager } = await import('../lib/logs/index.js');
|
|
481
479
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
480
|
+
// Get temp file path
|
|
481
|
+
const tempFileInfoPath = path.join(os.tmpdir(), 'dashcam', 'temp-file.json');
|
|
482
|
+
let tempFileInfo = null;
|
|
483
|
+
try {
|
|
484
|
+
tempFileInfo = JSON.parse(fs.readFileSync(tempFileInfoPath, 'utf8'));
|
|
485
|
+
} catch (error) {
|
|
486
|
+
logger.error('Failed to read temp file info', { error });
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const tempFile = tempFileInfo?.tempFile || result.outputPath.replace('.webm', '-temp.webm');
|
|
490
|
+
const outputPath = result.outputPath;
|
|
491
|
+
|
|
492
|
+
// Fix the video with FFmpeg (handle incomplete recordings)
|
|
493
|
+
logger.info('Fixing video with FFmpeg', { tempFile, outputPath });
|
|
494
|
+
if (fs.existsSync(tempFile)) {
|
|
495
|
+
try {
|
|
496
|
+
await fixVideoContainer(tempFile, outputPath);
|
|
497
|
+
logger.info('Video fixed successfully');
|
|
498
|
+
} catch (error) {
|
|
499
|
+
logger.warn('FFmpeg fix failed, using temp file as-is', { error: error.message });
|
|
500
|
+
// If fix fails, just copy the temp file
|
|
501
|
+
fs.copyFileSync(tempFile, outputPath);
|
|
492
502
|
}
|
|
503
|
+
} else {
|
|
504
|
+
logger.warn('Temp file not found, using output path directly', { tempFile });
|
|
493
505
|
}
|
|
494
506
|
|
|
507
|
+
// Collect application and log data
|
|
508
|
+
const apps = await applicationTracker.getApps(activeStatus.startTime);
|
|
509
|
+
const logs = await logsTrackerManager.getLogsForRecording();
|
|
510
|
+
|
|
511
|
+
const recordingResult = {
|
|
512
|
+
outputPath,
|
|
513
|
+
duration: result.duration,
|
|
514
|
+
clientStartDate: activeStatus.startTime,
|
|
515
|
+
apps,
|
|
516
|
+
logs,
|
|
517
|
+
title: activeStatus?.options?.title,
|
|
518
|
+
description: activeStatus?.options?.description,
|
|
519
|
+
project: activeStatus?.options?.project
|
|
520
|
+
};
|
|
521
|
+
|
|
495
522
|
if (!recordingResult || !recordingResult.outputPath) {
|
|
496
|
-
console.error('Failed to
|
|
497
|
-
logger.error('No recording result
|
|
523
|
+
console.error('Failed to process recording');
|
|
524
|
+
logger.error('No recording result', { recordingResult });
|
|
498
525
|
process.exit(1);
|
|
499
526
|
}
|
|
500
527
|
|
|
501
|
-
console.log('
|
|
528
|
+
console.log('Uploading recording...');
|
|
502
529
|
logger.debug('Recording result:', recordingResult);
|
|
503
530
|
|
|
504
531
|
try {
|
package/lib/processManager.js
CHANGED
|
@@ -11,7 +11,7 @@ const __dirname = path.dirname(__filename);
|
|
|
11
11
|
// Use user home directory for cross-session communication
|
|
12
12
|
const PROCESS_DIR = path.join(os.homedir(), '.dashcam-cli');
|
|
13
13
|
const STATUS_FILE = path.join(PROCESS_DIR, 'status.json');
|
|
14
|
-
const
|
|
14
|
+
const RECORDING_RESULT_FILE = path.join(PROCESS_DIR, 'recording-result.json');
|
|
15
15
|
|
|
16
16
|
console.log('[INIT] Process Manager initialized');
|
|
17
17
|
console.log('[INIT] Process directory:', PROCESS_DIR);
|
|
@@ -281,36 +281,33 @@ class ProcessManager {
|
|
|
281
281
|
return false;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
-
logger.info('
|
|
284
|
+
logger.info('Killing background process', { pid });
|
|
285
285
|
|
|
286
|
-
//
|
|
286
|
+
// Kill the process immediately - no graceful shutdown needed
|
|
287
|
+
// Video is already being streamed to disk, we'll fix it with FFmpeg
|
|
287
288
|
try {
|
|
288
|
-
process.kill(pid, '
|
|
289
|
-
logger.info('Sent
|
|
289
|
+
process.kill(pid, 'SIGKILL');
|
|
290
|
+
logger.info('Sent SIGKILL to background process');
|
|
290
291
|
} catch (error) {
|
|
291
|
-
logger.error('Failed to
|
|
292
|
+
logger.error('Failed to kill background process', { error });
|
|
292
293
|
throw new Error('Failed to stop background recording process');
|
|
293
294
|
}
|
|
294
295
|
|
|
295
|
-
// Wait for
|
|
296
|
-
logger.debug('Waiting for background process to
|
|
297
|
-
const maxWaitTime =
|
|
296
|
+
// Wait briefly for process to die
|
|
297
|
+
logger.debug('Waiting for background process to exit...');
|
|
298
|
+
const maxWaitTime = 5000; // 5 seconds should be plenty for SIGKILL
|
|
298
299
|
const startWait = Date.now();
|
|
299
300
|
|
|
300
301
|
while (this.isProcessRunning(pid) && (Date.now() - startWait) < maxWaitTime) {
|
|
301
|
-
await new Promise(resolve => setTimeout(resolve,
|
|
302
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
302
303
|
}
|
|
303
304
|
|
|
304
305
|
if (this.isProcessRunning(pid)) {
|
|
305
|
-
logger.error('Background process did not exit
|
|
306
|
-
|
|
307
|
-
process.kill(pid, 'SIGKILL');
|
|
308
|
-
} catch (error) {
|
|
309
|
-
logger.error('Failed to force kill background process', { error });
|
|
310
|
-
}
|
|
306
|
+
logger.error('Background process did not exit after SIGKILL');
|
|
307
|
+
throw new Error('Failed to kill background process');
|
|
311
308
|
}
|
|
312
309
|
|
|
313
|
-
logger.info('Background process
|
|
310
|
+
logger.info('Background process killed');
|
|
314
311
|
|
|
315
312
|
// Mark status as completed
|
|
316
313
|
this.markStatusCompleted({
|