diff --git a/examples/video-stream/audio_wave.py b/examples/video-stream/audio_wave.py index ce588702..b00c31aa 100644 --- a/examples/video-stream/audio_wave.py +++ b/examples/video-stream/audio_wave.py @@ -296,6 +296,8 @@ async def main(room: rtc.Room, room_name: str): finally: audio_task.cancel() await av_sync.aclose() + await audio_source.aclose() + await video_source.aclose() if __name__ == "__main__": diff --git a/examples/video-stream/video_play.py b/examples/video-stream/video_play.py index 05f753ef..b15e1ccc 100644 --- a/examples/video-stream/video_play.py +++ b/examples/video-stream/video_play.py @@ -181,6 +181,8 @@ async def _push_frames( finally: await streamer.aclose() await av_sync.aclose() + await audio_source.aclose() + await video_source.aclose() if __name__ == "__main__": diff --git a/livekit-rtc/livekit/rtc/audio_source.py b/livekit-rtc/livekit/rtc/audio_source.py index f32b8213..839203d8 100644 --- a/livekit-rtc/livekit/rtc/audio_source.py +++ b/livekit-rtc/livekit/rtc/audio_source.py @@ -118,7 +118,7 @@ async def capture_frame(self, frame: AudioFrame) -> None: Exception: If there is an error during frame capture. """ - if frame.samples_per_channel == 0: + if frame.samples_per_channel == 0 or self._ffi_handle.disposed: return now = time.monotonic() @@ -175,3 +175,10 @@ def _release_waiter(self) -> None: self._last_capture = 0.0 self._q_size = 0.0 self._join_fut = None + + async def aclose(self) -> None: + """Close the audio source + + This method cleans up resources associated with the audio source. + """ + self._ffi_handle.dispose() diff --git a/livekit-rtc/livekit/rtc/video_source.py b/livekit-rtc/livekit/rtc/video_source.py index 377f39f9..5ae58f66 100644 --- a/livekit-rtc/livekit/rtc/video_source.py +++ b/livekit-rtc/livekit/rtc/video_source.py @@ -42,3 +42,6 @@ def capture_frame( req.capture_video_frame.rotation = rotation req.capture_video_frame.timestamp_us = timestamp_us FfiClient.instance.request(req) + + async def aclose(self) -> None: + self._ffi_handle.dispose()