3a179fe524
Matrix, WhatsApp Cloud and the TTS tool each ran their own ffmpeg argv for the same speech-tuned libopus encode; they predate the shared helper and never migrated, so the codec flags, timeout handling and error reporting drifted (matrix 48k/30s, whatsapp_cloud async subprocess with no timeout and no `-ac 1`, tts an in-place sidecar repair). `transcode_to_ogg_opus` gains `timeout=` and `output_path=` (sibling-file and in-place writes go through a `.tmp.ogg` sidecar so a failed encode never truncates the source). Deleted: matrix `_matrix_transcode_voice_to_ogg`, tts `_ffmpeg_transcode_to_opus`; whatsapp_cloud `_convert_to_opus` keeps only its warn-once ffmpeg install hint and calls the helper via `asyncio.to_thread`. Matrix and tts keep their 48k bitrate. Behavior change: whatsapp_cloud transcodes now use mono (`-ac 1`), `-compression_level 10` and a 60s timeout like every other voice bubble; a failed encode logs at WARNING for all three sites (matrix previously DEBUG).