From 79b00841789705d2e95436bb1d4680e0e87ed035 Mon Sep 17 00:00:00 2001 From: Jules Date: Tue, 7 Apr 2026 19:27:54 +0200 Subject: [PATCH] Fix capture DSLR: pause avant capture + retry si I/O in progress - Frontend: arrete le preview 300ms avant la capture - Backend: 3 tentatives avec 500ms entre chaque si DSLR occupe Co-Authored-By: Claude Opus 4.6 (1M context) --- backend/camera.py | 29 +++++++++++++++++------------ frontend/js/camera.js | 4 +++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/backend/camera.py b/backend/camera.py index 5c9b83f..d6faaee 100644 --- a/backend/camera.py +++ b/backend/camera.py @@ -146,18 +146,23 @@ class Camera: return self._capture_simulation(chemin_dest) def _capture_gphoto2(self, chemin_dest: Path) -> Path | None: - try: - chemin_camera = self.camera.capture(gp.GP_CAPTURE_IMAGE) - fichier_camera = gp.CameraFile() - self.camera.file_get( - chemin_camera.folder, chemin_camera.name, gp.GP_FILE_TYPE_NORMAL, fichier_camera - ) - fichier_camera.save(str(chemin_dest)) - log.info(f"Photo capturee (DSLR) : {chemin_dest}") - return chemin_dest - except gp.GPhoto2Error as e: - log.error(f"Erreur capture DSLR : {e}") - return None + for attempt in range(3): + try: + chemin_camera = self.camera.capture(gp.GP_CAPTURE_IMAGE) + fichier_camera = gp.CameraFile() + self.camera.file_get( + chemin_camera.folder, chemin_camera.name, gp.GP_FILE_TYPE_NORMAL, fichier_camera + ) + fichier_camera.save(str(chemin_dest)) + log.info(f"Photo capturee (DSLR) : {chemin_dest}") + return chemin_dest + except gp.GPhoto2Error as e: + if "I/O in progress" in str(e) and attempt < 2: + log.warning(f"DSLR occupe, retry {attempt + 1}/3...") + time.sleep(0.5) + continue + log.error(f"Erreur capture DSLR : {e}") + return None def _capture_webcam(self, chemin_dest: Path) -> Path | None: if not self.webcam or not self.webcam.isOpened(): diff --git a/frontend/js/camera.js b/frontend/js/camera.js index 0ad6859..e8c4199 100644 --- a/frontend/js/camera.js +++ b/frontend/js/camera.js @@ -46,9 +46,11 @@ async function lancerCapture() { } await compteARebours(); - afficherFlash(); arreterPreview(); + await pause(300); // Laisser le DSLR se liberer du preview + + afficherFlash(); const resultat = await apiPost('/api/capturer'); if (resultat.erreur) {