From 6062c76cf8b2e5fd0a3d9d3f424f991112d8c843 Mon Sep 17 00:00:00 2001 From: BadStorm Developer Date: Sat, 5 Sep 2026 15:18:42 +0200 Subject: [PATCH] fix(talkbot): retry failed voice message processing --- containers/talkbot/server.py | 77 +++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/containers/talkbot/server.py b/containers/talkbot/server.py index 95a3b95..d18d2b4 100644 --- a/containers/talkbot/server.py +++ b/containers/talkbot/server.py @@ -4,6 +4,7 @@ import os import re import sqlite3 import subprocess +import tempfile import threading from datetime import datetime, timedelta, timezone from typing import Optional @@ -492,40 +493,53 @@ def is_blank_transcription(text: str) -> bool: def convert_audio_to_wav(audio_bytes: bytes) -> bytes: """Convert any FFmpeg-supported audio format to Whisper's WAV format.""" - try: - result = subprocess.run( - [ - "ffmpeg", - "-hide_banner", - "-loglevel", - "error", - "-i", - "pipe:0", - "-vn", - "-ac", - "1", - "-ar", - "16000", - "-c:a", - "pcm_s16le", - "-f", - "wav", - "pipe:1", - ], - input=audio_bytes, - capture_output=True, - check=False, - timeout=120, - ) - except FileNotFoundError as exc: - raise RuntimeError("ffmpeg is not installed in the talkbot container") from exc - except subprocess.TimeoutExpired as exc: - raise RuntimeError("Audio conversion with ffmpeg timed out") from exc + # Use a temporary file instead of stdin: MP4-based audio often has its + # metadata (moov atom) at the end and requires seeking during probing. + with tempfile.NamedTemporaryFile( + prefix="talkbot-input-", + suffix=".audio", + ) as input_file: + input_file.write(audio_bytes) + input_file.flush() + + try: + result = subprocess.run( + [ + "ffmpeg", + "-hide_banner", + "-loglevel", + "error", + "-i", + input_file.name, + "-vn", + "-ac", + "1", + "-ar", + "16000", + "-c:a", + "pcm_s16le", + "-f", + "wav", + "pipe:1", + ], + capture_output=True, + check=False, + timeout=120, + ) + except FileNotFoundError as exc: + raise RuntimeError( + "ffmpeg is not installed in the talkbot container" + ) from exc + except subprocess.TimeoutExpired as exc: + raise RuntimeError("Audio conversion with ffmpeg timed out") from exc if result.returncode != 0 or not result.stdout: error = result.stderr.decode("utf-8", errors="replace").strip() raise RuntimeError(f"Unable to convert audio to WAV: {error[:500]}") + if len(result.stdout) <= 78: + raise RuntimeError("Audio conversion produced an empty WAV file") + log.info( "Audio converted to WAV: %s -> %s bytes", len(audio_bytes), @@ -1198,8 +1212,9 @@ def process_event(job: dict) -> None: message_id, exc, ) - - return + # Let event_worker() reschedule the queued job. If we return here, + # the worker considers the event successful and removes it. + raise if message_text: log.info(