From 397031218bdcac7b95331f085260841d2791df56 Mon Sep 17 00:00:00 2001 From: Will Date: Sat, 14 Feb 2026 15:48:03 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20OGG/Opus=20truncation=20=E2=80=94=20clos?= =?UTF-8?q?e=20container=20before=20reading=20buffer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The finalize block in write_chunk() called output_buffer.getvalue() before container.close(). For OGG/Opus, the final page of audio data is only written to the buffer during close(), causing ~1-2 seconds of audio to be lost. Swap the order: close container first, then read buffer. Fixes: remsky/Kokoro-FastAPI#447 --- api/src/services/streaming_audio_writer.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/api/src/services/streaming_audio_writer.py b/api/src/services/streaming_audio_writer.py index de9c84e3..b1566f0b 100644 --- a/api/src/services/streaming_audio_writer.py +++ b/api/src/services/streaming_audio_writer.py @@ -80,13 +80,15 @@ def write_chunk( for packet in packets: self.container.mux(packet) - # Closing the container handles writing the trailer and finalizing the file. - # No explicit flush method is available or needed here. - logger.debug("Muxed final packets.") + # Close the container FIRST — this writes the final OGG page + # (or other format trailer) to the output buffer. For OGG/Opus, + # the last page of audio data is only written during close(). + self.container.close() + logger.debug("Closed container, final page/trailer written.") - # Get the final bytes from the buffer *before* closing it + # Now read the buffer which includes all trailing data data = self.output_buffer.getvalue() - self.close() # Close container and buffer + self.output_buffer.close() return data if audio_data is None or len(audio_data) == 0: