add start_watchdog/reset_watchdog to tasks
This commit is contained in:
@@ -202,14 +202,18 @@ class ParallelPipeline(BasePipeline):
|
|||||||
async def _process_up_queue(self):
|
async def _process_up_queue(self):
|
||||||
while True:
|
while True:
|
||||||
frame = await self._up_queue.get()
|
frame = await self._up_queue.get()
|
||||||
|
self.start_watchdog()
|
||||||
await self._parallel_push_frame(frame, FrameDirection.UPSTREAM)
|
await self._parallel_push_frame(frame, FrameDirection.UPSTREAM)
|
||||||
self._up_queue.task_done()
|
self._up_queue.task_done()
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _process_down_queue(self):
|
async def _process_down_queue(self):
|
||||||
running = True
|
running = True
|
||||||
while running:
|
while running:
|
||||||
frame = await self._down_queue.get()
|
frame = await self._down_queue.get()
|
||||||
|
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
endframe_counter = self._endframe_counter.get(frame.id, 0)
|
endframe_counter = self._endframe_counter.get(frame.id, 0)
|
||||||
|
|
||||||
# If we have a counter, decrement it.
|
# If we have a counter, decrement it.
|
||||||
@@ -224,3 +228,5 @@ class ParallelPipeline(BasePipeline):
|
|||||||
running = not (endframe_counter == 0 and isinstance(frame, EndFrame))
|
running = not (endframe_counter == 0 and isinstance(frame, EndFrame))
|
||||||
|
|
||||||
self._down_queue.task_done()
|
self._down_queue.task_done()
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
|
|||||||
@@ -61,5 +61,7 @@ class ConsumerProcessor(FrameProcessor):
|
|||||||
async def _consumer_task_handler(self):
|
async def _consumer_task_handler(self):
|
||||||
while True:
|
while True:
|
||||||
frame = await self._queue.get()
|
frame = await self._queue.get()
|
||||||
|
self.start_watchdog()
|
||||||
new_frame = await self._transformer(frame)
|
new_frame = await self._transformer(frame)
|
||||||
await self.push_frame(new_frame, self._direction)
|
await self.push_frame(new_frame, self._direction)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|||||||
@@ -412,6 +412,8 @@ class FrameProcessor(BaseObject):
|
|||||||
|
|
||||||
(frame, direction, callback) = await self.__input_queue.get()
|
(frame, direction, callback) = await self.__input_queue.get()
|
||||||
|
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
# Process the frame.
|
# Process the frame.
|
||||||
await self.process_frame(frame, direction)
|
await self.process_frame(frame, direction)
|
||||||
|
|
||||||
@@ -421,6 +423,8 @@ class FrameProcessor(BaseObject):
|
|||||||
|
|
||||||
self.__input_queue.task_done()
|
self.__input_queue.task_done()
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
def __create_push_task(self):
|
def __create_push_task(self):
|
||||||
if not self.__push_frame_task:
|
if not self.__push_frame_task:
|
||||||
self.__push_queue = asyncio.Queue()
|
self.__push_queue = asyncio.Queue()
|
||||||
@@ -434,5 +438,7 @@ class FrameProcessor(BaseObject):
|
|||||||
async def __push_frame_task_handler(self):
|
async def __push_frame_task_handler(self):
|
||||||
while True:
|
while True:
|
||||||
(frame, direction) = await self.__push_queue.get()
|
(frame, direction) = await self.__push_queue.get()
|
||||||
|
self.start_watchdog()
|
||||||
await self.__internal_push_frame(frame, direction)
|
await self.__internal_push_frame(frame, direction)
|
||||||
self.__push_queue.task_done()
|
self.__push_queue.task_done()
|
||||||
|
self.reset_watchdog()
|
||||||
|
|||||||
@@ -783,14 +783,18 @@ class RTVIProcessor(FrameProcessor):
|
|||||||
async def _action_task_handler(self):
|
async def _action_task_handler(self):
|
||||||
while True:
|
while True:
|
||||||
frame = await self._action_queue.get()
|
frame = await self._action_queue.get()
|
||||||
|
self.start_watchdog()
|
||||||
await self._handle_action(frame.message_id, frame.rtvi_action_run)
|
await self._handle_action(frame.message_id, frame.rtvi_action_run)
|
||||||
self._action_queue.task_done()
|
self._action_queue.task_done()
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _message_task_handler(self):
|
async def _message_task_handler(self):
|
||||||
while True:
|
while True:
|
||||||
message = await self._message_queue.get()
|
message = await self._message_queue.get()
|
||||||
|
self.start_watchdog()
|
||||||
await self._handle_message(message)
|
await self._handle_message(message)
|
||||||
self._message_queue.task_done()
|
self._message_queue.task_done()
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _handle_transport_message(self, frame: TransportMessageUrgentFrame):
|
async def _handle_transport_message(self, frame: TransportMessageUrgentFrame):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -190,6 +190,7 @@ class AssemblyAISTTService(STTService):
|
|||||||
while self._connected:
|
while self._connected:
|
||||||
try:
|
try:
|
||||||
message = await self._websocket.recv()
|
message = await self._websocket.recv()
|
||||||
|
self.start_watchdog()
|
||||||
data = json.loads(message)
|
data = json.loads(message)
|
||||||
await self._handle_message(data)
|
await self._handle_message(data)
|
||||||
except websockets.exceptions.ConnectionClosedOK:
|
except websockets.exceptions.ConnectionClosedOK:
|
||||||
@@ -197,6 +198,8 @@ class AssemblyAISTTService(STTService):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error processing WebSocket message: {e}")
|
logger.error(f"Error processing WebSocket message: {e}")
|
||||||
break
|
break
|
||||||
|
finally:
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Fatal error in receive handler: {e}")
|
logger.error(f"Fatal error in receive handler: {e}")
|
||||||
|
|||||||
@@ -285,6 +285,9 @@ class AWSTranscribeSTTService(STTService):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
response = await self._ws_client.recv()
|
response = await self._ws_client.recv()
|
||||||
|
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
headers, payload = decode_event(response)
|
headers, payload = decode_event(response)
|
||||||
|
|
||||||
if headers.get(":message-type") == "event":
|
if headers.get(":message-type") == "event":
|
||||||
@@ -342,3 +345,5 @@ class AWSTranscribeSTTService(STTService):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self} Unexpected error in receive loop: {e}")
|
logger.error(f"{self} Unexpected error in receive loop: {e}")
|
||||||
break
|
break
|
||||||
|
finally:
|
||||||
|
self.reset_watchdog()
|
||||||
|
|||||||
@@ -699,6 +699,8 @@ class AWSNovaSonicLLMService(LLMService):
|
|||||||
output = await self._stream.await_output()
|
output = await self._stream.await_output()
|
||||||
result = await output[1].receive()
|
result = await output[1].receive()
|
||||||
|
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
if result.value and result.value.bytes_:
|
if result.value and result.value.bytes_:
|
||||||
response_data = result.value.bytes_.decode("utf-8")
|
response_data = result.value.bytes_.decode("utf-8")
|
||||||
json_data = json.loads(response_data)
|
json_data = json.loads(response_data)
|
||||||
@@ -731,6 +733,8 @@ class AWSNovaSonicLLMService(LLMService):
|
|||||||
logger.error(f"{self} error processing responses: {e}")
|
logger.error(f"{self} error processing responses: {e}")
|
||||||
if self._wants_connection:
|
if self._wants_connection:
|
||||||
await self.reset_conversation()
|
await self.reset_conversation()
|
||||||
|
finally:
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _handle_completion_start_event(self, event_json):
|
async def _handle_completion_start_event(self, event_json):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -687,6 +687,8 @@ class GeminiMultimodalLiveLLMService(LLMService):
|
|||||||
|
|
||||||
async def _receive_task_handler(self):
|
async def _receive_task_handler(self):
|
||||||
async for message in self._websocket:
|
async for message in self._websocket:
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
evt = events.parse_server_event(message)
|
evt = events.parse_server_event(message)
|
||||||
# logger.debug(f"Received event: {message[:500]}")
|
# logger.debug(f"Received event: {message[:500]}")
|
||||||
# logger.debug(f"Received event: {evt}")
|
# logger.debug(f"Received event: {evt}")
|
||||||
@@ -708,8 +710,8 @@ class GeminiMultimodalLiveLLMService(LLMService):
|
|||||||
await self._handle_evt_error(evt)
|
await self._handle_evt_error(evt)
|
||||||
# errors are fatal, so exit the receive loop
|
# errors are fatal, so exit the receive loop
|
||||||
return
|
return
|
||||||
else:
|
|
||||||
pass
|
self.reset_watchdog()
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -502,6 +502,8 @@ class GladiaSTTService(STTService):
|
|||||||
async def _receive_task_handler(self):
|
async def _receive_task_handler(self):
|
||||||
try:
|
try:
|
||||||
async for message in self._websocket:
|
async for message in self._websocket:
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
content = json.loads(message)
|
content = json.loads(message)
|
||||||
|
|
||||||
# Handle audio chunk acknowledgments
|
# Handle audio chunk acknowledgments
|
||||||
@@ -559,11 +561,15 @@ class GladiaSTTService(STTService):
|
|||||||
translation, "", time_now_iso8601(), translated_language
|
translation, "", time_now_iso8601(), translated_language
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
except websockets.exceptions.ConnectionClosed:
|
except websockets.exceptions.ConnectionClosed:
|
||||||
# Expected when closing the connection
|
# Expected when closing the connection
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in Gladia WebSocket handler: {e}")
|
logger.error(f"Error in Gladia WebSocket handler: {e}")
|
||||||
|
finally:
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _maybe_reconnect(self) -> bool:
|
async def _maybe_reconnect(self) -> bool:
|
||||||
"""Handle exponential backoff reconnection logic."""
|
"""Handle exponential backoff reconnection logic."""
|
||||||
|
|||||||
@@ -747,9 +747,12 @@ class GoogleSTTService(STTService):
|
|||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
if self._request_queue.empty():
|
if self._request_queue.empty():
|
||||||
# wait for 10ms in case we don't have audio
|
# wait for 10ms in case we don't have audio
|
||||||
await asyncio.sleep(0.01)
|
await asyncio.sleep(0.01)
|
||||||
|
self.reset_watchdog()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Start bi-directional streaming
|
# Start bi-directional streaming
|
||||||
@@ -760,12 +763,13 @@ class GoogleSTTService(STTService):
|
|||||||
# Process responses
|
# Process responses
|
||||||
await self._process_responses(streaming_recognize)
|
await self._process_responses(streaming_recognize)
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
# If we're here, check if we need to reconnect
|
# If we're here, check if we need to reconnect
|
||||||
if (int(time.time() * 1000) - self._stream_start_time) > self.STREAMING_LIMIT:
|
if (int(time.time() * 1000) - self._stream_start_time) > self.STREAMING_LIMIT:
|
||||||
logger.debug("Reconnecting stream after timeout")
|
logger.debug("Reconnecting stream after timeout")
|
||||||
# Reset stream start time
|
# Reset stream start time
|
||||||
self._stream_start_time = int(time.time() * 1000)
|
self._stream_start_time = int(time.time() * 1000)
|
||||||
continue
|
|
||||||
else:
|
else:
|
||||||
# Normal stream end
|
# Normal stream end
|
||||||
break
|
break
|
||||||
@@ -775,7 +779,8 @@ class GoogleSTTService(STTService):
|
|||||||
|
|
||||||
await asyncio.sleep(1) # Brief delay before reconnecting
|
await asyncio.sleep(1) # Brief delay before reconnecting
|
||||||
self._stream_start_time = int(time.time() * 1000)
|
self._stream_start_time = int(time.time() * 1000)
|
||||||
continue
|
finally:
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in streaming task: {e}")
|
logger.error(f"Error in streaming task: {e}")
|
||||||
@@ -800,12 +805,16 @@ class GoogleSTTService(STTService):
|
|||||||
"""Process streaming recognition responses."""
|
"""Process streaming recognition responses."""
|
||||||
try:
|
try:
|
||||||
async for response in streaming_recognize:
|
async for response in streaming_recognize:
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
# Check streaming limit
|
# Check streaming limit
|
||||||
if (int(time.time() * 1000) - self._stream_start_time) > self.STREAMING_LIMIT:
|
if (int(time.time() * 1000) - self._stream_start_time) > self.STREAMING_LIMIT:
|
||||||
logger.debug("Stream timeout reached in response processing")
|
logger.debug("Stream timeout reached in response processing")
|
||||||
|
self.reset_watchdog()
|
||||||
break
|
break
|
||||||
|
|
||||||
if not response.results:
|
if not response.results:
|
||||||
|
self.reset_watchdog()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for result in response.results:
|
for result in response.results:
|
||||||
@@ -848,8 +857,10 @@ class GoogleSTTService(STTService):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error processing Google STT responses: {e}")
|
logger.error(f"Error processing Google STT responses: {e}")
|
||||||
|
self.reset_watchdog()
|
||||||
# Re-raise the exception to let it propagate (e.g. in the case of a timeout, propagate to _stream_audio to reconnect)
|
# Re-raise the exception to let it propagate (e.g. in the case of a
|
||||||
|
# timeout, propagate to _stream_audio to reconnect)
|
||||||
raise
|
raise
|
||||||
|
|||||||
@@ -203,12 +203,11 @@ class ResponseCancelEvent(ClientEvent):
|
|||||||
|
|
||||||
|
|
||||||
class ServerEvent(BaseModel):
|
class ServerEvent(BaseModel):
|
||||||
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||||
|
|
||||||
event_id: str
|
event_id: str
|
||||||
type: str
|
type: str
|
||||||
|
|
||||||
class Config:
|
|
||||||
arbitrary_types_allowed = True
|
|
||||||
|
|
||||||
|
|
||||||
class SessionCreatedEvent(ServerEvent):
|
class SessionCreatedEvent(ServerEvent):
|
||||||
type: Literal["session.created"]
|
type: Literal["session.created"]
|
||||||
|
|||||||
@@ -370,6 +370,7 @@ class OpenAIRealtimeBetaLLMService(LLMService):
|
|||||||
|
|
||||||
async def _receive_task_handler(self):
|
async def _receive_task_handler(self):
|
||||||
async for message in self._websocket:
|
async for message in self._websocket:
|
||||||
|
self.start_watchdog()
|
||||||
evt = events.parse_server_event(message)
|
evt = events.parse_server_event(message)
|
||||||
if evt.type == "session.created":
|
if evt.type == "session.created":
|
||||||
await self._handle_evt_session_created(evt)
|
await self._handle_evt_session_created(evt)
|
||||||
@@ -400,6 +401,7 @@ class OpenAIRealtimeBetaLLMService(LLMService):
|
|||||||
await self._handle_evt_error(evt)
|
await self._handle_evt_error(evt)
|
||||||
# errors are fatal, so exit the receive loop
|
# errors are fatal, so exit the receive loop
|
||||||
return
|
return
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
@traced_openai_realtime(operation="llm_setup")
|
@traced_openai_realtime(operation="llm_setup")
|
||||||
async def _handle_evt_session_created(self, evt):
|
async def _handle_evt_session_created(self, evt):
|
||||||
|
|||||||
@@ -224,11 +224,13 @@ class RivaSTTService(STTService):
|
|||||||
streaming_config=self._config,
|
streaming_config=self._config,
|
||||||
)
|
)
|
||||||
for response in responses:
|
for response in responses:
|
||||||
|
self.start_watchdog()
|
||||||
if not response.results:
|
if not response.results:
|
||||||
continue
|
continue
|
||||||
asyncio.run_coroutine_threadsafe(
|
asyncio.run_coroutine_threadsafe(
|
||||||
self._response_queue.put(response), self.get_event_loop()
|
self._response_queue.put(response), self.get_event_loop()
|
||||||
)
|
)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _thread_task_handler(self):
|
async def _thread_task_handler(self):
|
||||||
try:
|
try:
|
||||||
@@ -283,7 +285,9 @@ class RivaSTTService(STTService):
|
|||||||
async def _response_task_handler(self):
|
async def _response_task_handler(self):
|
||||||
while True:
|
while True:
|
||||||
response = await self._response_queue.get()
|
response = await self._response_queue.get()
|
||||||
|
self.start_watchdog()
|
||||||
await self._handle_response(response)
|
await self._handle_response(response)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def run_stt(self, audio: bytes) -> AsyncGenerator[Frame, None]:
|
async def run_stt(self, audio: bytes) -> AsyncGenerator[Frame, None]:
|
||||||
await self.start_ttfb_metrics()
|
await self.start_ttfb_metrics()
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ class SimliVideoService(FrameProcessor):
|
|||||||
async def _consume_and_process_audio(self):
|
async def _consume_and_process_audio(self):
|
||||||
await self._pipecat_resampler_event.wait()
|
await self._pipecat_resampler_event.wait()
|
||||||
async for audio_frame in self._simli_client.getAudioStreamIterator():
|
async for audio_frame in self._simli_client.getAudioStreamIterator():
|
||||||
|
self.start_watchdog()
|
||||||
resampled_frames = self._pipecat_resampler.resample(audio_frame)
|
resampled_frames = self._pipecat_resampler.resample(audio_frame)
|
||||||
for resampled_frame in resampled_frames:
|
for resampled_frame in resampled_frames:
|
||||||
audio_array = resampled_frame.to_ndarray()
|
audio_array = resampled_frame.to_ndarray()
|
||||||
@@ -74,10 +75,12 @@ class SimliVideoService(FrameProcessor):
|
|||||||
num_channels=1,
|
num_channels=1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _consume_and_process_video(self):
|
async def _consume_and_process_video(self):
|
||||||
await self._pipecat_resampler_event.wait()
|
await self._pipecat_resampler_event.wait()
|
||||||
async for video_frame in self._simli_client.getVideoStreamIterator(targetFormat="rgb24"):
|
async for video_frame in self._simli_client.getVideoStreamIterator(targetFormat="rgb24"):
|
||||||
|
self.start_watchdog()
|
||||||
# Process the video frame
|
# Process the video frame
|
||||||
convertedFrame: OutputImageRawFrame = OutputImageRawFrame(
|
convertedFrame: OutputImageRawFrame = OutputImageRawFrame(
|
||||||
image=video_frame.to_rgb().to_image().tobytes(),
|
image=video_frame.to_rgb().to_image().tobytes(),
|
||||||
@@ -86,6 +89,7 @@ class SimliVideoService(FrameProcessor):
|
|||||||
)
|
)
|
||||||
convertedFrame.pts = video_frame.pts
|
convertedFrame.pts = video_frame.pts
|
||||||
await self.push_frame(convertedFrame)
|
await self.push_frame(convertedFrame)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
async def process_frame(self, frame: Frame, direction: FrameDirection):
|
||||||
await super().process_frame(frame, direction)
|
await super().process_frame(frame, direction)
|
||||||
|
|||||||
@@ -217,5 +217,7 @@ class TavusVideoService(AIService):
|
|||||||
async def _send_task_handler(self):
|
async def _send_task_handler(self):
|
||||||
while True:
|
while True:
|
||||||
frame = await self._queue.get()
|
frame = await self._queue.get()
|
||||||
if isinstance(frame, OutputAudioRawFrame):
|
self.start_watchdog()
|
||||||
|
if isinstance(frame, OutputAudioRawFrame) and self._client:
|
||||||
await self._client.write_audio_frame(frame)
|
await self._client.write_audio_frame(frame)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|||||||
@@ -357,6 +357,8 @@ class BaseInputTransport(FrameProcessor):
|
|||||||
while True:
|
while True:
|
||||||
frame: InputAudioRawFrame = await self._audio_in_queue.get()
|
frame: InputAudioRawFrame = await self._audio_in_queue.get()
|
||||||
|
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
# If an audio filter is available, run it before VAD.
|
# If an audio filter is available, run it before VAD.
|
||||||
if self._params.audio_in_filter:
|
if self._params.audio_in_filter:
|
||||||
frame.audio = await self._params.audio_in_filter.filter(frame.audio)
|
frame.audio = await self._params.audio_in_filter.filter(frame.audio)
|
||||||
@@ -376,6 +378,8 @@ class BaseInputTransport(FrameProcessor):
|
|||||||
|
|
||||||
self._audio_in_queue.task_done()
|
self._audio_in_queue.task_done()
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _handle_prediction_result(self, result: MetricsData):
|
async def _handle_prediction_result(self, result: MetricsData):
|
||||||
"""Handle a prediction result event from the turn analyzer.
|
"""Handle a prediction result event from the turn analyzer.
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,8 @@ class FastAPIWebsocketInputTransport(BaseInputTransport):
|
|||||||
if not self._params.serializer:
|
if not self._params.serializer:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
self.start_watchdog()
|
||||||
|
|
||||||
frame = await self._params.serializer.deserialize(message)
|
frame = await self._params.serializer.deserialize(message)
|
||||||
|
|
||||||
if not frame:
|
if not frame:
|
||||||
@@ -180,9 +182,13 @@ class FastAPIWebsocketInputTransport(BaseInputTransport):
|
|||||||
await self.push_audio_frame(frame)
|
await self.push_audio_frame(frame)
|
||||||
else:
|
else:
|
||||||
await self.push_frame(frame)
|
await self.push_frame(frame)
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self} exception receiving data: {e.__class__.__name__} ({e})")
|
logger.error(f"{self} exception receiving data: {e.__class__.__name__} ({e})")
|
||||||
|
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
await self._client.trigger_client_disconnected()
|
await self._client.trigger_client_disconnected()
|
||||||
|
|
||||||
async def _monitor_websocket(self):
|
async def _monitor_websocket(self):
|
||||||
|
|||||||
@@ -423,8 +423,10 @@ class SmallWebRTCInputTransport(BaseInputTransport):
|
|||||||
async def _receive_audio(self):
|
async def _receive_audio(self):
|
||||||
try:
|
try:
|
||||||
async for audio_frame in self._client.read_audio_frame():
|
async for audio_frame in self._client.read_audio_frame():
|
||||||
|
self.start_watchdog()
|
||||||
if audio_frame:
|
if audio_frame:
|
||||||
await self.push_audio_frame(audio_frame)
|
await self.push_audio_frame(audio_frame)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self} exception receiving data: {e.__class__.__name__} ({e})")
|
logger.error(f"{self} exception receiving data: {e.__class__.__name__} ({e})")
|
||||||
@@ -432,6 +434,7 @@ class SmallWebRTCInputTransport(BaseInputTransport):
|
|||||||
async def _receive_video(self):
|
async def _receive_video(self):
|
||||||
try:
|
try:
|
||||||
async for video_frame in self._client.read_video_frame():
|
async for video_frame in self._client.read_video_frame():
|
||||||
|
self.start_watchdog()
|
||||||
if video_frame:
|
if video_frame:
|
||||||
await self.push_video_frame(video_frame)
|
await self.push_video_frame(video_frame)
|
||||||
|
|
||||||
@@ -450,6 +453,7 @@ class SmallWebRTCInputTransport(BaseInputTransport):
|
|||||||
await self.push_video_frame(image_frame)
|
await self.push_video_frame(image_frame)
|
||||||
# Remove from pending requests
|
# Remove from pending requests
|
||||||
del self._image_requests[req_id]
|
del self._image_requests[req_id]
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self} exception receiving data: {e.__class__.__name__} ({e})")
|
logger.error(f"{self} exception receiving data: {e.__class__.__name__} ({e})")
|
||||||
|
|||||||
@@ -415,6 +415,7 @@ class LiveKitInputTransport(BaseInputTransport):
|
|||||||
logger.info("Audio input task started")
|
logger.info("Audio input task started")
|
||||||
while True:
|
while True:
|
||||||
audio_data = await self._client.get_next_audio_frame()
|
audio_data = await self._client.get_next_audio_frame()
|
||||||
|
self.start_watchdog()
|
||||||
if audio_data:
|
if audio_data:
|
||||||
audio_frame_event, participant_id = audio_data
|
audio_frame_event, participant_id = audio_data
|
||||||
pipecat_audio_frame = await self._convert_livekit_audio_to_pipecat(
|
pipecat_audio_frame = await self._convert_livekit_audio_to_pipecat(
|
||||||
@@ -427,6 +428,7 @@ class LiveKitInputTransport(BaseInputTransport):
|
|||||||
num_channels=pipecat_audio_frame.num_channels,
|
num_channels=pipecat_audio_frame.num_channels,
|
||||||
)
|
)
|
||||||
await self.push_audio_frame(input_audio_frame)
|
await self.push_audio_frame(input_audio_frame)
|
||||||
|
self.reset_watchdog()
|
||||||
|
|
||||||
async def _convert_livekit_audio_to_pipecat(
|
async def _convert_livekit_audio_to_pipecat(
|
||||||
self, audio_frame_event: rtc.AudioFrameEvent
|
self, audio_frame_event: rtc.AudioFrameEvent
|
||||||
|
|||||||
Reference in New Issue
Block a user