diff --git a/voice.py b/voice.py index 7f975bf..2b301c9 100644 --- a/voice.py +++ b/voice.py @@ -408,11 +408,11 @@ class VoiceSession: logger.info("Track pub: %s %s kind=%s", p.identity, pub.sid, pub.kind) @self.lk_room.on("track_muted") - def on_mute(pub, p): + def on_mute(p, pub): logger.info("Track MUTED: %s %s kind=%s", p.identity, pub.sid, pub.kind) @self.lk_room.on("track_unmuted") - def on_unmute(pub, p): + def on_unmute(p, pub): logger.info("Track UNMUTED: %s %s kind=%s", p.identity, pub.sid, pub.kind) @self.lk_room.on("track_subscribed") @@ -483,12 +483,24 @@ class VoiceSession: ok = kp.set_key(bot_identity, self._bot_key, 0) logger.info("Set bot key for %s (ok=%s, %d bytes)", bot_identity, ok, len(self._bot_key)) - # Element Call may rotate keys when bot joins — handled asynchronously by - # on_encryption_key() (stores keys) + on_track_subscribed() / on_e2ee_state_changed() - # (applies keys when frame cryptor exists). No blocking wait needed. - logger.info("E2EE key state: %d keys stored (max_idx=%d)", - len(self._caller_all_keys), - max(self._caller_all_keys.keys()) if self._caller_all_keys else -1) + # Element Call rotates its key when bot joins. Wait up to 3s for the + # rotated key to arrive via nio sync before proceeding. If it arrives, + # on_encryption_key() stores it and (if track already subscribed) sets it. + pre_key_count = len(self._caller_all_keys) + pre_max_idx = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1 + logger.info("Waiting up to 3s for key rotation (current: %d keys, max_idx=%d)...", + pre_key_count, pre_max_idx) + for _wait in range(6): # 6 × 0.5s = 3s + await asyncio.sleep(0.5) + new_count = len(self._caller_all_keys) + new_max = max(self._caller_all_keys.keys()) if self._caller_all_keys else -1 + if new_max > pre_max_idx or new_count > pre_key_count: + self._caller_key = self._caller_all_keys[new_max] + logger.info("Key rotated: index %d→%d, count %d→%d", + pre_max_idx, new_max, pre_key_count, new_count) + break + else: + logger.info("No key rotation after 3s — proceeding with key[%d]", pre_max_idx) # Find the remote participant, wait up to 10s if not yet connected remote_identity = None