From 7c5c37c19bf6bdf6dbf68ace4ee231ab01ca69a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?The=CC=81o=20Monnom?= Date: Fri, 4 Oct 2024 15:11:08 -0700 Subject: [PATCH] wip --- livekit-rtc/livekit/rtc/audio_frame.py | 2 ++ livekit-rtc/livekit/rtc/audio_source.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/livekit-rtc/livekit/rtc/audio_frame.py b/livekit-rtc/livekit/rtc/audio_frame.py index e6b8088b..9e9931ab 100644 --- a/livekit-rtc/livekit/rtc/audio_frame.py +++ b/livekit-rtc/livekit/rtc/audio_frame.py @@ -24,6 +24,8 @@ class AudioFrame: """ A class that represents a frame of audio data with specific properties such as sample rate, number of channels, and samples per channel. + + The format of the audio data is 16-bit signed integers (int16) interleaved by channel. """ def __init__( diff --git a/livekit-rtc/livekit/rtc/audio_source.py b/livekit-rtc/livekit/rtc/audio_source.py index 2c32d61b..41ce1695 100644 --- a/livekit-rtc/livekit/rtc/audio_source.py +++ b/livekit-rtc/livekit/rtc/audio_source.py @@ -70,7 +70,7 @@ def __init__( self._last_capture = 0.0 self._q_size = 0.0 self._join_handle: asyncio.TimerHandle | None = None - self._join_fut: asyncio.Future[None] = self._loop.create_future() + self._join_fut: asyncio.Future[None] | None = None @property def sample_rate(self) -> int: @@ -118,6 +118,9 @@ async def capture_frame(self, frame: AudioFrame) -> None: Exception: If there is an error during frame capture. """ + if frame.samples_per_channel == 0: + return + now = time.monotonic() elapsed = 0.0 if self._last_capture == 0.0 else now - self._last_capture self._q_size += frame.samples_per_channel / self.sample_rate - elapsed @@ -126,7 +129,7 @@ async def capture_frame(self, frame: AudioFrame) -> None: if self._join_handle: self._join_handle.cancel() - if self._join_fut.done(): + if self._join_fut is None: self._join_fut = self._loop.create_future() self._join_handle = self._loop.call_later(self._q_size, self._release_waiter) @@ -163,8 +166,11 @@ async def wait_for_playout(self) -> None: await asyncio.shield(self._join_fut) def _release_waiter(self) -> None: + assert self._join_fut is not None + if not self._join_fut.done(): self._join_fut.set_result(None) self._last_capture = 0.0 self._q_size = 0.0 + self._join_fut = None