From 7516e0ad61252ce99fd21b06d8ac00d750e621bb Mon Sep 17 00:00:00 2001 From: Pheby Date: Fri, 12 Jun 2026 11:36:39 +0000 Subject: [PATCH] fix: wait for finalized wav header before transcription --- bot.py | 15 +++++++++++++-- tests/test_bot.py | 23 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/bot.py b/bot.py index d6d080f..06ceed5 100644 --- a/bot.py +++ b/bot.py @@ -4,6 +4,7 @@ import asyncio import logging import os import uuid +import wave from pathlib import Path import discord @@ -136,8 +137,18 @@ async def wait_for_file_ready(file_path: str, attempts: int = 20, delay: float = if size > 0 and size == last_size: stable_count += 1 if stable_count >= 2: - logger.info("Recording file finalized: path=%s size_bytes=%s", file_path, size) - return True + try: + with wave.open(file_path, "rb") as wav_file: + wav_file.getparams() + except (wave.Error, EOFError, OSError) as exc: + logger.info( + "Recording file exists and is size-stable but WAV header is not finalized yet: path=%s error=%s", + file_path, + exc, + ) + else: + logger.info("Recording file finalized: path=%s size_bytes=%s", file_path, size) + return True else: stable_count = 0 last_size = size diff --git a/tests/test_bot.py b/tests/test_bot.py index cf4f532..986eb3c 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -1,6 +1,7 @@ import asyncio import os import sys +import wave from pathlib import Path from types import SimpleNamespace @@ -106,3 +107,25 @@ def test_meeting_recorder_wraps_wave_sink_with_silence_generator(tmp_path, monke assert created["silence"].destination is created["wave"] assert vc.listened_sink is created["silence"] assert recorder.recording is True + + +def test_wait_for_file_ready_rejects_stable_but_invalid_wav(tmp_path): + broken = tmp_path / "meeting.wav" + broken.write_bytes(b"not a real wav file") + + ready = asyncio.run(bot.wait_for_file_ready(str(broken), attempts=3, delay=0.001)) + + assert ready is False + + +def test_wait_for_file_ready_accepts_valid_wav(tmp_path): + valid = tmp_path / "meeting.wav" + with wave.open(str(valid), "wb") as wav_file: + wav_file.setnchannels(1) + wav_file.setsampwidth(2) + wav_file.setframerate(16000) + wav_file.writeframes(b"\x00\x00" * 160) + + ready = asyncio.run(bot.wait_for_file_ready(str(valid), attempts=3, delay=0.001)) + + assert ready is True