add preconnect audio buffer API to LocalAudioTrack#648
add preconnect audio buffer API to LocalAudioTrack#648theomonnom wants to merge 1 commit intomainfrom
Conversation
Adds start_preconnect_buffer/stop_preconnect_buffer/send_preconnect_buffer to LocalAudioTrack, backed by a zero-allocation circular bytearray ring buffer. Sends buffered audio via byte stream data channels using the existing lk.agent.pre-connect-audio-buffer protocol.
| async def _on_participant_active(participant: RemoteParticipant) -> None: | ||
| if participant.identity != target_identity: | ||
| return | ||
| if not track.has_preconnect_buffer: | ||
| return | ||
| room.off("participant_active", _on_participant_active) | ||
| try: | ||
| await track.send_preconnect_buffer( | ||
| destination_identity=participant.identity | ||
| ) | ||
| except Exception: | ||
| logger.exception("failed to auto-send preconnect buffer") | ||
|
|
||
| room.on("participant_active", _on_participant_active) |
There was a problem hiding this comment.
🔴 Registering async callback with EventEmitter.on() always raises ValueError
The _setup_preconnect_auto_send method defines _on_participant_active as an async def and registers it with room.on("participant_active", _on_participant_active) at line 816. However, EventEmitter.on() (event_emitter.py:160-163) explicitly rejects async callbacks by raising ValueError("Cannot register an async callback with .on(). Use asyncio.create_task within your synchronous callback instead."). This means the auto-send feature will always crash with a ValueError when _setup_preconnect_auto_send is called, which propagates up through publish_track() when preconnect_buffer_auto_send_to is set and the track has a preconnect buffer.
Prompt for agents
The _setup_preconnect_auto_send method in participant.py defines _on_participant_active as an async function and tries to register it with room.on("participant_active", ...) at line 816. However, EventEmitter.on() (in event_emitter.py:160-163) raises ValueError when given an async callback.
The fix should follow the pattern recommended by the error message: define a synchronous callback that internally creates a task. For example:
def _on_participant_active(participant: RemoteParticipant) -> None:
if participant.identity != target_identity:
return
if not track.has_preconnect_buffer:
return
room.off("participant_active", _on_participant_active)
asyncio.ensure_future(_send_preconnect(participant))
async def _send_preconnect(participant: RemoteParticipant) -> None:
try:
await track.send_preconnect_buffer(destination_identity=participant.identity)
except Exception:
logger.exception("failed to auto-send preconnect buffer")
room.on("participant_active", _on_participant_active)
This is in _setup_preconnect_auto_send in livekit-rtc/livekit/rtc/participant.py. The EventEmitter.on() constraint is in livekit-rtc/livekit/rtc/event_emitter.py:159-163.
Was this helpful? React with 👍 or 👎 to provide feedback.
No description provided.