Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions livekit-agents/livekit/agents/utils/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,4 @@ async def file_reader() -> None:

finally:
await cancel_and_wait(reader_task)
await decoder.aclose()
10 changes: 9 additions & 1 deletion livekit-agents/livekit/agents/voice/background_audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,13 @@ async def _play_task(
else:
sound = audio_frames_from_file(sound)

stopped = False
Copy link
Member

@theomonnom theomonnom Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need the stopped flag if we just ignore the RuntimError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that okay to just ignore the runtime error, the generator is still not closed? I am wondering should we also close the generator from audio file?


async def _gen_wrapper() -> AsyncGenerator[rtc.AudioFrame, None]:
async for frame in sound:
if stopped:
break

if volume != 1.0:
data = np.frombuffer(frame.data, dtype=np.int16).astype(np.float32)
data *= 10 ** (np.log10(volume))
Expand All @@ -372,7 +377,10 @@ async def _gen_wrapper() -> AsyncGenerator[rtc.AudioFrame, None]:

await asyncio.sleep(0)
if play_handle._stop_fut.done():
await gen.aclose()
stopped = True
with contextlib.suppress(RuntimeError):
# ignore error caused by race condition between aclose() and gen.__anext__()
await gen.aclose()

@log_exceptions(logger=logger)
async def _run_mixer_task(self) -> None:
Expand Down