transport: allow requesting a user frame
This commit is contained in:
@@ -169,8 +169,12 @@ class DailyTransport(ThreadedTransport, EventHandler):
|
|||||||
if self._mic_enabled:
|
if self._mic_enabled:
|
||||||
self.mic.write_frames(frame)
|
self.mic.write_frames(frame)
|
||||||
|
|
||||||
def send_app_message(self, message: Any, participantId: str | None):
|
def request_participant_image(self, participant_id: str):
|
||||||
self.client.send_app_message(message, participantId)
|
if participant_id in self._video_renderers:
|
||||||
|
self._video_renderers[participant_id]["render_next_frame"] = True
|
||||||
|
|
||||||
|
def send_app_message(self, message: Any, participant_id: str | None):
|
||||||
|
self.client.send_app_message(message, participant_id)
|
||||||
|
|
||||||
def read_audio_frames(self, desired_frame_count):
|
def read_audio_frames(self, desired_frame_count):
|
||||||
bytes = b""
|
bytes = b""
|
||||||
@@ -302,6 +306,7 @@ class DailyTransport(ThreadedTransport, EventHandler):
|
|||||||
self._video_renderers[participant_id] = {
|
self._video_renderers[participant_id] = {
|
||||||
"framerate": framerate,
|
"framerate": framerate,
|
||||||
"timestamp": 0,
|
"timestamp": 0,
|
||||||
|
"render_next_frame": False,
|
||||||
}
|
}
|
||||||
self.client.set_video_renderer(
|
self.client.set_video_renderer(
|
||||||
participant_id,
|
participant_id,
|
||||||
@@ -310,17 +315,28 @@ class DailyTransport(ThreadedTransport, EventHandler):
|
|||||||
color_format=color_format)
|
color_format=color_format)
|
||||||
|
|
||||||
def on_participant_video_frame(self, participant_id, video_frame):
|
def on_participant_video_frame(self, participant_id, video_frame):
|
||||||
|
if not self._loop:
|
||||||
|
return
|
||||||
|
|
||||||
|
render_frame = False
|
||||||
|
|
||||||
curr_time = time.time()
|
curr_time = time.time()
|
||||||
prev_time = self._video_renderers[participant_id]["timestamp"]
|
framerate = self._video_renderers[participant_id]["framerate"]
|
||||||
diff_time = curr_time - prev_time
|
|
||||||
period = 1 / self._video_renderers[participant_id]["framerate"]
|
if framerate > 0:
|
||||||
if diff_time > period and self._loop:
|
prev_time = self._video_renderers[participant_id]["timestamp"]
|
||||||
self._video_renderers[participant_id]["timestamp"] = curr_time
|
next_time = prev_time + 1 / framerate
|
||||||
|
render_frame = curr_time > next_time
|
||||||
|
elif self._video_renderers[participant_id]["render_next_frame"]:
|
||||||
|
self._video_renderers[participant_id]["render_next_frame"] = False
|
||||||
|
render_frame = True
|
||||||
|
|
||||||
|
if render_frame:
|
||||||
frame = UserImageFrame(participant_id, video_frame.buffer,
|
frame = UserImageFrame(participant_id, video_frame.buffer,
|
||||||
(video_frame.width, video_frame.height))
|
(video_frame.width, video_frame.height))
|
||||||
asyncio.run_coroutine_threadsafe(
|
asyncio.run_coroutine_threadsafe(self.receive_queue.put(frame), self._loop)
|
||||||
self.receive_queue.put(frame), self._loop
|
|
||||||
)
|
self._video_renderers[participant_id]["timestamp"] = curr_time
|
||||||
|
|
||||||
def on_error(self, error):
|
def on_error(self, error):
|
||||||
self._logger.error(f"on_error: {error}")
|
self._logger.error(f"on_error: {error}")
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from dailyai.pipeline.frames import (
|
|||||||
SpriteFrame,
|
SpriteFrame,
|
||||||
StartFrame,
|
StartFrame,
|
||||||
TextFrame,
|
TextFrame,
|
||||||
|
UserImageRequestFrame,
|
||||||
UserStartedSpeakingFrame,
|
UserStartedSpeakingFrame,
|
||||||
UserStoppedSpeakingFrame,
|
UserStoppedSpeakingFrame,
|
||||||
)
|
)
|
||||||
@@ -382,7 +383,11 @@ class ThreadedTransport(AbstractTransport):
|
|||||||
def _set_images(self, images: list[bytes], start_frame=0):
|
def _set_images(self, images: list[bytes], start_frame=0):
|
||||||
self._images = itertools.cycle(images)
|
self._images = itertools.cycle(images)
|
||||||
|
|
||||||
def send_app_message(self, message: Any, participantId: str | None):
|
def request_participant_image(self, participant_id: str):
|
||||||
|
""" Child classes should override this to force an image from a user. """
|
||||||
|
pass
|
||||||
|
|
||||||
|
def send_app_message(self, message: Any, participant_id: str | None):
|
||||||
""" Child classes should override this to send a custom message to the room. """
|
""" Child classes should override this to send a custom message to the room. """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -458,9 +463,10 @@ class ThreadedTransport(AbstractTransport):
|
|||||||
self._set_image(frame.image)
|
self._set_image(frame.image)
|
||||||
elif isinstance(frame, SpriteFrame):
|
elif isinstance(frame, SpriteFrame):
|
||||||
self._set_images(frame.images)
|
self._set_images(frame.images)
|
||||||
|
elif isinstance(frame, UserImageRequestFrame):
|
||||||
|
self.request_participant_image(frame.user_id)
|
||||||
elif isinstance(frame, SendAppMessageFrame):
|
elif isinstance(frame, SendAppMessageFrame):
|
||||||
self.send_app_message(
|
self.send_app_message(frame.message, frame.participant_id)
|
||||||
frame.message, frame.participantId)
|
|
||||||
elif len(b):
|
elif len(b):
|
||||||
self.write_frame_to_mic(bytes(b))
|
self.write_frame_to_mic(bytes(b))
|
||||||
b = bytearray()
|
b = bytearray()
|
||||||
|
|||||||
Reference in New Issue
Block a user