diff --git a/voice.py b/voice.py index 85c01b3..bf14bb6 100644 --- a/voice.py +++ b/voice.py @@ -693,8 +693,25 @@ class VoiceSession: if self._caller_all_keys: for idx, base_k in sorted(self._caller_all_keys.items()): _derive_and_set_key(kp_local, caller_id, base_k, idx) - logger.info("on_ts: derived+set key[%d] for %s (%s track)", + logger.info("on_ts: set key[%d] for %s (%s track)", idx, caller_id, track_type) + # MAT-144: Video frame cryptors may not be fully initialized + # when set_key is first called. Schedule aggressive re-keying. + if int(t.kind) == 2: + async def _video_rekey(pid=caller_id): + for delay in (0.3, 0.8, 2.0, 5.0): + await asyncio.sleep(delay) + if not self.lk_room: + break + try: + kp_v = self.lk_room.e2ee_manager.key_provider + for idx, base_k in sorted(self._caller_all_keys.items()): + _derive_and_set_key(kp_v, pid, base_k, idx) + logger.info("video_rekey: re-set %d keys for %s (delay=%.1fs)", + len(self._caller_all_keys), pid, delay) + except Exception as exc: + logger.warning("video_rekey failed: %s", exc) + asyncio.ensure_future(_video_rekey()) else: logger.warning("on_ts: no caller keys yet — scheduling 0.5s retry") async def _brief_key_retry(pid=caller_id): @@ -704,7 +721,7 @@ class VoiceSession: kp_r = self.lk_room.e2ee_manager.key_provider for idx, base_k in sorted(self._caller_all_keys.items()): _derive_and_set_key(kp_r, pid, base_k, idx) - logger.info("on_ts_retry: derived+set key[%d] for %s", idx, pid) + logger.info("on_ts_retry: set key[%d] for %s", idx, pid) except Exception as exc: logger.warning("on_ts_retry: set_key failed: %s", exc) else: