@hexar/biometric-identity-sdk-react-native 1.0.10 → 1.0.11
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAGlI,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,iCAAiC;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAGlI,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,iCAAiC;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAqyBtD,CAAC;AA4OF,eAAe,aAAa,CAAC"}
|
|
@@ -116,6 +116,7 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
116
116
|
const frameCaptureInterval = (0, react_1.useRef)(null);
|
|
117
117
|
const videoRecordingRef = (0, react_1.useRef)(null);
|
|
118
118
|
const isRecordingRef = (0, react_1.useRef)(false);
|
|
119
|
+
const recordingTimeoutRef = (0, react_1.useRef)(null);
|
|
119
120
|
const minDurationMs = 8000;
|
|
120
121
|
const totalDuration = duration || Math.max(minDurationMs, challenges.reduce((sum, c) => sum + c.duration_ms, 0) + 2000);
|
|
121
122
|
// Check camera permissions
|
|
@@ -369,14 +370,24 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
369
370
|
}
|
|
370
371
|
}, [device]);
|
|
371
372
|
const stopRecording = (0, react_1.useCallback)(async () => {
|
|
372
|
-
console.log('
|
|
373
|
+
console.log('stopRecording called, isRecording:', isRecordingRef.current);
|
|
374
|
+
// Clear any pending timeouts
|
|
375
|
+
if (recordingTimeoutRef.current) {
|
|
376
|
+
clearTimeout(recordingTimeoutRef.current);
|
|
377
|
+
recordingTimeoutRef.current = null;
|
|
378
|
+
}
|
|
373
379
|
if (frameCaptureInterval.current) {
|
|
374
380
|
clearInterval(frameCaptureInterval.current);
|
|
375
381
|
frameCaptureInterval.current = null;
|
|
376
382
|
}
|
|
383
|
+
// Prevent multiple calls
|
|
384
|
+
if (!isRecordingRef.current) {
|
|
385
|
+
console.log('Recording already stopped, ignoring');
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
377
388
|
if (videoRecordingRef.current) {
|
|
378
389
|
try {
|
|
379
|
-
console.log('Stopping video recording');
|
|
390
|
+
console.log('Stopping video recording, current ref:', !!videoRecordingRef.current);
|
|
380
391
|
const recording = videoRecordingRef.current;
|
|
381
392
|
videoRecordingRef.current = null;
|
|
382
393
|
isRecordingRef.current = false;
|
|
@@ -387,6 +398,7 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
387
398
|
console.error('Error stopping video recording:', error);
|
|
388
399
|
isRecordingRef.current = false;
|
|
389
400
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
401
|
+
console.log('Error duration check:', actualDuration, 'minDurationMs:', minDurationMs, 'frames:', frames.length);
|
|
390
402
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
391
403
|
console.log('Video stopped with error, using captured frames');
|
|
392
404
|
const result = {
|
|
@@ -402,29 +414,39 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
402
414
|
}
|
|
403
415
|
}
|
|
404
416
|
else {
|
|
417
|
+
console.log('No video recording ref, just setting flag to false');
|
|
405
418
|
isRecordingRef.current = false;
|
|
406
419
|
}
|
|
407
420
|
}, [frames, completedChallenges, challenges, sessionId, onComplete, minDurationMs]);
|
|
408
421
|
const runChallenge = (0, react_1.useCallback)((index) => {
|
|
409
422
|
if (index >= challenges.length) {
|
|
410
|
-
console.log('All challenges completed,
|
|
423
|
+
console.log('All challenges completed, checking duration');
|
|
411
424
|
setOverallProgress(100);
|
|
425
|
+
// Clear the totalDuration timeout since we're handling it manually
|
|
426
|
+
if (recordingTimeoutRef.current) {
|
|
427
|
+
clearTimeout(recordingTimeoutRef.current);
|
|
428
|
+
recordingTimeoutRef.current = null;
|
|
429
|
+
console.log('Cleared totalDuration timeout');
|
|
430
|
+
}
|
|
412
431
|
if (isRecordingRef.current) {
|
|
413
432
|
const elapsed = Date.now() - recordingStartTime.current;
|
|
414
433
|
console.log('Checking duration - Elapsed:', (elapsed / 1000).toFixed(1), 's, Min required:', (minDurationMs / 1000).toFixed(1), 's');
|
|
415
434
|
if (elapsed < minDurationMs) {
|
|
416
435
|
const remaining = minDurationMs - elapsed;
|
|
417
436
|
console.log('Waiting additional', (remaining / 1000).toFixed(1), 's to meet minimum duration');
|
|
418
|
-
setTimeout(() => {
|
|
437
|
+
recordingTimeoutRef.current = setTimeout(() => {
|
|
438
|
+
console.log('Minimum duration wait completed, stopping recording');
|
|
419
439
|
if (isRecordingRef.current) {
|
|
420
440
|
stopRecording();
|
|
421
441
|
}
|
|
422
442
|
}, remaining);
|
|
423
443
|
return;
|
|
424
444
|
}
|
|
445
|
+
console.log('Duration requirement met, stopping immediately');
|
|
425
446
|
stopRecording();
|
|
426
447
|
}
|
|
427
448
|
else {
|
|
449
|
+
console.log('Recording already stopped, checking if we can complete');
|
|
428
450
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
429
451
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
430
452
|
console.log('Recording already stopped, completing with frames');
|
|
@@ -489,8 +511,15 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
489
511
|
videoRecordingRef.current = await cameraRef.current.startRecording({
|
|
490
512
|
flash: 'off',
|
|
491
513
|
onRecordingFinished: (video) => {
|
|
492
|
-
console.log('Video recording finished callback called, path:', video?.path || 'N/A');
|
|
493
|
-
|
|
514
|
+
console.log('Video recording finished callback called, path:', video?.path || 'N/A', 'phase:', phase);
|
|
515
|
+
// Ensure we're in the right state to process
|
|
516
|
+
if (phase === 'recording' || phase === 'processing') {
|
|
517
|
+
handleVideoComplete(video);
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
console.warn('Received onRecordingFinished but phase is', phase, '- calling handleVideoComplete anyway');
|
|
521
|
+
handleVideoComplete(video);
|
|
522
|
+
}
|
|
494
523
|
},
|
|
495
524
|
onRecordingError: (error) => {
|
|
496
525
|
console.error('Recording error:', error);
|
|
@@ -509,16 +538,24 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
509
538
|
startFrameCapture();
|
|
510
539
|
}
|
|
511
540
|
runChallenge(0);
|
|
512
|
-
|
|
513
|
-
|
|
541
|
+
// Set a safety timeout that's longer than totalDuration to ensure we stop eventually
|
|
542
|
+
// This will be cleared if challenges complete early
|
|
543
|
+
const maxDuration = Math.max(totalDuration, minDurationMs + 2000); // Add 2s buffer
|
|
544
|
+
recordingTimeoutRef.current = setTimeout(() => {
|
|
545
|
+
console.log('Safety timeout reached (max duration), stopping recording');
|
|
514
546
|
if (isRecordingRef.current) {
|
|
515
547
|
stopRecording().catch(err => {
|
|
516
|
-
console.error('Error stopping recording on timeout:', err);
|
|
548
|
+
console.error('Error stopping recording on safety timeout:', err);
|
|
517
549
|
});
|
|
518
550
|
}
|
|
519
|
-
},
|
|
520
|
-
return () =>
|
|
521
|
-
|
|
551
|
+
}, maxDuration);
|
|
552
|
+
return () => {
|
|
553
|
+
if (recordingTimeoutRef.current) {
|
|
554
|
+
clearTimeout(recordingTimeoutRef.current);
|
|
555
|
+
recordingTimeoutRef.current = null;
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
}, [device, totalDuration, minDurationMs, handleVideoComplete, handleRecordingError, runChallenge, stopRecording, startFrameCapture]);
|
|
522
559
|
// Current challenge
|
|
523
560
|
const currentChallenge = challenges[currentChallengeIndex];
|
|
524
561
|
// Get direction arrow for the current challenge
|
package/package.json
CHANGED
|
@@ -147,6 +147,7 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
147
147
|
const frameCaptureInterval = useRef<NodeJS.Timeout | null>(null);
|
|
148
148
|
const videoRecordingRef = useRef<any>(null);
|
|
149
149
|
const isRecordingRef = useRef<boolean>(false);
|
|
150
|
+
const recordingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
150
151
|
const minDurationMs = 8000;
|
|
151
152
|
const totalDuration = duration || Math.max(
|
|
152
153
|
minDurationMs,
|
|
@@ -436,16 +437,28 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
436
437
|
}, [device]);
|
|
437
438
|
|
|
438
439
|
const stopRecording = useCallback(async () => {
|
|
439
|
-
console.log('
|
|
440
|
+
console.log('stopRecording called, isRecording:', isRecordingRef.current);
|
|
441
|
+
|
|
442
|
+
// Clear any pending timeouts
|
|
443
|
+
if (recordingTimeoutRef.current) {
|
|
444
|
+
clearTimeout(recordingTimeoutRef.current);
|
|
445
|
+
recordingTimeoutRef.current = null;
|
|
446
|
+
}
|
|
440
447
|
|
|
441
448
|
if (frameCaptureInterval.current) {
|
|
442
449
|
clearInterval(frameCaptureInterval.current);
|
|
443
450
|
frameCaptureInterval.current = null;
|
|
444
451
|
}
|
|
445
452
|
|
|
453
|
+
// Prevent multiple calls
|
|
454
|
+
if (!isRecordingRef.current) {
|
|
455
|
+
console.log('Recording already stopped, ignoring');
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
|
|
446
459
|
if (videoRecordingRef.current) {
|
|
447
460
|
try {
|
|
448
|
-
console.log('Stopping video recording');
|
|
461
|
+
console.log('Stopping video recording, current ref:', !!videoRecordingRef.current);
|
|
449
462
|
const recording = videoRecordingRef.current;
|
|
450
463
|
videoRecordingRef.current = null;
|
|
451
464
|
isRecordingRef.current = false;
|
|
@@ -457,6 +470,7 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
457
470
|
isRecordingRef.current = false;
|
|
458
471
|
|
|
459
472
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
473
|
+
console.log('Error duration check:', actualDuration, 'minDurationMs:', minDurationMs, 'frames:', frames.length);
|
|
460
474
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
461
475
|
console.log('Video stopped with error, using captured frames');
|
|
462
476
|
const result: VideoRecordingResult = {
|
|
@@ -471,15 +485,23 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
471
485
|
}
|
|
472
486
|
}
|
|
473
487
|
} else {
|
|
488
|
+
console.log('No video recording ref, just setting flag to false');
|
|
474
489
|
isRecordingRef.current = false;
|
|
475
490
|
}
|
|
476
491
|
}, [frames, completedChallenges, challenges, sessionId, onComplete, minDurationMs]);
|
|
477
492
|
|
|
478
493
|
const runChallenge = useCallback((index: number) => {
|
|
479
494
|
if (index >= challenges.length) {
|
|
480
|
-
console.log('All challenges completed,
|
|
495
|
+
console.log('All challenges completed, checking duration');
|
|
481
496
|
setOverallProgress(100);
|
|
482
497
|
|
|
498
|
+
// Clear the totalDuration timeout since we're handling it manually
|
|
499
|
+
if (recordingTimeoutRef.current) {
|
|
500
|
+
clearTimeout(recordingTimeoutRef.current);
|
|
501
|
+
recordingTimeoutRef.current = null;
|
|
502
|
+
console.log('Cleared totalDuration timeout');
|
|
503
|
+
}
|
|
504
|
+
|
|
483
505
|
if (isRecordingRef.current) {
|
|
484
506
|
const elapsed = Date.now() - recordingStartTime.current;
|
|
485
507
|
console.log('Checking duration - Elapsed:', (elapsed / 1000).toFixed(1), 's, Min required:', (minDurationMs / 1000).toFixed(1), 's');
|
|
@@ -487,7 +509,8 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
487
509
|
if (elapsed < minDurationMs) {
|
|
488
510
|
const remaining = minDurationMs - elapsed;
|
|
489
511
|
console.log('Waiting additional', (remaining / 1000).toFixed(1), 's to meet minimum duration');
|
|
490
|
-
setTimeout(() => {
|
|
512
|
+
recordingTimeoutRef.current = setTimeout(() => {
|
|
513
|
+
console.log('Minimum duration wait completed, stopping recording');
|
|
491
514
|
if (isRecordingRef.current) {
|
|
492
515
|
stopRecording();
|
|
493
516
|
}
|
|
@@ -495,8 +518,10 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
495
518
|
return;
|
|
496
519
|
}
|
|
497
520
|
|
|
521
|
+
console.log('Duration requirement met, stopping immediately');
|
|
498
522
|
stopRecording();
|
|
499
523
|
} else {
|
|
524
|
+
console.log('Recording already stopped, checking if we can complete');
|
|
500
525
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
501
526
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
502
527
|
console.log('Recording already stopped, completing with frames');
|
|
@@ -573,8 +598,14 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
573
598
|
videoRecordingRef.current = await cameraRef.current.startRecording({
|
|
574
599
|
flash: 'off',
|
|
575
600
|
onRecordingFinished: (video: any) => {
|
|
576
|
-
console.log('Video recording finished callback called, path:', video?.path || 'N/A');
|
|
577
|
-
|
|
601
|
+
console.log('Video recording finished callback called, path:', video?.path || 'N/A', 'phase:', phase);
|
|
602
|
+
// Ensure we're in the right state to process
|
|
603
|
+
if (phase === 'recording' || phase === 'processing') {
|
|
604
|
+
handleVideoComplete(video);
|
|
605
|
+
} else {
|
|
606
|
+
console.warn('Received onRecordingFinished but phase is', phase, '- calling handleVideoComplete anyway');
|
|
607
|
+
handleVideoComplete(video);
|
|
608
|
+
}
|
|
578
609
|
},
|
|
579
610
|
onRecordingError: (error: any) => {
|
|
580
611
|
console.error('Recording error:', error);
|
|
@@ -593,17 +624,25 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
593
624
|
|
|
594
625
|
runChallenge(0);
|
|
595
626
|
|
|
596
|
-
|
|
597
|
-
|
|
627
|
+
// Set a safety timeout that's longer than totalDuration to ensure we stop eventually
|
|
628
|
+
// This will be cleared if challenges complete early
|
|
629
|
+
const maxDuration = Math.max(totalDuration, minDurationMs + 2000); // Add 2s buffer
|
|
630
|
+
recordingTimeoutRef.current = setTimeout(() => {
|
|
631
|
+
console.log('Safety timeout reached (max duration), stopping recording');
|
|
598
632
|
if (isRecordingRef.current) {
|
|
599
633
|
stopRecording().catch(err => {
|
|
600
|
-
console.error('Error stopping recording on timeout:', err);
|
|
634
|
+
console.error('Error stopping recording on safety timeout:', err);
|
|
601
635
|
});
|
|
602
636
|
}
|
|
603
|
-
},
|
|
637
|
+
}, maxDuration);
|
|
604
638
|
|
|
605
|
-
return () =>
|
|
606
|
-
|
|
639
|
+
return () => {
|
|
640
|
+
if (recordingTimeoutRef.current) {
|
|
641
|
+
clearTimeout(recordingTimeoutRef.current);
|
|
642
|
+
recordingTimeoutRef.current = null;
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
}, [device, totalDuration, minDurationMs, handleVideoComplete, handleRecordingError, runChallenge, stopRecording, startFrameCapture]);
|
|
607
646
|
|
|
608
647
|
// Current challenge
|
|
609
648
|
const currentChallenge = challenges[currentChallengeIndex];
|