From d7524afeff1c1c0c0eba2132c60c065080d65a59 Mon Sep 17 00:00:00 2001 From: Jonathan Schuster Date: Sun, 26 Apr 2026 14:44:37 +0200 Subject: [PATCH] fix: disable Analyse on active recordings; guard server-side too Clicking Analyse on a file currently being recorded caused libsndfile to fail with 'Internal psf_fseek() failed' because an in-progress FLAC file has no seektable (written only on close()). Client: Analyse button is disabled with a tooltip while isRec is true. Server: _api_analyze checks status.json and returns 409 with a readable message if the file is still being recorded, before attempting to open it. --- web.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/web.py b/web.py index 36a6b81..a8d2651 100644 --- a/web.py +++ b/web.py @@ -272,6 +272,15 @@ class _Handler(BaseHTTPRequestHandler): if path is None: return + status_path = Path(self.recordings_dir) / 'status.json' + try: + with open(status_path) as fh: + if filename in set(json.load(fh).get('active', [])): + self._json_err(409, 'File is currently being recorded — analysis unavailable until recording stops') + return + except Exception: + pass + ext = path.suffix.lower() if ext == '.wav': result = analyze_wav(path, threshold=self.threshold) @@ -691,7 +700,12 @@ async function load() { const abtn = document.createElement('button'); abtn.textContent = 'Analyse'; abtn.setAttribute('aria-label', `Analyse loudness of ${f.name}`); - abtn.addEventListener('click', () => analyse(f.name, cell, abtn)); + if (isRec) { + abtn.disabled = true; + abtn.title = 'Recording in progress — analyse after recording stops'; + } else { + abtn.addEventListener('click', () => analyse(f.name, cell, abtn)); + } cell.appendChild(abtn); }