mirror of
https://github.com/R0m1k3/Regisflow.git
synced 2026-10-23 23:28:18 +02:00
Improve camera reliability and diagnose capture issues more effectively
Adds detailed logging and retry logic to address camera startup and dimension detection failures in CameraModal and useCamera. Replit-Commit-Author: Agent Replit-Commit-Session-Id: dec54137-d5a2-4406-8ad4-5f2f9fb110bf Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/0715008c-7244-40f4-befc-26c014852236/eb403944-9342-469a-8dd7-95b8b1a1cf40.jpg
This commit is contained in:
1 parent
ed38c25c9f
commit
97c6f3ec1e
3 files changed
+108
-14
No files matched your search
@@ -25,31 +25,47 @@ export default function CameraModal({
|
|||||||
}: CameraModalProps) {
|
}: CameraModalProps) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isOpen && videoRef.current) {
|
if (isOpen && videoRef.current) {
|
||||||
// Ensure video starts playing when modal opens
|
|
||||||
const video = videoRef.current;
|
const video = videoRef.current;
|
||||||
|
console.log('CameraModal useEffect - video element ready');
|
||||||
|
|
||||||
const handleLoadedMetadata = () => {
|
const handleLoadedMetadata = () => {
|
||||||
console.log('Video loaded metadata:', video.videoWidth, 'x', video.videoHeight);
|
console.log('CameraModal: Video metadata loaded, dimensions:', video.videoWidth, 'x', video.videoHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCanPlay = () => {
|
const handleCanPlay = () => {
|
||||||
console.log('Video can play');
|
console.log('CameraModal: Video can play, readyState:', video.readyState);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleError = (error: Event) => {
|
const handleError = (error: Event) => {
|
||||||
console.error('Video error:', error);
|
console.error('CameraModal: Video error event:', error);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePlay = () => {
|
||||||
|
console.log('CameraModal: Video started playing');
|
||||||
};
|
};
|
||||||
|
|
||||||
video.addEventListener('loadedmetadata', handleLoadedMetadata);
|
video.addEventListener('loadedmetadata', handleLoadedMetadata);
|
||||||
video.addEventListener('canplay', handleCanPlay);
|
video.addEventListener('canplay', handleCanPlay);
|
||||||
video.addEventListener('error', handleError);
|
video.addEventListener('error', handleError);
|
||||||
|
video.addEventListener('play', handlePlay);
|
||||||
|
|
||||||
video.play().catch(console.error);
|
// Forcer le play avec gestion d'erreur
|
||||||
|
const startPlayback = async () => {
|
||||||
|
try {
|
||||||
|
await video.play();
|
||||||
|
console.log('CameraModal: Video play() successful');
|
||||||
|
} catch (playError) {
|
||||||
|
console.error('CameraModal: Video play() failed:', playError);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
startPlayback();
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
video.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
video.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
||||||
video.removeEventListener('canplay', handleCanPlay);
|
video.removeEventListener('canplay', handleCanPlay);
|
||||||
video.removeEventListener('error', handleError);
|
video.removeEventListener('error', handleError);
|
||||||
|
video.removeEventListener('play', handlePlay);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [isOpen, videoRef]);
|
}, [isOpen, videoRef]);
|
||||||
|
|||||||
@@ -184,7 +184,8 @@ export default function NewSaleForm() {
|
|||||||
|
|
||||||
// Photo capture functions
|
// Photo capture functions
|
||||||
const handlePhotoCapture = async (photoType: PhotoType) => {
|
const handlePhotoCapture = async (photoType: PhotoType) => {
|
||||||
console.log('Photo capture requested for:', photoType);
|
console.log('=== PHOTO CAPTURE REQUESTED ===');
|
||||||
|
console.log('Photo type:', photoType);
|
||||||
|
|
||||||
// Vérifications préliminaires
|
// Vérifications préliminaires
|
||||||
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||||
@@ -208,8 +209,35 @@ export default function NewSaleForm() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('Attempting to start camera...');
|
console.log('Attempting to start camera...');
|
||||||
|
|
||||||
|
// Afficher toast de démarrage
|
||||||
|
toast({
|
||||||
|
title: "Démarrage de la caméra",
|
||||||
|
description: "Préparation de la caméra en cours...",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Démarrer la caméra
|
||||||
await startCamera(photoType);
|
await startCamera(photoType);
|
||||||
console.log('Camera started successfully');
|
console.log('Camera started successfully');
|
||||||
|
|
||||||
|
// Attendre 2 secondes supplémentaires pour s'assurer que la vidéo est prête
|
||||||
|
console.log('Waiting for video to be fully ready...');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
|
|
||||||
|
// Vérifier l'état final de la vidéo
|
||||||
|
if (videoRef.current) {
|
||||||
|
const video = videoRef.current;
|
||||||
|
console.log('Final video state check:', {
|
||||||
|
videoWidth: video.videoWidth,
|
||||||
|
videoHeight: video.videoHeight,
|
||||||
|
readyState: video.readyState,
|
||||||
|
paused: video.paused,
|
||||||
|
currentTime: video.currentTime
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Camera should be ready for capture');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Camera start failed:', error);
|
console.error('Camera start failed:', error);
|
||||||
toast({
|
toast({
|
||||||
|
|||||||
@@ -111,17 +111,33 @@ export function useCamera() {
|
|||||||
handleLoadedMetadata();
|
handleLoadedMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Timeout de sécurité réduit
|
// Timeout de sécurité avec état détaillé
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
video.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
video.removeEventListener('loadedmetadata', handleLoadedMetadata);
|
||||||
video.removeEventListener('error', handleError);
|
video.removeEventListener('error', handleError);
|
||||||
video.removeEventListener('canplay', handleCanPlay);
|
video.removeEventListener('canplay', handleCanPlay);
|
||||||
console.log('Video load timeout, current state:', {
|
console.log('Video load timeout - final state:', {
|
||||||
readyState: video.readyState,
|
readyState: video.readyState,
|
||||||
videoWidth: video.videoWidth,
|
videoWidth: video.videoWidth,
|
||||||
videoHeight: video.videoHeight,
|
videoHeight: video.videoHeight,
|
||||||
paused: video.paused
|
paused: video.paused,
|
||||||
|
currentTime: video.currentTime,
|
||||||
|
duration: video.duration,
|
||||||
|
srcObject: !!video.srcObject
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Vérifier si le stream est actif
|
||||||
|
if (video.srcObject) {
|
||||||
|
const stream = video.srcObject as MediaStream;
|
||||||
|
const tracks = stream.getTracks();
|
||||||
|
console.log('Stream tracks status:', tracks.map(t => ({
|
||||||
|
kind: t.kind,
|
||||||
|
enabled: t.enabled,
|
||||||
|
readyState: t.readyState,
|
||||||
|
label: t.label
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
resolve(true);
|
resolve(true);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
});
|
});
|
||||||
@@ -158,23 +174,57 @@ export function useCamera() {
|
|||||||
|
|
||||||
console.log('Starting photo capture, current dimensions:', video.videoWidth, 'x', video.videoHeight);
|
console.log('Starting photo capture, current dimensions:', video.videoWidth, 'x', video.videoHeight);
|
||||||
|
|
||||||
// Attendre que la vidéo ait des dimensions valides
|
// Attendre que la vidéo ait des dimensions valides avec diagnostic détaillé
|
||||||
let attempts = 0;
|
let attempts = 0;
|
||||||
const maxAttempts = 50; // 5 secondes max
|
const maxAttempts = 100; // 10 secondes max
|
||||||
|
|
||||||
const waitForDimensions = () => {
|
const waitForDimensions = () => {
|
||||||
return new Promise<void>((resolveWait) => {
|
return new Promise<void>((resolveWait) => {
|
||||||
const checkDimensions = () => {
|
const checkDimensions = () => {
|
||||||
attempts++;
|
attempts++;
|
||||||
console.log(`Checking video dimensions, attempt ${attempts}: ${video.videoWidth}x${video.videoHeight}`);
|
|
||||||
|
// Diagnostic détaillé à chaque tentative
|
||||||
|
const diagnosticInfo = {
|
||||||
|
attempt: attempts,
|
||||||
|
videoWidth: video.videoWidth,
|
||||||
|
videoHeight: video.videoHeight,
|
||||||
|
readyState: video.readyState,
|
||||||
|
paused: video.paused,
|
||||||
|
currentTime: video.currentTime,
|
||||||
|
duration: video.duration,
|
||||||
|
networkState: video.networkState,
|
||||||
|
srcObject: !!video.srcObject
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log(`Capture attempt ${attempts}/100:`, diagnosticInfo);
|
||||||
|
|
||||||
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
||||||
console.log('Video dimensions are valid:', video.videoWidth, 'x', video.videoHeight);
|
console.log('✅ Video dimensions are valid:', video.videoWidth, 'x', video.videoHeight);
|
||||||
resolveWait();
|
resolveWait();
|
||||||
} else if (attempts >= maxAttempts) {
|
} else if (attempts >= maxAttempts) {
|
||||||
|
console.error('❌ Timeout: video dimensions not available after 10 seconds');
|
||||||
|
console.error('Final video state:', diagnosticInfo);
|
||||||
|
|
||||||
|
// Vérifier l'état du stream
|
||||||
|
if (video.srcObject) {
|
||||||
|
const stream = video.srcObject as MediaStream;
|
||||||
|
const tracks = stream.getTracks();
|
||||||
|
console.error('Stream tracks final state:', tracks.map(t => ({
|
||||||
|
kind: t.kind,
|
||||||
|
enabled: t.enabled,
|
||||||
|
readyState: t.readyState,
|
||||||
|
label: t.label
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
|
||||||
setIsCapturing(false);
|
setIsCapturing(false);
|
||||||
reject(new Error('Timeout: video dimensions not available after 5 seconds'));
|
reject(new Error('Timeout: video dimensions not available after 10 seconds'));
|
||||||
} else {
|
} else {
|
||||||
|
// Diagnostic périodique plus détaillé
|
||||||
|
if (attempts % 10 === 0) {
|
||||||
|
console.warn(`Still waiting for video dimensions after ${attempts} attempts...`);
|
||||||
|
console.warn('Current video state:', diagnosticInfo);
|
||||||
|
}
|
||||||
setTimeout(checkDimensions, 100);
|
setTimeout(checkDimensions, 100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user