From d333a29c4ce029080fc07960b8c9aac26d242cf3 Mon Sep 17 00:00:00 2001 From: perco Date: Tue, 2 Jun 2026 16:42:52 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20encodage=20clip=20:=20H.264=20baseline=20?= =?UTF-8?q?720p=20CRF28=20pour=20compatibilit=C3=A9=20navigateur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Transcode clip en H.264 baseline level 3.1 (compatible tous navigateurs) - Downsample à 720p pour réduire la taille (17MB raw → ~2.5MB encodé) - CRF 28 + preset fast = bon compromis qualité/vitesse - Sans audio (inutile pour surveillance) - -movflags +faststart pour lecture streaming sans téléchargement complet Co-Authored-By: Claude Sonnet 4.6 --- app/watcher.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/watcher.py b/app/watcher.py index e3f4720..83f57bf 100644 --- a/app/watcher.py +++ b/app/watcher.py @@ -138,14 +138,21 @@ def _process_event(): "-vf", f"fps={CAPTURE_FPS}", "-q:v", "2", frames_pattern, ], capture_output=True, timeout=30) - # Step 2b: remux clip for browser compatibility (moov atom at start) + # Step 2b: transcode to H.264 baseline for browser compatibility web_clip = os.path.join(event_dir, "clip_web.mp4") subprocess.run([ "ffmpeg", "-y", "-i", clip_path, - "-c", "copy", "-movflags", "+faststart", web_clip, - ], capture_output=True, timeout=20) + "-c:v", "libx264", "-profile:v", "baseline", "-level", "3.1", + "-preset", "fast", "-crf", "28", + "-vf", "scale=-2:720", # downsample to 720p — enough for review + "-an", # no audio needed for surveillance + "-movflags", "+faststart", # moov atom at front for streaming + web_clip, + ], capture_output=True, timeout=60) if os.path.exists(web_clip): os.replace(web_clip, clip_path) + else: + log.warning("Transcode failed, keeping raw clip") frame_files = sorted(glob.glob(os.path.join(event_dir, "frame_*.jpg"))) log.info(f"Extracted {len(frame_files)} frames")