From 8982410b035b1aca19b93619e2497b1898cdfdc6 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 11 May 2026 10:04:44 +0800 Subject: [PATCH 1/4] E2E Test: E2E test for end to end encryption. --- .github/workflows/tests.yml | 4 +- livekit-rtc/livekit/rtc/e2ee.py | 18 +- livekit-rtc/livekit/rtc/room.py | 14 +- .../tests/test_e2ee_per_participant.py | 396 ++++++++++++++++++ livekit-rtc/tests/test_e2ee_shared_key.py | 341 +++++++++++++++ 5 files changed, 764 insertions(+), 9 deletions(-) create mode 100644 livekit-rtc/tests/test_e2ee_per_participant.py create mode 100644 livekit-rtc/tests/test_e2ee_shared_key.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5834e804..3b495c01 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -128,7 +128,7 @@ jobs: LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }} run: | source .test-venv/bin/activate - pytest tests/ + pytest tests/ livekit-rtc/tests/ - name: Run tests (Windows) if: runner.os == 'Windows' @@ -136,6 +136,6 @@ jobs: LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }} LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }} LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }} - run: .test-venv\Scripts\python.exe -m pytest tests/ + run: .test-venv\Scripts\python.exe -m pytest tests/ livekit-rtc/tests/ shell: pwsh \ No newline at end of file diff --git a/livekit-rtc/livekit/rtc/e2ee.py b/livekit-rtc/livekit/rtc/e2ee.py index 0258c157..3e72d830 100644 --- a/livekit-rtc/livekit/rtc/e2ee.py +++ b/livekit-rtc/livekit/rtc/e2ee.py @@ -185,16 +185,28 @@ def ratchet_key(self, participant_identity: str, key_index: int) -> bytes: class FrameCryptor: - def __init__(self, room_handle: int, participant_identity: str, key_index: int, enabled: bool): + def __init__( + self, + room_handle: int, + participant_identity: str, + track_sid: str, + key_index: int, + enabled: bool, + ): self._room_handle = room_handle self._enabled = enabled self._participant_identity = participant_identity + self._track_sid = track_sid self._key_index = key_index @property def participant_identity(self) -> str: return self._participant_identity + @property + def track_sid(self) -> str: + return self._track_sid + @property def key_index(self) -> int: return self._key_index @@ -218,6 +230,7 @@ def set_enabled(self, enabled: bool) -> None: req = proto_ffi.FfiRequest() req.e2ee.room_handle = self._room_handle req.e2ee.cryptor_set_enabled.participant_identity = self._participant_identity + req.e2ee.cryptor_set_enabled.track_sid = self._track_sid req.e2ee.cryptor_set_enabled.enabled = enabled FfiClient.instance.request(req) @@ -236,6 +249,7 @@ def set_key_index(self, key_index: int) -> None: req = proto_ffi.FfiRequest() req.e2ee.room_handle = self._room_handle req.e2ee.cryptor_set_key_index.participant_identity = self._participant_identity + req.e2ee.cryptor_set_key_index.track_sid = self._track_sid req.e2ee.cryptor_set_key_index.key_index = key_index FfiClient.instance.request(req) @@ -289,6 +303,7 @@ def frame_cryptors(self) -> List[FrameCryptor]: """ req = proto_ffi.FfiRequest() req.e2ee.room_handle = self._room_handle + req.e2ee.manager_get_frame_cryptors.SetInParent() resp = FfiClient.instance.request(req) frame_cryptors = [] @@ -297,6 +312,7 @@ def frame_cryptors(self) -> List[FrameCryptor]: FrameCryptor( self._room_handle, frame_cryptor.participant_identity, + frame_cryptor.track_sid, frame_cryptor.key_index, frame_cryptor.enabled, ) diff --git a/livekit-rtc/livekit/rtc/room.py b/livekit-rtc/livekit/rtc/room.py index b4a822a5..21577c08 100644 --- a/livekit-rtc/livekit/rtc/room.py +++ b/livekit-rtc/livekit/rtc/room.py @@ -460,9 +460,10 @@ def on_participant_connected(participant): ) req.connect.options.e2ee.encryption_type = options.e2ee.encryption_type - req.connect.options.e2ee.key_provider_options.shared_key = ( - options.e2ee.key_provider_options.shared_key # type: ignore - ) + if options.e2ee.key_provider_options.shared_key is not None: + req.connect.options.e2ee.key_provider_options.shared_key = ( + options.e2ee.key_provider_options.shared_key + ) req.connect.options.e2ee.key_provider_options.ratchet_salt = ( options.e2ee.key_provider_options.ratchet_salt ) @@ -481,9 +482,10 @@ def on_participant_connected(participant): if options.encryption: req.connect.options.encryption.encryption_type = options.encryption.encryption_type - req.connect.options.encryption.key_provider_options.shared_key = ( - options.encryption.key_provider_options.shared_key # type: ignore - ) + if options.encryption.key_provider_options.shared_key is not None: + req.connect.options.encryption.key_provider_options.shared_key = ( + options.encryption.key_provider_options.shared_key + ) req.connect.options.encryption.key_provider_options.ratchet_salt = ( options.encryption.key_provider_options.ratchet_salt ) diff --git a/livekit-rtc/tests/test_e2ee_per_participant.py b/livekit-rtc/tests/test_e2ee_per_participant.py new file mode 100644 index 00000000..25a98ff9 --- /dev/null +++ b/livekit-rtc/tests/test_e2ee_per_participant.py @@ -0,0 +1,396 @@ +# Copyright 2026 LiveKit, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""E2E tests for E2EE key per-partcipant.""" + +from __future__ import annotations + +import asyncio +import os +import uuid +from typing import Callable, TypeVar + +import pytest + +from livekit import api, rtc + + +# Per-participant keys (publisher identity → list of (key_bytes, key_index)) +PUBLISHER_IDENTITY = "e2eePublisher" +PUBLISHER_KEYS: list[tuple[bytes, int]] = [ + (b"12345678", 0), + (b"abcdefgh", 1), + (b"ijklmnop", 2), +] + +WIDTH, HEIGHT = 320, 180 +FRAME_RATE = 15 + +T = TypeVar("T") + + +def skip_if_no_credentials(): + required_vars = ["LIVEKIT_URL", "LIVEKIT_API_KEY", "LIVEKIT_API_SECRET"] + missing = [var for var in required_vars if not os.getenv(var)] + return pytest.mark.skipif( + bool(missing), reason=f"Missing environment variables: {', '.join(missing)}" + ) + + +def create_token(identity: str, room_name: str) -> str: + return ( + api.AccessToken() + .with_identity(identity) + .with_name(identity) + .with_grants( + api.VideoGrants( + room_join=True, + room=room_name, + ) + ) + .to_jwt() + ) + + +def unique_room_name(base: str) -> str: + return f"{base}-{uuid.uuid4().hex[:8]}" + + +async def assert_eventually( + condition: Callable[[], T], + timeout: float = 15.0, + interval: float = 0.1, + message: str = "Condition not met within timeout", +) -> T: + deadline = asyncio.get_event_loop().time() + timeout + last_result = None + while asyncio.get_event_loop().time() < deadline: + last_result = condition() + if last_result: + return last_result + await asyncio.sleep(interval) + raise AssertionError(f"{message} (last result: {last_result})") + + +def make_per_participant_e2ee_options() -> rtc.E2EEOptions: + options = rtc.E2EEOptions() + # No shared key — keys are installed per participant after connect. + options.key_provider_options.shared_key = None + options.key_provider_options.ratchet_window_size = 16 + return options + + +def install_publisher_keys(room: rtc.Room) -> None: + """Install the publisher's per-participant keys on `room`'s key provider.""" + key_provider = room.e2ee_manager.key_provider + assert key_provider is not None, "room is missing a key provider" + for key, key_index in PUBLISHER_KEYS: + key_provider.set_key(PUBLISHER_IDENTITY, key, key_index) + + +def set_key_index_on_all_cryptors(room: rtc.Room, key_index: int) -> None: + """Equivalent of dart's e2eeManager.setKeyIndex(idx): apply to every cryptor.""" + for cryptor in room.e2ee_manager.frame_cryptors(): + cryptor.set_key_index(key_index) + + +async def publish_dummy_video(source: rtc.VideoSource, stop_event: asyncio.Event) -> None: + """Continuously publish frames until stop_event is set.""" + pixel_count = WIDTH * HEIGHT + frame_idx = 0 + while not stop_event.is_set(): + fill = frame_idx % 256 + pixel = bytes((255, fill, (fill + 85) % 256, (fill + 170) % 256)) + buf = pixel * pixel_count + frame = rtc.VideoFrame(WIDTH, HEIGHT, rtc.VideoBufferType.ARGB, buf) + source.capture_frame(frame) + frame_idx += 1 + try: + await asyncio.wait_for(stop_event.wait(), timeout=1.0 / FRAME_RATE) + except asyncio.TimeoutError: + pass + + +@pytest.mark.asyncio +@skip_if_no_credentials() +async def test_e2ee_per_participant(): + """E2E test for per-participant E2EE keys. + + E2EE per-participant E2E test: + 1. Each room has its own KeyProvider; the publisher's three keys + (indexes 0/1/2) are installed on every room. + 2. Publisher publishes a video track. Receivers must observe + track_published and an OK e2ee_state. + 3. All participants must use GCM encryption. + 4. Publisher ratchets key index 2 → receivers observe KEY_RATCHETED. + 5. Publisher disables E2EE → receivers observe DECRYPTION_FAILED. + 6. Publisher switches to key index 1 and re-enables E2EE → receivers + observe OK (since they already have key index 1). + 7. Publisher switches to key index 2 and ratchets it; receivers + switch to key index 2 → receivers observe KEY_RATCHETED. + """ + room_name = unique_room_name("test-e2ee-per-participant") + url = os.getenv("LIVEKIT_URL") + + publisher_room = rtc.Room() + receiver1_room = rtc.Room() + receiver2_room = rtc.Room() + + publisher_token = create_token(PUBLISHER_IDENTITY, room_name) + receiver1_token = create_token("receiver1", room_name) + receiver2_token = create_token("receiver2", room_name) + + track_published_on: dict[str, asyncio.Event] = { + "receiver1": asyncio.Event(), + "receiver2": asyncio.Event(), + } + track_subscribed_on: dict[str, asyncio.Event] = { + "receiver1": asyncio.Event(), + "receiver2": asyncio.Event(), + } + seen_e2ee_states: dict[str, set[int]] = { + "receiver1": set(), + "receiver2": set(), + } + e2ee_state_log: dict[str, list[int]] = { + "receiver1": [], + "receiver2": [], + } + + def wire_receiver(room: rtc.Room, label: str) -> None: + @room.on("track_published") + def _on_pub( + publication: rtc.RemoteTrackPublication, participant: rtc.RemoteParticipant + ) -> None: + track_published_on[label].set() + + @room.on("track_subscribed") + def _on_sub( + track: rtc.Track, + publication: rtc.RemoteTrackPublication, + participant: rtc.RemoteParticipant, + ) -> None: + track_subscribed_on[label].set() + + @room.on("e2ee_state_changed") + def _on_state(participant: rtc.Participant, state: int) -> None: + if participant is not None and participant.identity == PUBLISHER_IDENTITY: + seen_e2ee_states[label].add(state) + e2ee_state_log[label].append(state) + + wire_receiver(receiver1_room, "receiver1") + wire_receiver(receiver2_room, "receiver2") + + publish_stop = asyncio.Event() + publish_task: asyncio.Task | None = None + + try: + # 1) connect all three rooms with per-participant E2EE options + await publisher_room.connect( + url, + publisher_token, + options=rtc.RoomOptions( + auto_subscribe=True, encryption=make_per_participant_e2ee_options() + ), + ) + await receiver1_room.connect( + url, + receiver1_token, + options=rtc.RoomOptions( + auto_subscribe=True, encryption=make_per_participant_e2ee_options() + ), + ) + await receiver2_room.connect( + url, + receiver2_token, + options=rtc.RoomOptions( + auto_subscribe=True, encryption=make_per_participant_e2ee_options() + ), + ) + + for room in (publisher_room, receiver1_room, receiver2_room): + assert room.connection_state == rtc.ConnectionState.CONN_CONNECTED + install_publisher_keys(room) + + # 2) publish a video track + source = rtc.VideoSource(WIDTH, HEIGHT) + track = rtc.LocalVideoTrack.create_video_track("e2ee-cam", source) + publish_options = rtc.TrackPublishOptions() + publish_options.source = rtc.TrackSource.SOURCE_CAMERA + publish_options.video_codec = rtc.VideoCodec.VP8 + publish_options.simulcast = True + publication = await publisher_room.local_participant.publish_track( + track, publish_options + ) + assert publication is not None and publication.sid + + publish_task = asyncio.create_task(publish_dummy_video(source, publish_stop)) + + # 3) receivers see track_published / track_subscribed + await asyncio.wait_for(track_published_on["receiver1"].wait(), timeout=15.0) + await asyncio.wait_for(track_published_on["receiver2"].wait(), timeout=15.0) + await asyncio.wait_for(track_subscribed_on["receiver1"].wait(), timeout=15.0) + await asyncio.wait_for(track_subscribed_on["receiver2"].wait(), timeout=15.0) + + # 4) receivers reach EncryptionState.OK + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver1"], + message=( + "receiver1 did not reach EncryptionState.OK " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver2"], + message=( + "receiver2 did not reach EncryptionState.OK " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + # 5) verify GCM on both receiver rooms + def all_remote_video_pubs_gcm(room: rtc.Room) -> bool: + for rp in room.remote_participants.values(): + for pub in rp.track_publications.values(): + if pub.kind != rtc.TrackKind.KIND_VIDEO: + continue + if pub.encryption_type != rtc.EncryptionType.GCM: + return False + return True + + await assert_eventually( + lambda: all_remote_video_pubs_gcm(receiver1_room), + message="receiver1 sees a non-GCM video publication", + ) + await assert_eventually( + lambda: all_remote_video_pubs_gcm(receiver2_room), + message="receiver2 sees a non-GCM video publication", + ) + + # 6) ratchet publisher's key at index 0 (the default cryptor key index); + # receivers should auto-ratchet to match. + seen_e2ee_states["receiver1"].clear() + seen_e2ee_states["receiver2"].clear() + e2ee_state_log["receiver1"].clear() + e2ee_state_log["receiver2"].clear() + await asyncio.sleep(1.0) + + publisher_key_provider = publisher_room.e2ee_manager.key_provider + assert publisher_key_provider is not None + publisher_key_provider.ratchet_key(PUBLISHER_IDENTITY, key_index=0) + + await assert_eventually( + lambda: rtc.EncryptionState.KEY_RATCHETED in seen_e2ee_states["receiver1"], + message=( + "receiver1 did not observe KEY_RATCHETED after publisher ratchet " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.KEY_RATCHETED in seen_e2ee_states["receiver2"], + message=( + "receiver2 did not observe KEY_RATCHETED after publisher ratchet " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + # 7) disable e2ee on publisher → receivers observe DECRYPTION_FAILED + seen_e2ee_states["receiver1"].clear() + seen_e2ee_states["receiver2"].clear() + e2ee_state_log["receiver1"].clear() + e2ee_state_log["receiver2"].clear() + await asyncio.sleep(1.0) + + publisher_room.e2ee_manager.set_enabled(False) + + await assert_eventually( + lambda: rtc.EncryptionState.DECRYPTION_FAILED in seen_e2ee_states["receiver1"], + message=( + "receiver1 did not observe DECRYPTION_FAILED " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.DECRYPTION_FAILED in seen_e2ee_states["receiver2"], + message=( + "receiver2 did not observe DECRYPTION_FAILED " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + # 8) publisher switches to key index 1 and re-enables e2ee + # receivers already have key index 1 → should reach OK + seen_e2ee_states["receiver1"].clear() + seen_e2ee_states["receiver2"].clear() + e2ee_state_log["receiver1"].clear() + e2ee_state_log["receiver2"].clear() + await asyncio.sleep(1.0) + + set_key_index_on_all_cryptors(publisher_room, 1) + publisher_room.e2ee_manager.set_enabled(True) + + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver1"], + message=( + "receiver1 did not return to EncryptionState.OK with key index 1 " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver2"], + message=( + "receiver2 did not return to EncryptionState.OK with key index 1 " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + # 9) publisher switches to key index 2 and ratchets it; receivers + # switch to key index 2 → should observe KEY_RATCHETED + seen_e2ee_states["receiver1"].clear() + seen_e2ee_states["receiver2"].clear() + e2ee_state_log["receiver1"].clear() + e2ee_state_log["receiver2"].clear() + await asyncio.sleep(1.0) + + set_key_index_on_all_cryptors(publisher_room, 2) + publisher_key_provider.ratchet_key(PUBLISHER_IDENTITY, key_index=2) + set_key_index_on_all_cryptors(receiver1_room, 2) + set_key_index_on_all_cryptors(receiver2_room, 2) + + await assert_eventually( + lambda: rtc.EncryptionState.KEY_RATCHETED in seen_e2ee_states["receiver1"], + message=( + "receiver1 did not observe KEY_RATCHETED after key-index switch " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.KEY_RATCHETED in seen_e2ee_states["receiver2"], + message=( + "receiver2 did not observe KEY_RATCHETED after key-index switch " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + finally: + publish_stop.set() + if publish_task is not None: + try: + await asyncio.wait_for(publish_task, timeout=2.0) + except (asyncio.TimeoutError, asyncio.CancelledError): + publish_task.cancel() + + for room in (publisher_room, receiver1_room, receiver2_room): + if room.isconnected(): + await room.disconnect() diff --git a/livekit-rtc/tests/test_e2ee_shared_key.py b/livekit-rtc/tests/test_e2ee_shared_key.py new file mode 100644 index 00000000..48681ae9 --- /dev/null +++ b/livekit-rtc/tests/test_e2ee_shared_key.py @@ -0,0 +1,341 @@ +# Copyright 2026 LiveKit, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""E2E tests for E2EE shared key .""" + +from __future__ import annotations + +import asyncio +import os +import uuid +from typing import Callable, TypeVar + +import pytest + +from livekit import api, rtc + + +SHARED_KEY = b"12345678" +WIDTH, HEIGHT = 320, 180 +FRAME_RATE = 15 + +T = TypeVar("T") + + +def skip_if_no_credentials(): + required_vars = ["LIVEKIT_URL", "LIVEKIT_API_KEY", "LIVEKIT_API_SECRET"] + missing = [var for var in required_vars if not os.getenv(var)] + return pytest.mark.skipif( + bool(missing), reason=f"Missing environment variables: {', '.join(missing)}" + ) + + +def create_token(identity: str, room_name: str) -> str: + return ( + api.AccessToken() + .with_identity(identity) + .with_name(identity) + .with_grants( + api.VideoGrants( + room_join=True, + room=room_name, + ) + ) + .to_jwt() + ) + + +def unique_room_name(base: str) -> str: + return f"{base}-{uuid.uuid4().hex[:8]}" + + +async def assert_eventually( + condition: Callable[[], T], + timeout: float = 10.0, + interval: float = 0.1, + message: str = "Condition not met within timeout", +) -> T: + deadline = asyncio.get_event_loop().time() + timeout + last_result = None + while asyncio.get_event_loop().time() < deadline: + last_result = condition() + if last_result: + return last_result + await asyncio.sleep(interval) + raise AssertionError(f"{message} (last result: {last_result})") + + +def make_e2ee_options() -> rtc.E2EEOptions: + options = rtc.E2EEOptions() + options.key_provider_options.shared_key = SHARED_KEY + options.key_provider_options.ratchet_window_size = 16 + return options + + +async def publish_dummy_video(source: rtc.VideoSource, stop_event: asyncio.Event) -> None: + """Continuously publish frames until stop_event is set.""" + pixel_count = WIDTH * HEIGHT + frame_idx = 0 + while not stop_event.is_set(): + fill = frame_idx % 256 + pixel = bytes((255, fill, (fill + 85) % 256, (fill + 170) % 256)) + buf = pixel * pixel_count + frame = rtc.VideoFrame(WIDTH, HEIGHT, rtc.VideoBufferType.ARGB, buf) + source.capture_frame(frame) + frame_idx += 1 + try: + await asyncio.wait_for(stop_event.wait(), timeout=1.0 / FRAME_RATE) + except asyncio.TimeoutError: + pass + + +@pytest.mark.asyncio +@skip_if_no_credentials() +async def test_e2ee_shared_key(): + """E2E test for shared-key E2EE. + + E2EE shared key E2E test: + 1. Publisher and two receivers connect with the same shared key. + 2. Publisher publishes a video track; receivers must observe + track_published and an OK e2ee_state. + 3. All participants must use GCM encryption. + 4. Publisher ratchets the shared key; receivers must observe + KEY_RATCHETED state. + 5. Publisher disables E2EE; receivers must observe DECRYPTION_FAILED. + 6. Publisher re-enables E2EE; receivers must observe OK again. + """ + room_name = unique_room_name("test-e2ee-shared-key") + url = os.getenv("LIVEKIT_URL") + + publisher_room = rtc.Room() + receiver1_room = rtc.Room() + receiver2_room = rtc.Room() + + publisher_token = create_token("e2eePublisher", room_name) + receiver1_token = create_token("receiver1", room_name) + receiver2_token = create_token("receiver2", room_name) + + # State tracked from event callbacks + track_published_on: dict[str, asyncio.Event] = { + "receiver1": asyncio.Event(), + "receiver2": asyncio.Event(), + } + track_subscribed_on: dict[str, asyncio.Event] = { + "receiver1": asyncio.Event(), + "receiver2": asyncio.Event(), + } + # all e2ee states seen for the publisher's identity (per receiver), since the + # last reset. KEY_RATCHETED in particular can be transient. + seen_e2ee_states: dict[str, set[int]] = { + "receiver1": set(), + "receiver2": set(), + } + e2ee_state_log: dict[str, list[int]] = { + "receiver1": [], + "receiver2": [], + } + + def wire_receiver(room: rtc.Room, label: str) -> None: + @room.on("track_published") + def _on_pub( + publication: rtc.RemoteTrackPublication, participant: rtc.RemoteParticipant + ) -> None: + track_published_on[label].set() + + @room.on("track_subscribed") + def _on_sub( + track: rtc.Track, + publication: rtc.RemoteTrackPublication, + participant: rtc.RemoteParticipant, + ) -> None: + track_subscribed_on[label].set() + + @room.on("e2ee_state_changed") + def _on_state(participant: rtc.Participant, state: int) -> None: + # only track state from the publisher's frames + if participant is not None and participant.identity == "e2eePublisher": + seen_e2ee_states[label].add(state) + e2ee_state_log[label].append(state) + + wire_receiver(receiver1_room, "receiver1") + wire_receiver(receiver2_room, "receiver2") + + publish_stop = asyncio.Event() + publish_task: asyncio.Task | None = None + + try: + connect_options = rtc.RoomOptions( + auto_subscribe=True, encryption=make_e2ee_options() + ) + + await publisher_room.connect(url, publisher_token, options=connect_options) + await receiver1_room.connect( + url, receiver1_token, options=rtc.RoomOptions( + auto_subscribe=True, encryption=make_e2ee_options() + ) + ) + await receiver2_room.connect( + url, receiver2_token, options=rtc.RoomOptions( + auto_subscribe=True, encryption=make_e2ee_options() + ) + ) + + # 1) all connected + for room in (publisher_room, receiver1_room, receiver2_room): + assert room.connection_state == rtc.ConnectionState.CONN_CONNECTED + + # 2) publish a video track from the publisher + source = rtc.VideoSource(WIDTH, HEIGHT) + track = rtc.LocalVideoTrack.create_video_track("e2ee-cam", source) + publish_options = rtc.TrackPublishOptions() + publish_options.source = rtc.TrackSource.SOURCE_CAMERA + publish_options.video_codec = rtc.VideoCodec.VP8 + publish_options.simulcast = True + publication = await publisher_room.local_participant.publish_track( + track, publish_options + ) + assert publication is not None and publication.sid + + publish_task = asyncio.create_task(publish_dummy_video(source, publish_stop)) + + # 3) receivers must observe track_published + await asyncio.wait_for(track_published_on["receiver1"].wait(), timeout=15.0) + await asyncio.wait_for(track_published_on["receiver2"].wait(), timeout=15.0) + + # 4) receivers must subscribe to the track + await asyncio.wait_for(track_subscribed_on["receiver1"].wait(), timeout=15.0) + await asyncio.wait_for(track_subscribed_on["receiver2"].wait(), timeout=15.0) + + # 5) wait for receivers to see an OK encryption state from the publisher + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver1"], + timeout=15.0, + message="receiver1 did not reach EncryptionState.OK", + ) + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver2"], + timeout=15.0, + message="receiver2 did not reach EncryptionState.OK", + ) + + # 6) verify all participants are using GCM on the published video track + def all_remote_video_pubs_gcm(room: rtc.Room) -> bool: + for rp in room.remote_participants.values(): + for pub in rp.track_publications.values(): + if pub.kind != rtc.TrackKind.KIND_VIDEO: + continue + if pub.encryption_type != rtc.EncryptionType.GCM: + return False + return True + + await assert_eventually( + lambda: all_remote_video_pubs_gcm(receiver1_room), + message="receiver1 sees a non-GCM video publication", + ) + await assert_eventually( + lambda: all_remote_video_pubs_gcm(receiver2_room), + message="receiver2 sees a non-GCM video publication", + ) + + # 7) ratchet the shared key on the publisher; receivers should ratchet too + seen_e2ee_states["receiver1"].clear() + seen_e2ee_states["receiver2"].clear() + e2ee_state_log["receiver1"].clear() + e2ee_state_log["receiver2"].clear() + await asyncio.sleep(1.0) + + key_provider = publisher_room.e2ee_manager.key_provider + assert key_provider is not None + key_provider.ratchet_shared_key(key_index=0) + + await assert_eventually( + lambda: rtc.EncryptionState.KEY_RATCHETED in seen_e2ee_states["receiver1"], + timeout=15.0, + message=( + "receiver1 did not observe KEY_RATCHETED after publisher ratchet " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.KEY_RATCHETED in seen_e2ee_states["receiver2"], + timeout=15.0, + message=( + "receiver2 did not observe KEY_RATCHETED after publisher ratchet " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + # 8) disable e2ee on the publisher; receivers should fail to decrypt + seen_e2ee_states["receiver1"].clear() + seen_e2ee_states["receiver2"].clear() + e2ee_state_log["receiver1"].clear() + e2ee_state_log["receiver2"].clear() + await asyncio.sleep(1.0) + + publisher_room.e2ee_manager.set_enabled(False) + + await assert_eventually( + lambda: rtc.EncryptionState.DECRYPTION_FAILED in seen_e2ee_states["receiver1"], + timeout=15.0, + message=( + "receiver1 did not observe DECRYPTION_FAILED after publisher disabled e2ee " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.DECRYPTION_FAILED in seen_e2ee_states["receiver2"], + timeout=15.0, + message=( + "receiver2 did not observe DECRYPTION_FAILED after publisher disabled e2ee " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + # 9) re-enable e2ee on the publisher; receivers should reach OK again + seen_e2ee_states["receiver1"].clear() + seen_e2ee_states["receiver2"].clear() + e2ee_state_log["receiver1"].clear() + e2ee_state_log["receiver2"].clear() + await asyncio.sleep(1.0) + + publisher_room.e2ee_manager.set_enabled(True) + + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver1"], + timeout=15.0, + message=( + "receiver1 did not return to EncryptionState.OK after re-enable " + f"(saw {e2ee_state_log['receiver1']})" + ), + ) + await assert_eventually( + lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver2"], + timeout=15.0, + message=( + "receiver2 did not return to EncryptionState.OK after re-enable " + f"(saw {e2ee_state_log['receiver2']})" + ), + ) + + finally: + publish_stop.set() + if publish_task is not None: + try: + await asyncio.wait_for(publish_task, timeout=2.0) + except (asyncio.TimeoutError, asyncio.CancelledError): + publish_task.cancel() + + for room in (publisher_room, receiver1_room, receiver2_room): + if room.isconnected(): + await room.disconnect() From f3d3407be32e782c14b75f3f241a59ed81e03193 Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 11 May 2026 10:09:31 +0800 Subject: [PATCH 2/4] uvx ruff format. --- .../tests/test_e2ee_per_participant.py | 16 +++++---------- livekit-rtc/tests/test_e2ee_shared_key.py | 20 ++++++++----------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/livekit-rtc/tests/test_e2ee_per_participant.py b/livekit-rtc/tests/test_e2ee_per_participant.py index 25a98ff9..66d5a98f 100644 --- a/livekit-rtc/tests/test_e2ee_per_participant.py +++ b/livekit-rtc/tests/test_e2ee_per_participant.py @@ -230,9 +230,7 @@ def _on_state(participant: rtc.Participant, state: int) -> None: publish_options.source = rtc.TrackSource.SOURCE_CAMERA publish_options.video_codec = rtc.VideoCodec.VP8 publish_options.simulcast = True - publication = await publisher_room.local_participant.publish_track( - track, publish_options - ) + publication = await publisher_room.local_participant.publish_track(track, publish_options) assert publication is not None and publication.sid publish_task = asyncio.create_task(publish_dummy_video(source, publish_stop)) @@ -247,15 +245,13 @@ def _on_state(participant: rtc.Participant, state: int) -> None: await assert_eventually( lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver1"], message=( - "receiver1 did not reach EncryptionState.OK " - f"(saw {e2ee_state_log['receiver1']})" + f"receiver1 did not reach EncryptionState.OK (saw {e2ee_state_log['receiver1']})" ), ) await assert_eventually( lambda: rtc.EncryptionState.OK in seen_e2ee_states["receiver2"], message=( - "receiver2 did not reach EncryptionState.OK " - f"(saw {e2ee_state_log['receiver2']})" + f"receiver2 did not reach EncryptionState.OK (saw {e2ee_state_log['receiver2']})" ), ) @@ -317,15 +313,13 @@ def all_remote_video_pubs_gcm(room: rtc.Room) -> bool: await assert_eventually( lambda: rtc.EncryptionState.DECRYPTION_FAILED in seen_e2ee_states["receiver1"], message=( - "receiver1 did not observe DECRYPTION_FAILED " - f"(saw {e2ee_state_log['receiver1']})" + f"receiver1 did not observe DECRYPTION_FAILED (saw {e2ee_state_log['receiver1']})" ), ) await assert_eventually( lambda: rtc.EncryptionState.DECRYPTION_FAILED in seen_e2ee_states["receiver2"], message=( - "receiver2 did not observe DECRYPTION_FAILED " - f"(saw {e2ee_state_log['receiver2']})" + f"receiver2 did not observe DECRYPTION_FAILED (saw {e2ee_state_log['receiver2']})" ), ) diff --git a/livekit-rtc/tests/test_e2ee_shared_key.py b/livekit-rtc/tests/test_e2ee_shared_key.py index 48681ae9..04d23108 100644 --- a/livekit-rtc/tests/test_e2ee_shared_key.py +++ b/livekit-rtc/tests/test_e2ee_shared_key.py @@ -175,20 +175,18 @@ def _on_state(participant: rtc.Participant, state: int) -> None: publish_task: asyncio.Task | None = None try: - connect_options = rtc.RoomOptions( - auto_subscribe=True, encryption=make_e2ee_options() - ) + connect_options = rtc.RoomOptions(auto_subscribe=True, encryption=make_e2ee_options()) await publisher_room.connect(url, publisher_token, options=connect_options) await receiver1_room.connect( - url, receiver1_token, options=rtc.RoomOptions( - auto_subscribe=True, encryption=make_e2ee_options() - ) + url, + receiver1_token, + options=rtc.RoomOptions(auto_subscribe=True, encryption=make_e2ee_options()), ) await receiver2_room.connect( - url, receiver2_token, options=rtc.RoomOptions( - auto_subscribe=True, encryption=make_e2ee_options() - ) + url, + receiver2_token, + options=rtc.RoomOptions(auto_subscribe=True, encryption=make_e2ee_options()), ) # 1) all connected @@ -202,9 +200,7 @@ def _on_state(participant: rtc.Participant, state: int) -> None: publish_options.source = rtc.TrackSource.SOURCE_CAMERA publish_options.video_codec = rtc.VideoCodec.VP8 publish_options.simulcast = True - publication = await publisher_room.local_participant.publish_track( - track, publish_options - ) + publication = await publisher_room.local_participant.publish_track(track, publish_options) assert publication is not None and publication.sid publish_task = asyncio.create_task(publish_dummy_video(source, publish_stop)) From 4bfc30cf4c5265153524435c433048807774b66c Mon Sep 17 00:00:00 2001 From: cloudwebrtc Date: Mon, 11 May 2026 11:00:19 +0800 Subject: [PATCH 3/4] bump rust-sdks. --- livekit-rtc/rust-sdks | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/livekit-rtc/rust-sdks b/livekit-rtc/rust-sdks index 2ea09e6e..b384a6f9 160000 --- a/livekit-rtc/rust-sdks +++ b/livekit-rtc/rust-sdks @@ -1 +1 @@ -Subproject commit 2ea09e6e5b7cc22f0fb8066bd6f0637a5ed38f08 +Subproject commit b384a6f9bd872ef5cbfd369dbc6294ec61d7031d From 206a35e399e51c7bf09713e4d0e5e8aa32dd18bb Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 04:11:00 +0000 Subject: [PATCH 4/4] generated protobuf --- livekit-rtc/livekit/rtc/_proto/room_pb2.py | 298 ++++++++++---------- livekit-rtc/livekit/rtc/_proto/room_pb2.pyi | 42 +-- 2 files changed, 151 insertions(+), 189 deletions(-) diff --git a/livekit-rtc/livekit/rtc/_proto/room_pb2.py b/livekit-rtc/livekit/rtc/_proto/room_pb2.py index 8f1a6c51..dd224581 100644 --- a/livekit-rtc/livekit/rtc/_proto/room_pb2.py +++ b/livekit-rtc/livekit/rtc/_proto/room_pb2.py @@ -22,7 +22,7 @@ from . import data_track_pb2 as data__track__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nroom.proto\x12\rlivekit.proto\x1a\ne2ee.proto\x1a\x0chandle.proto\x1a\x11participant.proto\x1a\x0btrack.proto\x1a\x11video_frame.proto\x1a\x0bstats.proto\x1a\x11\x64\x61ta_stream.proto\x1a\x10\x64\x61ta_track.proto\"s\n\x0e\x43onnectRequest\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\r\n\x05token\x18\x02 \x02(\t\x12+\n\x07options\x18\x03 \x02(\x0b\x32\x1a.livekit.proto.RoomOptions\x12\x18\n\x10request_async_id\x18\x04 \x01(\x04\"#\n\x0f\x43onnectResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\xbf\x03\n\x0f\x43onnectCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12\x37\n\x06result\x18\x03 \x01(\x0b\x32%.livekit.proto.ConnectCallback.ResultH\x00\x1a\x89\x01\n\x15ParticipantWithTracks\x12\x34\n\x0bparticipant\x18\x01 \x02(\x0b\x32\x1f.livekit.proto.OwnedParticipant\x12:\n\x0cpublications\x18\x02 \x03(\x0b\x32$.livekit.proto.OwnedTrackPublication\x1a\xb8\x01\n\x06Result\x12&\n\x04room\x18\x01 \x02(\x0b\x32\x18.livekit.proto.OwnedRoom\x12:\n\x11local_participant\x18\x02 \x02(\x0b\x32\x1f.livekit.proto.OwnedParticipant\x12J\n\x0cparticipants\x18\x03 \x03(\x0b\x32\x34.livekit.proto.ConnectCallback.ParticipantWithTracksB\t\n\x07message\"s\n\x11\x44isconnectRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x18\n\x10request_async_id\x18\x02 \x01(\x04\x12/\n\x06reason\x18\x03 \x01(\x0e\x32\x1f.livekit.proto.DisconnectReason\"&\n\x12\x44isconnectResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"&\n\x12\x44isconnectCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\x7f\n\x17SimulateScenarioRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x35\n\x08scenario\x18\x02 \x02(\x0e\x32#.livekit.proto.SimulateScenarioKind\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\",\n\x18SimulateScenarioResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\";\n\x18SimulateScenarioCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x9c\x01\n\x13PublishTrackRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x14\n\x0ctrack_handle\x18\x02 \x02(\x04\x12\x33\n\x07options\x18\x03 \x02(\x0b\x32\".livekit.proto.TrackPublishOptions\x12\x18\n\x10request_async_id\x18\x04 \x01(\x04\"(\n\x14PublishTrackResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\x81\x01\n\x14PublishTrackCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12;\n\x0bpublication\x18\x03 \x01(\x0b\x32$.livekit.proto.OwnedTrackPublicationH\x00\x42\t\n\x07message\"\x81\x01\n\x15UnpublishTrackRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\x12\x19\n\x11stop_on_unpublish\x18\x03 \x02(\x08\x12\x18\n\x10request_async_id\x18\x04 \x01(\x04\"*\n\x16UnpublishTrackResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"9\n\x16UnpublishTrackCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\xd3\x01\n\x12PublishDataRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x10\n\x08\x64\x61ta_ptr\x18\x02 \x02(\x04\x12\x10\n\x08\x64\x61ta_len\x18\x03 \x02(\x04\x12\x10\n\x08reliable\x18\x04 \x02(\x08\x12\x1c\n\x10\x64\x65stination_sids\x18\x05 \x03(\tB\x02\x18\x01\x12\r\n\x05topic\x18\x06 \x01(\t\x12\x1e\n\x16\x64\x65stination_identities\x18\x07 \x03(\t\x12\x18\n\x10request_async_id\x18\x08 \x01(\x04\"\'\n\x13PublishDataResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"6\n\x13PublishDataCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\xc0\x01\n\x1bPublishTranscriptionRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\x12\x10\n\x08track_id\x18\x03 \x02(\t\x12\x35\n\x08segments\x18\x04 \x03(\x0b\x32#.livekit.proto.TranscriptionSegment\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"0\n\x1cPublishTranscriptionResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"?\n\x1cPublishTranscriptionCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x90\x01\n\x15PublishSipDtmfRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0c\n\x04\x63ode\x18\x02 \x02(\r\x12\r\n\x05\x64igit\x18\x03 \x02(\t\x12\x1e\n\x16\x64\x65stination_identities\x18\x04 \x03(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"*\n\x16PublishSipDtmfResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"9\n\x16PublishSipDtmfCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"g\n\x17SetLocalMetadataRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x10\n\x08metadata\x18\x02 \x02(\t\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\",\n\x18SetLocalMetadataResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\";\n\x18SetLocalMetadataCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x9e\x01\n\x16SendChatMessageRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0f\n\x07message\x18\x02 \x02(\t\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x01(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"\xd6\x01\n\x16\x45\x64itChatMessageRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x11\n\tedit_text\x18\x02 \x02(\t\x12\x34\n\x10original_message\x18\x03 \x02(\x0b\x32\x1a.livekit.proto.ChatMessage\x12\x1e\n\x16\x64\x65stination_identities\x18\x04 \x03(\t\x12\x17\n\x0fsender_identity\x18\x05 \x01(\t\x12\x18\n\x10request_async_id\x18\x06 \x01(\x04\"+\n\x17SendChatMessageResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"{\n\x17SendChatMessageCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12\x32\n\x0c\x63hat_message\x18\x03 \x01(\x0b\x32\x1a.livekit.proto.ChatMessageH\x00\x42\t\n\x07message\"\x8b\x01\n\x19SetLocalAttributesRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x32\n\nattributes\x18\x02 \x03(\x0b\x32\x1e.livekit.proto.AttributesEntry\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\"-\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x02(\t\x12\r\n\x05value\x18\x02 \x02(\t\".\n\x1aSetLocalAttributesResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"=\n\x1aSetLocalAttributesCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"_\n\x13SetLocalNameRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0c\n\x04name\x18\x02 \x02(\t\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\"(\n\x14SetLocalNameResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"7\n\x14SetLocalNameCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"E\n\x14SetSubscribedRequest\x12\x11\n\tsubscribe\x18\x01 \x02(\x08\x12\x1a\n\x12publication_handle\x18\x02 \x02(\x04\"\x17\n\x15SetSubscribedResponse\"G\n\x16GetSessionStatsRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x18\n\x10request_async_id\x18\x02 \x01(\x04\"+\n\x17GetSessionStatsResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\xf7\x01\n\x17GetSessionStatsCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12?\n\x06result\x18\x03 \x01(\x0b\x32-.livekit.proto.GetSessionStatsCallback.ResultH\x00\x1am\n\x06Result\x12\x30\n\x0fpublisher_stats\x18\x01 \x03(\x0b\x32\x17.livekit.proto.RtcStats\x12\x31\n\x10subscriber_stats\x18\x02 \x03(\x0b\x32\x17.livekit.proto.RtcStatsB\t\n\x07message\";\n\rVideoEncoding\x12\x13\n\x0bmax_bitrate\x18\x01 \x02(\x04\x12\x15\n\rmax_framerate\x18\x02 \x02(\x01\"$\n\rAudioEncoding\x12\x13\n\x0bmax_bitrate\x18\x01 \x02(\x04\"\xfb\x02\n\x13TrackPublishOptions\x12\x34\n\x0evideo_encoding\x18\x01 \x01(\x0b\x32\x1c.livekit.proto.VideoEncoding\x12\x34\n\x0e\x61udio_encoding\x18\x02 \x01(\x0b\x32\x1c.livekit.proto.AudioEncoding\x12.\n\x0bvideo_codec\x18\x03 \x01(\x0e\x32\x19.livekit.proto.VideoCodec\x12\x0b\n\x03\x64tx\x18\x04 \x01(\x08\x12\x0b\n\x03red\x18\x05 \x01(\x08\x12\x11\n\tsimulcast\x18\x06 \x01(\x08\x12*\n\x06source\x18\x07 \x01(\x0e\x32\x1a.livekit.proto.TrackSource\x12\x0e\n\x06stream\x18\x08 \x01(\t\x12\x19\n\x11preconnect_buffer\x18\t \x01(\x08\x12\x44\n\x17packet_trailer_features\x18\n \x03(\x0e\x32#.livekit.proto.PacketTrailerFeature\"=\n\tIceServer\x12\x0c\n\x04urls\x18\x01 \x03(\t\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x10\n\x08password\x18\x03 \x01(\t\"\xc4\x01\n\tRtcConfig\x12;\n\x12ice_transport_type\x18\x01 \x01(\x0e\x32\x1f.livekit.proto.IceTransportType\x12K\n\x1a\x63ontinual_gathering_policy\x18\x02 \x01(\x0e\x32\'.livekit.proto.ContinualGatheringPolicy\x12-\n\x0bice_servers\x18\x03 \x03(\x0b\x32\x18.livekit.proto.IceServer\"\xae\x02\n\x0bRoomOptions\x12\x16\n\x0e\x61uto_subscribe\x18\x01 \x01(\x08\x12\x17\n\x0f\x61\x64\x61ptive_stream\x18\x02 \x01(\x08\x12\x10\n\x08\x64ynacast\x18\x03 \x01(\x08\x12,\n\x04\x65\x32\x65\x65\x18\x04 \x01(\x0b\x32\x1a.livekit.proto.E2eeOptionsB\x02\x18\x01\x12,\n\nrtc_config\x18\x05 \x01(\x0b\x32\x18.livekit.proto.RtcConfig\x12\x14\n\x0cjoin_retries\x18\x06 \x01(\r\x12.\n\nencryption\x18\x07 \x01(\x0b\x32\x1a.livekit.proto.E2eeOptions\x12\x1e\n\x16single_peer_connection\x18\x08 \x01(\x08\x12\x1a\n\x12\x63onnect_timeout_ms\x18\t \x01(\x04\"w\n\x14TranscriptionSegment\x12\n\n\x02id\x18\x01 \x02(\t\x12\x0c\n\x04text\x18\x02 \x02(\t\x12\x12\n\nstart_time\x18\x03 \x02(\x04\x12\x10\n\x08\x65nd_time\x18\x04 \x02(\x04\x12\r\n\x05\x66inal\x18\x05 \x02(\x08\x12\x10\n\x08language\x18\x06 \x02(\t\"0\n\nBufferInfo\x12\x10\n\x08\x64\x61ta_ptr\x18\x01 \x02(\x04\x12\x10\n\x08\x64\x61ta_len\x18\x02 \x02(\x04\"e\n\x0bOwnedBuffer\x12-\n\x06handle\x18\x01 \x02(\x0b\x32\x1d.livekit.proto.FfiOwnedHandle\x12\'\n\x04\x64\x61ta\x18\x02 \x02(\x0b\x32\x19.livekit.proto.BufferInfo\"\xce\x17\n\tRoomEvent\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x44\n\x15participant_connected\x18\x02 \x01(\x0b\x32#.livekit.proto.ParticipantConnectedH\x00\x12J\n\x18participant_disconnected\x18\x03 \x01(\x0b\x32&.livekit.proto.ParticipantDisconnectedH\x00\x12\x43\n\x15local_track_published\x18\x04 \x01(\x0b\x32\".livekit.proto.LocalTrackPublishedH\x00\x12G\n\x17local_track_unpublished\x18\x05 \x01(\x0b\x32$.livekit.proto.LocalTrackUnpublishedH\x00\x12\x45\n\x16local_track_subscribed\x18\x06 \x01(\x0b\x32#.livekit.proto.LocalTrackSubscribedH\x00\x12\x38\n\x0ftrack_published\x18\x07 \x01(\x0b\x32\x1d.livekit.proto.TrackPublishedH\x00\x12<\n\x11track_unpublished\x18\x08 \x01(\x0b\x32\x1f.livekit.proto.TrackUnpublishedH\x00\x12:\n\x10track_subscribed\x18\t \x01(\x0b\x32\x1e.livekit.proto.TrackSubscribedH\x00\x12>\n\x12track_unsubscribed\x18\n \x01(\x0b\x32 .livekit.proto.TrackUnsubscribedH\x00\x12K\n\x19track_subscription_failed\x18\x0b \x01(\x0b\x32&.livekit.proto.TrackSubscriptionFailedH\x00\x12\x30\n\x0btrack_muted\x18\x0c \x01(\x0b\x32\x19.livekit.proto.TrackMutedH\x00\x12\x34\n\rtrack_unmuted\x18\r \x01(\x0b\x32\x1b.livekit.proto.TrackUnmutedH\x00\x12G\n\x17\x61\x63tive_speakers_changed\x18\x0e \x01(\x0b\x32$.livekit.proto.ActiveSpeakersChangedH\x00\x12\x43\n\x15room_metadata_changed\x18\x0f \x01(\x0b\x32\".livekit.proto.RoomMetadataChangedH\x00\x12\x39\n\x10room_sid_changed\x18\x10 \x01(\x0b\x32\x1d.livekit.proto.RoomSidChangedH\x00\x12Q\n\x1cparticipant_metadata_changed\x18\x11 \x01(\x0b\x32).livekit.proto.ParticipantMetadataChangedH\x00\x12I\n\x18participant_name_changed\x18\x12 \x01(\x0b\x32%.livekit.proto.ParticipantNameChangedH\x00\x12U\n\x1eparticipant_attributes_changed\x18\x13 \x01(\x0b\x32+.livekit.proto.ParticipantAttributesChangedH\x00\x12M\n\x1a\x63onnection_quality_changed\x18\x14 \x01(\x0b\x32\'.livekit.proto.ConnectionQualityChangedH\x00\x12I\n\x18\x63onnection_state_changed\x18\x15 \x01(\x0b\x32%.livekit.proto.ConnectionStateChangedH\x00\x12\x33\n\x0c\x64isconnected\x18\x16 \x01(\x0b\x32\x1b.livekit.proto.DisconnectedH\x00\x12\x33\n\x0creconnecting\x18\x17 \x01(\x0b\x32\x1b.livekit.proto.ReconnectingH\x00\x12\x31\n\x0breconnected\x18\x18 \x01(\x0b\x32\x1a.livekit.proto.ReconnectedH\x00\x12=\n\x12\x65\x32\x65\x65_state_changed\x18\x19 \x01(\x0b\x32\x1f.livekit.proto.E2eeStateChangedH\x00\x12%\n\x03\x65os\x18\x1a \x01(\x0b\x32\x16.livekit.proto.RoomEOSH\x00\x12\x41\n\x14\x64\x61ta_packet_received\x18\x1b \x01(\x0b\x32!.livekit.proto.DataPacketReceivedH\x00\x12\x46\n\x16transcription_received\x18\x1c \x01(\x0b\x32$.livekit.proto.TranscriptionReceivedH\x00\x12:\n\x0c\x63hat_message\x18\x1d \x01(\x0b\x32\".livekit.proto.ChatMessageReceivedH\x00\x12I\n\x16stream_header_received\x18\x1e \x01(\x0b\x32\'.livekit.proto.DataStreamHeaderReceivedH\x00\x12G\n\x15stream_chunk_received\x18\x1f \x01(\x0b\x32&.livekit.proto.DataStreamChunkReceivedH\x00\x12K\n\x17stream_trailer_received\x18 \x01(\x0b\x32(.livekit.proto.DataStreamTrailerReceivedH\x00\x12i\n\"data_channel_low_threshold_changed\x18! \x01(\x0b\x32;.livekit.proto.DataChannelBufferedAmountLowThresholdChangedH\x00\x12=\n\x12\x62yte_stream_opened\x18\" \x01(\x0b\x32\x1f.livekit.proto.ByteStreamOpenedH\x00\x12=\n\x12text_stream_opened\x18# \x01(\x0b\x32\x1f.livekit.proto.TextStreamOpenedH\x00\x12/\n\x0croom_updated\x18$ \x01(\x0b\x32\x17.livekit.proto.RoomInfoH\x00\x12(\n\x05moved\x18% \x01(\x0b\x32\x17.livekit.proto.RoomInfoH\x00\x12\x42\n\x14participants_updated\x18& \x01(\x0b\x32\".livekit.proto.ParticipantsUpdatedH\x00\x12\x62\n%participant_encryption_status_changed\x18\' \x01(\x0b\x32\x31.livekit.proto.ParticipantEncryptionStatusChangedH\x00\x12U\n\x1eparticipant_permission_changed\x18) \x01(\x0b\x32+.livekit.proto.ParticipantPermissionChangedH\x00\x12\x38\n\x0ftoken_refreshed\x18( \x01(\x0b\x32\x1d.livekit.proto.TokenRefreshedH\x00\x12>\n\x12participant_active\x18* \x01(\x0b\x32 .livekit.proto.ParticipantActiveH\x00\x12\x41\n\x14\x64\x61ta_track_published\x18+ \x01(\x0b\x32!.livekit.proto.DataTrackPublishedH\x00\x12\x45\n\x16\x64\x61ta_track_unpublished\x18, \x01(\x0b\x32#.livekit.proto.DataTrackUnpublishedH\x00\x12G\n\x17local_track_republished\x18- \x01(\x0b\x32$.livekit.proto.LocalTrackRepublishedH\x00\x42\t\n\x07message\"\xc9\x02\n\x08RoomInfo\x12\x0b\n\x03sid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x02(\t\x12\x10\n\x08metadata\x18\x03 \x02(\t\x12.\n&lossy_dc_buffered_amount_low_threshold\x18\x04 \x02(\x04\x12\x31\n)reliable_dc_buffered_amount_low_threshold\x18\x05 \x02(\x04\x12\x15\n\rempty_timeout\x18\x06 \x02(\r\x12\x19\n\x11\x64\x65parture_timeout\x18\x07 \x02(\r\x12\x18\n\x10max_participants\x18\x08 \x02(\r\x12\x15\n\rcreation_time\x18\t \x02(\x03\x12\x18\n\x10num_participants\x18\n \x02(\r\x12\x16\n\x0enum_publishers\x18\x0b \x02(\r\x12\x18\n\x10\x61\x63tive_recording\x18\x0c \x02(\x08\"a\n\tOwnedRoom\x12-\n\x06handle\x18\x01 \x02(\x0b\x32\x1d.livekit.proto.FfiOwnedHandle\x12%\n\x04info\x18\x02 \x02(\x0b\x32\x17.livekit.proto.RoomInfo\"K\n\x13ParticipantsUpdated\x12\x34\n\x0cparticipants\x18\x01 \x03(\x0b\x32\x1e.livekit.proto.ParticipantInfo\"E\n\x14ParticipantConnected\x12-\n\x04info\x18\x01 \x02(\x0b\x32\x1f.livekit.proto.OwnedParticipant\"1\n\x11ParticipantActive\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\"s\n\x17ParticipantDisconnected\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12:\n\x11\x64isconnect_reason\x18\x02 \x02(\x0e\x32\x1f.livekit.proto.DisconnectReason\"(\n\x13LocalTrackPublished\x12\x11\n\ttrack_sid\x18\x01 \x02(\t\"0\n\x15LocalTrackUnpublished\x12\x17\n\x0fpublication_sid\x18\x01 \x02(\t\"|\n\x15LocalTrackRepublished\x12\x1a\n\x12publication_handle\x18\x01 \x02(\x04\x12\x14\n\x0cprevious_sid\x18\x02 \x02(\t\x12\x31\n\x04info\x18\x03 \x02(\x0b\x32#.livekit.proto.TrackPublicationInfo\")\n\x14LocalTrackSubscribed\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"i\n\x0eTrackPublished\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x39\n\x0bpublication\x18\x02 \x02(\x0b\x32$.livekit.proto.OwnedTrackPublication\"I\n\x10TrackUnpublished\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x17\n\x0fpublication_sid\x18\x02 \x02(\t\"Y\n\x0fTrackSubscribed\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12(\n\x05track\x18\x02 \x02(\x0b\x32\x19.livekit.proto.OwnedTrack\"D\n\x11TrackUnsubscribed\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"Y\n\x17TrackSubscriptionFailed\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\x12\r\n\x05\x65rror\x18\x03 \x02(\t\"=\n\nTrackMuted\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"?\n\x0cTrackUnmuted\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"_\n\x10\x45\x32\x65\x65StateChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12-\n\x05state\x18\x02 \x02(\x0e\x32\x1e.livekit.proto.EncryptionState\"7\n\x15\x41\x63tiveSpeakersChanged\x12\x1e\n\x16participant_identities\x18\x01 \x03(\t\"\'\n\x13RoomMetadataChanged\x12\x10\n\x08metadata\x18\x01 \x02(\t\"\x1d\n\x0eRoomSidChanged\x12\x0b\n\x03sid\x18\x01 \x02(\t\"L\n\x1aParticipantMetadataChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x10\n\x08metadata\x18\x02 \x02(\t\"\xac\x01\n\x1cParticipantAttributesChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x32\n\nattributes\x18\x02 \x03(\x0b\x32\x1e.livekit.proto.AttributesEntry\x12:\n\x12\x63hanged_attributes\x18\x03 \x03(\x0b\x32\x1e.livekit.proto.AttributesEntry\"X\n\"ParticipantEncryptionStatusChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x14\n\x0cis_encrypted\x18\x02 \x02(\x08\"D\n\x16ParticipantNameChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x0c\n\x04name\x18\x02 \x02(\t\"v\n\x1cParticipantPermissionChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x38\n\npermission\x18\x02 \x01(\x0b\x32$.livekit.proto.ParticipantPermission\"k\n\x18\x43onnectionQualityChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x31\n\x07quality\x18\x02 \x02(\x0e\x32 .livekit.proto.ConnectionQuality\"E\n\nUserPacket\x12(\n\x04\x64\x61ta\x18\x01 \x02(\x0b\x32\x1a.livekit.proto.OwnedBuffer\x12\r\n\x05topic\x18\x02 \x01(\t\"y\n\x0b\x43hatMessage\x12\n\n\x02id\x18\x01 \x02(\t\x12\x11\n\ttimestamp\x18\x02 \x02(\x03\x12\x0f\n\x07message\x18\x03 \x02(\t\x12\x16\n\x0e\x65\x64it_timestamp\x18\x04 \x01(\x03\x12\x0f\n\x07\x64\x65leted\x18\x05 \x01(\x08\x12\x11\n\tgenerated\x18\x06 \x01(\x08\"`\n\x13\x43hatMessageReceived\x12+\n\x07message\x18\x01 \x02(\x0b\x32\x1a.livekit.proto.ChatMessage\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\"&\n\x07SipDTMF\x12\x0c\n\x04\x63ode\x18\x01 \x02(\r\x12\r\n\x05\x64igit\x18\x02 \x01(\t\"\xbf\x01\n\x12\x44\x61taPacketReceived\x12+\n\x04kind\x18\x01 \x02(\x0e\x32\x1d.livekit.proto.DataPacketKind\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\x12)\n\x04user\x18\x04 \x01(\x0b\x32\x19.livekit.proto.UserPacketH\x00\x12*\n\x08sip_dtmf\x18\x05 \x01(\x0b\x32\x16.livekit.proto.SipDTMFH\x00\x42\x07\n\x05value\"\x7f\n\x15TranscriptionReceived\x12\x1c\n\x14participant_identity\x18\x01 \x01(\t\x12\x11\n\ttrack_sid\x18\x02 \x01(\t\x12\x35\n\x08segments\x18\x03 \x03(\x0b\x32#.livekit.proto.TranscriptionSegment\"G\n\x16\x43onnectionStateChanged\x12-\n\x05state\x18\x01 \x02(\x0e\x32\x1e.livekit.proto.ConnectionState\"\x0b\n\tConnected\"?\n\x0c\x44isconnected\x12/\n\x06reason\x18\x01 \x02(\x0e\x32\x1f.livekit.proto.DisconnectReason\"\x0e\n\x0cReconnecting\"\r\n\x0bReconnected\"\x1f\n\x0eTokenRefreshed\x12\r\n\x05token\x18\x01 \x02(\t\"\t\n\x07RoomEOS\"\x8e\x07\n\nDataStream\x1a\xaa\x01\n\nTextHeader\x12?\n\x0eoperation_type\x18\x01 \x02(\x0e\x32\'.livekit.proto.DataStream.OperationType\x12\x0f\n\x07version\x18\x02 \x01(\x05\x12\x1a\n\x12reply_to_stream_id\x18\x03 \x01(\t\x12\x1b\n\x13\x61ttached_stream_ids\x18\x04 \x03(\t\x12\x11\n\tgenerated\x18\x05 \x01(\x08\x1a\x1a\n\nByteHeader\x12\x0c\n\x04name\x18\x01 \x02(\t\x1a\xeb\x02\n\x06Header\x12\x11\n\tstream_id\x18\x01 \x02(\t\x12\x11\n\ttimestamp\x18\x02 \x02(\x03\x12\x11\n\tmime_type\x18\x03 \x02(\t\x12\r\n\x05topic\x18\x04 \x02(\t\x12\x14\n\x0ctotal_length\x18\x05 \x01(\x04\x12\x44\n\nattributes\x18\x06 \x03(\x0b\x32\x30.livekit.proto.DataStream.Header.AttributesEntry\x12;\n\x0btext_header\x18\x07 \x01(\x0b\x32$.livekit.proto.DataStream.TextHeaderH\x00\x12;\n\x0b\x62yte_header\x18\x08 \x01(\x0b\x32$.livekit.proto.DataStream.ByteHeaderH\x00\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x10\n\x0e\x63ontent_header\x1a]\n\x05\x43hunk\x12\x11\n\tstream_id\x18\x01 \x02(\t\x12\x13\n\x0b\x63hunk_index\x18\x02 \x02(\x04\x12\x0f\n\x07\x63ontent\x18\x03 \x02(\x0c\x12\x0f\n\x07version\x18\x04 \x01(\x05\x12\n\n\x02iv\x18\x05 \x01(\x0c\x1a\xa6\x01\n\x07Trailer\x12\x11\n\tstream_id\x18\x01 \x02(\t\x12\x0e\n\x06reason\x18\x02 \x02(\t\x12\x45\n\nattributes\x18\x03 \x03(\x0b\x32\x31.livekit.proto.DataStream.Trailer.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"A\n\rOperationType\x12\n\n\x06\x43REATE\x10\x00\x12\n\n\x06UPDATE\x10\x01\x12\n\n\x06\x44\x45LETE\x10\x02\x12\x0c\n\x08REACTION\x10\x03\"j\n\x18\x44\x61taStreamHeaderReceived\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x30\n\x06header\x18\x02 \x02(\x0b\x32 .livekit.proto.DataStream.Header\"g\n\x17\x44\x61taStreamChunkReceived\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12.\n\x05\x63hunk\x18\x02 \x02(\x0b\x32\x1f.livekit.proto.DataStream.Chunk\"m\n\x19\x44\x61taStreamTrailerReceived\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x32\n\x07trailer\x18\x02 \x02(\x0b\x32!.livekit.proto.DataStream.Trailer\"\xc0\x01\n\x17SendStreamHeaderRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x30\n\x06header\x18\x02 \x02(\x0b\x32 .livekit.proto.DataStream.Header\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x02(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"\xbd\x01\n\x16SendStreamChunkRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12.\n\x05\x63hunk\x18\x02 \x02(\x0b\x32\x1f.livekit.proto.DataStream.Chunk\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x02(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"\xc3\x01\n\x18SendStreamTrailerRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x32\n\x07trailer\x18\x02 \x02(\x0b\x32!.livekit.proto.DataStream.Trailer\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x02(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\",\n\x18SendStreamHeaderResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"+\n\x17SendStreamChunkResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"-\n\x19SendStreamTrailerResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\";\n\x18SendStreamHeaderCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\":\n\x17SendStreamChunkCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"<\n\x19SendStreamTrailerCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x93\x01\n/SetDataChannelBufferedAmountLowThresholdRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x11\n\tthreshold\x18\x02 \x02(\x04\x12+\n\x04kind\x18\x03 \x02(\x0e\x32\x1d.livekit.proto.DataPacketKind\"2\n0SetDataChannelBufferedAmountLowThresholdResponse\"n\n,DataChannelBufferedAmountLowThresholdChanged\x12+\n\x04kind\x18\x01 \x02(\x0e\x32\x1d.livekit.proto.DataPacketKind\x12\x11\n\tthreshold\x18\x02 \x02(\x04\"f\n\x10\x42yteStreamOpened\x12\x34\n\x06reader\x18\x01 \x02(\x0b\x32$.livekit.proto.OwnedByteStreamReader\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\"f\n\x10TextStreamOpened\x12\x34\n\x06reader\x18\x01 \x02(\x0b\x32$.livekit.proto.OwnedTextStreamReader\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\"H\n\x12\x44\x61taTrackPublished\x12\x32\n\x05track\x18\x01 \x02(\x0b\x32#.livekit.proto.OwnedRemoteDataTrack\"#\n\x14\x44\x61taTrackUnpublished\x12\x0b\n\x03sid\x18\x01 \x02(\t*\xe6\x01\n\x14SimulateScenarioKind\x12\x1d\n\x19SIMULATE_SIGNAL_RECONNECT\x10\x00\x12\x14\n\x10SIMULATE_SPEAKER\x10\x01\x12\x19\n\x15SIMULATE_NODE_FAILURE\x10\x02\x12\x19\n\x15SIMULATE_SERVER_LEAVE\x10\x03\x12\x16\n\x12SIMULATE_MIGRATION\x10\x04\x12\x16\n\x12SIMULATE_FORCE_TCP\x10\x05\x12\x16\n\x12SIMULATE_FORCE_TLS\x10\x06\x12\x1b\n\x17SIMULATE_FULL_RECONNECT\x10\x07*P\n\x10IceTransportType\x12\x13\n\x0fTRANSPORT_RELAY\x10\x00\x12\x14\n\x10TRANSPORT_NOHOST\x10\x01\x12\x11\n\rTRANSPORT_ALL\x10\x02*C\n\x18\x43ontinualGatheringPolicy\x12\x0f\n\x0bGATHER_ONCE\x10\x00\x12\x16\n\x12GATHER_CONTINUALLY\x10\x01*`\n\x11\x43onnectionQuality\x12\x10\n\x0cQUALITY_POOR\x10\x00\x12\x10\n\x0cQUALITY_GOOD\x10\x01\x12\x15\n\x11QUALITY_EXCELLENT\x10\x02\x12\x10\n\x0cQUALITY_LOST\x10\x03*S\n\x0f\x43onnectionState\x12\x15\n\x11\x43ONN_DISCONNECTED\x10\x00\x12\x12\n\x0e\x43ONN_CONNECTED\x10\x01\x12\x15\n\x11\x43ONN_RECONNECTING\x10\x02*3\n\x0e\x44\x61taPacketKind\x12\x0e\n\nKIND_LOSSY\x10\x00\x12\x11\n\rKIND_RELIABLE\x10\x01\x42\x10\xaa\x02\rLiveKit.Proto') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nroom.proto\x12\rlivekit.proto\x1a\ne2ee.proto\x1a\x0chandle.proto\x1a\x11participant.proto\x1a\x0btrack.proto\x1a\x11video_frame.proto\x1a\x0bstats.proto\x1a\x11\x64\x61ta_stream.proto\x1a\x10\x64\x61ta_track.proto\"s\n\x0e\x43onnectRequest\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\r\n\x05token\x18\x02 \x02(\t\x12+\n\x07options\x18\x03 \x02(\x0b\x32\x1a.livekit.proto.RoomOptions\x12\x18\n\x10request_async_id\x18\x04 \x01(\x04\"#\n\x0f\x43onnectResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\xbf\x03\n\x0f\x43onnectCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12\x37\n\x06result\x18\x03 \x01(\x0b\x32%.livekit.proto.ConnectCallback.ResultH\x00\x1a\x89\x01\n\x15ParticipantWithTracks\x12\x34\n\x0bparticipant\x18\x01 \x02(\x0b\x32\x1f.livekit.proto.OwnedParticipant\x12:\n\x0cpublications\x18\x02 \x03(\x0b\x32$.livekit.proto.OwnedTrackPublication\x1a\xb8\x01\n\x06Result\x12&\n\x04room\x18\x01 \x02(\x0b\x32\x18.livekit.proto.OwnedRoom\x12:\n\x11local_participant\x18\x02 \x02(\x0b\x32\x1f.livekit.proto.OwnedParticipant\x12J\n\x0cparticipants\x18\x03 \x03(\x0b\x32\x34.livekit.proto.ConnectCallback.ParticipantWithTracksB\t\n\x07message\"s\n\x11\x44isconnectRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x18\n\x10request_async_id\x18\x02 \x01(\x04\x12/\n\x06reason\x18\x03 \x01(\x0e\x32\x1f.livekit.proto.DisconnectReason\"&\n\x12\x44isconnectResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"&\n\x12\x44isconnectCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\x7f\n\x17SimulateScenarioRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x35\n\x08scenario\x18\x02 \x02(\x0e\x32#.livekit.proto.SimulateScenarioKind\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\",\n\x18SimulateScenarioResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\";\n\x18SimulateScenarioCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x9c\x01\n\x13PublishTrackRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x14\n\x0ctrack_handle\x18\x02 \x02(\x04\x12\x33\n\x07options\x18\x03 \x02(\x0b\x32\".livekit.proto.TrackPublishOptions\x12\x18\n\x10request_async_id\x18\x04 \x01(\x04\"(\n\x14PublishTrackResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\x81\x01\n\x14PublishTrackCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12;\n\x0bpublication\x18\x03 \x01(\x0b\x32$.livekit.proto.OwnedTrackPublicationH\x00\x42\t\n\x07message\"\x81\x01\n\x15UnpublishTrackRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\x12\x19\n\x11stop_on_unpublish\x18\x03 \x02(\x08\x12\x18\n\x10request_async_id\x18\x04 \x01(\x04\"*\n\x16UnpublishTrackResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"9\n\x16UnpublishTrackCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\xd3\x01\n\x12PublishDataRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x10\n\x08\x64\x61ta_ptr\x18\x02 \x02(\x04\x12\x10\n\x08\x64\x61ta_len\x18\x03 \x02(\x04\x12\x10\n\x08reliable\x18\x04 \x02(\x08\x12\x1c\n\x10\x64\x65stination_sids\x18\x05 \x03(\tB\x02\x18\x01\x12\r\n\x05topic\x18\x06 \x01(\t\x12\x1e\n\x16\x64\x65stination_identities\x18\x07 \x03(\t\x12\x18\n\x10request_async_id\x18\x08 \x01(\x04\"\'\n\x13PublishDataResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"6\n\x13PublishDataCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\xc0\x01\n\x1bPublishTranscriptionRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\x12\x10\n\x08track_id\x18\x03 \x02(\t\x12\x35\n\x08segments\x18\x04 \x03(\x0b\x32#.livekit.proto.TranscriptionSegment\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"0\n\x1cPublishTranscriptionResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"?\n\x1cPublishTranscriptionCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x90\x01\n\x15PublishSipDtmfRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0c\n\x04\x63ode\x18\x02 \x02(\r\x12\r\n\x05\x64igit\x18\x03 \x02(\t\x12\x1e\n\x16\x64\x65stination_identities\x18\x04 \x03(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"*\n\x16PublishSipDtmfResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"9\n\x16PublishSipDtmfCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"g\n\x17SetLocalMetadataRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x10\n\x08metadata\x18\x02 \x02(\t\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\",\n\x18SetLocalMetadataResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\";\n\x18SetLocalMetadataCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x9e\x01\n\x16SendChatMessageRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0f\n\x07message\x18\x02 \x02(\t\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x01(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"\xd6\x01\n\x16\x45\x64itChatMessageRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x11\n\tedit_text\x18\x02 \x02(\t\x12\x34\n\x10original_message\x18\x03 \x02(\x0b\x32\x1a.livekit.proto.ChatMessage\x12\x1e\n\x16\x64\x65stination_identities\x18\x04 \x03(\t\x12\x17\n\x0fsender_identity\x18\x05 \x01(\t\x12\x18\n\x10request_async_id\x18\x06 \x01(\x04\"+\n\x17SendChatMessageResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"{\n\x17SendChatMessageCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12\x32\n\x0c\x63hat_message\x18\x03 \x01(\x0b\x32\x1a.livekit.proto.ChatMessageH\x00\x42\t\n\x07message\"\x8b\x01\n\x19SetLocalAttributesRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x32\n\nattributes\x18\x02 \x03(\x0b\x32\x1e.livekit.proto.AttributesEntry\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\"-\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x02(\t\x12\r\n\x05value\x18\x02 \x02(\t\".\n\x1aSetLocalAttributesResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"=\n\x1aSetLocalAttributesCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"_\n\x13SetLocalNameRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x0c\n\x04name\x18\x02 \x02(\t\x12\x18\n\x10request_async_id\x18\x03 \x01(\x04\"(\n\x14SetLocalNameResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"7\n\x14SetLocalNameCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"E\n\x14SetSubscribedRequest\x12\x11\n\tsubscribe\x18\x01 \x02(\x08\x12\x1a\n\x12publication_handle\x18\x02 \x02(\x04\"\x17\n\x15SetSubscribedResponse\"G\n\x16GetSessionStatsRequest\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x18\n\x10request_async_id\x18\x02 \x01(\x04\"+\n\x17GetSessionStatsResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"\xf7\x01\n\x17GetSessionStatsCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\x0f\n\x05\x65rror\x18\x02 \x01(\tH\x00\x12?\n\x06result\x18\x03 \x01(\x0b\x32-.livekit.proto.GetSessionStatsCallback.ResultH\x00\x1am\n\x06Result\x12\x30\n\x0fpublisher_stats\x18\x01 \x03(\x0b\x32\x17.livekit.proto.RtcStats\x12\x31\n\x10subscriber_stats\x18\x02 \x03(\x0b\x32\x17.livekit.proto.RtcStatsB\t\n\x07message\";\n\rVideoEncoding\x12\x13\n\x0bmax_bitrate\x18\x01 \x02(\x04\x12\x15\n\rmax_framerate\x18\x02 \x02(\x01\"$\n\rAudioEncoding\x12\x13\n\x0bmax_bitrate\x18\x01 \x02(\x04\"\xfb\x02\n\x13TrackPublishOptions\x12\x34\n\x0evideo_encoding\x18\x01 \x01(\x0b\x32\x1c.livekit.proto.VideoEncoding\x12\x34\n\x0e\x61udio_encoding\x18\x02 \x01(\x0b\x32\x1c.livekit.proto.AudioEncoding\x12.\n\x0bvideo_codec\x18\x03 \x01(\x0e\x32\x19.livekit.proto.VideoCodec\x12\x0b\n\x03\x64tx\x18\x04 \x01(\x08\x12\x0b\n\x03red\x18\x05 \x01(\x08\x12\x11\n\tsimulcast\x18\x06 \x01(\x08\x12*\n\x06source\x18\x07 \x01(\x0e\x32\x1a.livekit.proto.TrackSource\x12\x0e\n\x06stream\x18\x08 \x01(\t\x12\x19\n\x11preconnect_buffer\x18\t \x01(\x08\x12\x44\n\x17packet_trailer_features\x18\n \x03(\x0e\x32#.livekit.proto.PacketTrailerFeature\"=\n\tIceServer\x12\x0c\n\x04urls\x18\x01 \x03(\t\x12\x10\n\x08username\x18\x02 \x01(\t\x12\x10\n\x08password\x18\x03 \x01(\t\"\xc4\x01\n\tRtcConfig\x12;\n\x12ice_transport_type\x18\x01 \x01(\x0e\x32\x1f.livekit.proto.IceTransportType\x12K\n\x1a\x63ontinual_gathering_policy\x18\x02 \x01(\x0e\x32\'.livekit.proto.ContinualGatheringPolicy\x12-\n\x0bice_servers\x18\x03 \x03(\x0b\x32\x18.livekit.proto.IceServer\"\xae\x02\n\x0bRoomOptions\x12\x16\n\x0e\x61uto_subscribe\x18\x01 \x01(\x08\x12\x17\n\x0f\x61\x64\x61ptive_stream\x18\x02 \x01(\x08\x12\x10\n\x08\x64ynacast\x18\x03 \x01(\x08\x12,\n\x04\x65\x32\x65\x65\x18\x04 \x01(\x0b\x32\x1a.livekit.proto.E2eeOptionsB\x02\x18\x01\x12,\n\nrtc_config\x18\x05 \x01(\x0b\x32\x18.livekit.proto.RtcConfig\x12\x14\n\x0cjoin_retries\x18\x06 \x01(\r\x12.\n\nencryption\x18\x07 \x01(\x0b\x32\x1a.livekit.proto.E2eeOptions\x12\x1e\n\x16single_peer_connection\x18\x08 \x01(\x08\x12\x1a\n\x12\x63onnect_timeout_ms\x18\t \x01(\x04\"w\n\x14TranscriptionSegment\x12\n\n\x02id\x18\x01 \x02(\t\x12\x0c\n\x04text\x18\x02 \x02(\t\x12\x12\n\nstart_time\x18\x03 \x02(\x04\x12\x10\n\x08\x65nd_time\x18\x04 \x02(\x04\x12\r\n\x05\x66inal\x18\x05 \x02(\x08\x12\x10\n\x08language\x18\x06 \x02(\t\"0\n\nBufferInfo\x12\x10\n\x08\x64\x61ta_ptr\x18\x01 \x02(\x04\x12\x10\n\x08\x64\x61ta_len\x18\x02 \x02(\x04\"e\n\x0bOwnedBuffer\x12-\n\x06handle\x18\x01 \x02(\x0b\x32\x1d.livekit.proto.FfiOwnedHandle\x12\'\n\x04\x64\x61ta\x18\x02 \x02(\x0b\x32\x19.livekit.proto.BufferInfo\"\x85\x17\n\tRoomEvent\x12\x13\n\x0broom_handle\x18\x01 \x02(\x04\x12\x44\n\x15participant_connected\x18\x02 \x01(\x0b\x32#.livekit.proto.ParticipantConnectedH\x00\x12J\n\x18participant_disconnected\x18\x03 \x01(\x0b\x32&.livekit.proto.ParticipantDisconnectedH\x00\x12\x43\n\x15local_track_published\x18\x04 \x01(\x0b\x32\".livekit.proto.LocalTrackPublishedH\x00\x12G\n\x17local_track_unpublished\x18\x05 \x01(\x0b\x32$.livekit.proto.LocalTrackUnpublishedH\x00\x12\x45\n\x16local_track_subscribed\x18\x06 \x01(\x0b\x32#.livekit.proto.LocalTrackSubscribedH\x00\x12\x38\n\x0ftrack_published\x18\x07 \x01(\x0b\x32\x1d.livekit.proto.TrackPublishedH\x00\x12<\n\x11track_unpublished\x18\x08 \x01(\x0b\x32\x1f.livekit.proto.TrackUnpublishedH\x00\x12:\n\x10track_subscribed\x18\t \x01(\x0b\x32\x1e.livekit.proto.TrackSubscribedH\x00\x12>\n\x12track_unsubscribed\x18\n \x01(\x0b\x32 .livekit.proto.TrackUnsubscribedH\x00\x12K\n\x19track_subscription_failed\x18\x0b \x01(\x0b\x32&.livekit.proto.TrackSubscriptionFailedH\x00\x12\x30\n\x0btrack_muted\x18\x0c \x01(\x0b\x32\x19.livekit.proto.TrackMutedH\x00\x12\x34\n\rtrack_unmuted\x18\r \x01(\x0b\x32\x1b.livekit.proto.TrackUnmutedH\x00\x12G\n\x17\x61\x63tive_speakers_changed\x18\x0e \x01(\x0b\x32$.livekit.proto.ActiveSpeakersChangedH\x00\x12\x43\n\x15room_metadata_changed\x18\x0f \x01(\x0b\x32\".livekit.proto.RoomMetadataChangedH\x00\x12\x39\n\x10room_sid_changed\x18\x10 \x01(\x0b\x32\x1d.livekit.proto.RoomSidChangedH\x00\x12Q\n\x1cparticipant_metadata_changed\x18\x11 \x01(\x0b\x32).livekit.proto.ParticipantMetadataChangedH\x00\x12I\n\x18participant_name_changed\x18\x12 \x01(\x0b\x32%.livekit.proto.ParticipantNameChangedH\x00\x12U\n\x1eparticipant_attributes_changed\x18\x13 \x01(\x0b\x32+.livekit.proto.ParticipantAttributesChangedH\x00\x12M\n\x1a\x63onnection_quality_changed\x18\x14 \x01(\x0b\x32\'.livekit.proto.ConnectionQualityChangedH\x00\x12I\n\x18\x63onnection_state_changed\x18\x15 \x01(\x0b\x32%.livekit.proto.ConnectionStateChangedH\x00\x12\x33\n\x0c\x64isconnected\x18\x16 \x01(\x0b\x32\x1b.livekit.proto.DisconnectedH\x00\x12\x33\n\x0creconnecting\x18\x17 \x01(\x0b\x32\x1b.livekit.proto.ReconnectingH\x00\x12\x31\n\x0breconnected\x18\x18 \x01(\x0b\x32\x1a.livekit.proto.ReconnectedH\x00\x12=\n\x12\x65\x32\x65\x65_state_changed\x18\x19 \x01(\x0b\x32\x1f.livekit.proto.E2eeStateChangedH\x00\x12%\n\x03\x65os\x18\x1a \x01(\x0b\x32\x16.livekit.proto.RoomEOSH\x00\x12\x41\n\x14\x64\x61ta_packet_received\x18\x1b \x01(\x0b\x32!.livekit.proto.DataPacketReceivedH\x00\x12\x46\n\x16transcription_received\x18\x1c \x01(\x0b\x32$.livekit.proto.TranscriptionReceivedH\x00\x12:\n\x0c\x63hat_message\x18\x1d \x01(\x0b\x32\".livekit.proto.ChatMessageReceivedH\x00\x12I\n\x16stream_header_received\x18\x1e \x01(\x0b\x32\'.livekit.proto.DataStreamHeaderReceivedH\x00\x12G\n\x15stream_chunk_received\x18\x1f \x01(\x0b\x32&.livekit.proto.DataStreamChunkReceivedH\x00\x12K\n\x17stream_trailer_received\x18 \x01(\x0b\x32(.livekit.proto.DataStreamTrailerReceivedH\x00\x12i\n\"data_channel_low_threshold_changed\x18! \x01(\x0b\x32;.livekit.proto.DataChannelBufferedAmountLowThresholdChangedH\x00\x12=\n\x12\x62yte_stream_opened\x18\" \x01(\x0b\x32\x1f.livekit.proto.ByteStreamOpenedH\x00\x12=\n\x12text_stream_opened\x18# \x01(\x0b\x32\x1f.livekit.proto.TextStreamOpenedH\x00\x12/\n\x0croom_updated\x18$ \x01(\x0b\x32\x17.livekit.proto.RoomInfoH\x00\x12(\n\x05moved\x18% \x01(\x0b\x32\x17.livekit.proto.RoomInfoH\x00\x12\x42\n\x14participants_updated\x18& \x01(\x0b\x32\".livekit.proto.ParticipantsUpdatedH\x00\x12\x62\n%participant_encryption_status_changed\x18\' \x01(\x0b\x32\x31.livekit.proto.ParticipantEncryptionStatusChangedH\x00\x12U\n\x1eparticipant_permission_changed\x18) \x01(\x0b\x32+.livekit.proto.ParticipantPermissionChangedH\x00\x12\x38\n\x0ftoken_refreshed\x18( \x01(\x0b\x32\x1d.livekit.proto.TokenRefreshedH\x00\x12>\n\x12participant_active\x18* \x01(\x0b\x32 .livekit.proto.ParticipantActiveH\x00\x12\x41\n\x14\x64\x61ta_track_published\x18+ \x01(\x0b\x32!.livekit.proto.DataTrackPublishedH\x00\x12\x45\n\x16\x64\x61ta_track_unpublished\x18, \x01(\x0b\x32#.livekit.proto.DataTrackUnpublishedH\x00\x42\t\n\x07message\"\xc9\x02\n\x08RoomInfo\x12\x0b\n\x03sid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x02(\t\x12\x10\n\x08metadata\x18\x03 \x02(\t\x12.\n&lossy_dc_buffered_amount_low_threshold\x18\x04 \x02(\x04\x12\x31\n)reliable_dc_buffered_amount_low_threshold\x18\x05 \x02(\x04\x12\x15\n\rempty_timeout\x18\x06 \x02(\r\x12\x19\n\x11\x64\x65parture_timeout\x18\x07 \x02(\r\x12\x18\n\x10max_participants\x18\x08 \x02(\r\x12\x15\n\rcreation_time\x18\t \x02(\x03\x12\x18\n\x10num_participants\x18\n \x02(\r\x12\x16\n\x0enum_publishers\x18\x0b \x02(\r\x12\x18\n\x10\x61\x63tive_recording\x18\x0c \x02(\x08\"a\n\tOwnedRoom\x12-\n\x06handle\x18\x01 \x02(\x0b\x32\x1d.livekit.proto.FfiOwnedHandle\x12%\n\x04info\x18\x02 \x02(\x0b\x32\x17.livekit.proto.RoomInfo\"K\n\x13ParticipantsUpdated\x12\x34\n\x0cparticipants\x18\x01 \x03(\x0b\x32\x1e.livekit.proto.ParticipantInfo\"E\n\x14ParticipantConnected\x12-\n\x04info\x18\x01 \x02(\x0b\x32\x1f.livekit.proto.OwnedParticipant\"1\n\x11ParticipantActive\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\"s\n\x17ParticipantDisconnected\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12:\n\x11\x64isconnect_reason\x18\x02 \x02(\x0e\x32\x1f.livekit.proto.DisconnectReason\"(\n\x13LocalTrackPublished\x12\x11\n\ttrack_sid\x18\x01 \x02(\t\"0\n\x15LocalTrackUnpublished\x12\x17\n\x0fpublication_sid\x18\x01 \x02(\t\")\n\x14LocalTrackSubscribed\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"i\n\x0eTrackPublished\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x39\n\x0bpublication\x18\x02 \x02(\x0b\x32$.livekit.proto.OwnedTrackPublication\"I\n\x10TrackUnpublished\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x17\n\x0fpublication_sid\x18\x02 \x02(\t\"Y\n\x0fTrackSubscribed\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12(\n\x05track\x18\x02 \x02(\x0b\x32\x19.livekit.proto.OwnedTrack\"D\n\x11TrackUnsubscribed\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"Y\n\x17TrackSubscriptionFailed\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\x12\r\n\x05\x65rror\x18\x03 \x02(\t\"=\n\nTrackMuted\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"?\n\x0cTrackUnmuted\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x11\n\ttrack_sid\x18\x02 \x02(\t\"_\n\x10\x45\x32\x65\x65StateChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12-\n\x05state\x18\x02 \x02(\x0e\x32\x1e.livekit.proto.EncryptionState\"7\n\x15\x41\x63tiveSpeakersChanged\x12\x1e\n\x16participant_identities\x18\x01 \x03(\t\"\'\n\x13RoomMetadataChanged\x12\x10\n\x08metadata\x18\x01 \x02(\t\"\x1d\n\x0eRoomSidChanged\x12\x0b\n\x03sid\x18\x01 \x02(\t\"L\n\x1aParticipantMetadataChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x10\n\x08metadata\x18\x02 \x02(\t\"\xac\x01\n\x1cParticipantAttributesChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x32\n\nattributes\x18\x02 \x03(\x0b\x32\x1e.livekit.proto.AttributesEntry\x12:\n\x12\x63hanged_attributes\x18\x03 \x03(\x0b\x32\x1e.livekit.proto.AttributesEntry\"X\n\"ParticipantEncryptionStatusChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x14\n\x0cis_encrypted\x18\x02 \x02(\x08\"D\n\x16ParticipantNameChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x0c\n\x04name\x18\x02 \x02(\t\"v\n\x1cParticipantPermissionChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x38\n\npermission\x18\x02 \x01(\x0b\x32$.livekit.proto.ParticipantPermission\"k\n\x18\x43onnectionQualityChanged\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x31\n\x07quality\x18\x02 \x02(\x0e\x32 .livekit.proto.ConnectionQuality\"E\n\nUserPacket\x12(\n\x04\x64\x61ta\x18\x01 \x02(\x0b\x32\x1a.livekit.proto.OwnedBuffer\x12\r\n\x05topic\x18\x02 \x01(\t\"y\n\x0b\x43hatMessage\x12\n\n\x02id\x18\x01 \x02(\t\x12\x11\n\ttimestamp\x18\x02 \x02(\x03\x12\x0f\n\x07message\x18\x03 \x02(\t\x12\x16\n\x0e\x65\x64it_timestamp\x18\x04 \x01(\x03\x12\x0f\n\x07\x64\x65leted\x18\x05 \x01(\x08\x12\x11\n\tgenerated\x18\x06 \x01(\x08\"`\n\x13\x43hatMessageReceived\x12+\n\x07message\x18\x01 \x02(\x0b\x32\x1a.livekit.proto.ChatMessage\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\"&\n\x07SipDTMF\x12\x0c\n\x04\x63ode\x18\x01 \x02(\r\x12\r\n\x05\x64igit\x18\x02 \x01(\t\"\xbf\x01\n\x12\x44\x61taPacketReceived\x12+\n\x04kind\x18\x01 \x02(\x0e\x32\x1d.livekit.proto.DataPacketKind\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\x12)\n\x04user\x18\x04 \x01(\x0b\x32\x19.livekit.proto.UserPacketH\x00\x12*\n\x08sip_dtmf\x18\x05 \x01(\x0b\x32\x16.livekit.proto.SipDTMFH\x00\x42\x07\n\x05value\"\x7f\n\x15TranscriptionReceived\x12\x1c\n\x14participant_identity\x18\x01 \x01(\t\x12\x11\n\ttrack_sid\x18\x02 \x01(\t\x12\x35\n\x08segments\x18\x03 \x03(\x0b\x32#.livekit.proto.TranscriptionSegment\"G\n\x16\x43onnectionStateChanged\x12-\n\x05state\x18\x01 \x02(\x0e\x32\x1e.livekit.proto.ConnectionState\"\x0b\n\tConnected\"?\n\x0c\x44isconnected\x12/\n\x06reason\x18\x01 \x02(\x0e\x32\x1f.livekit.proto.DisconnectReason\"\x0e\n\x0cReconnecting\"\r\n\x0bReconnected\"\x1f\n\x0eTokenRefreshed\x12\r\n\x05token\x18\x01 \x02(\t\"\t\n\x07RoomEOS\"\x8e\x07\n\nDataStream\x1a\xaa\x01\n\nTextHeader\x12?\n\x0eoperation_type\x18\x01 \x02(\x0e\x32\'.livekit.proto.DataStream.OperationType\x12\x0f\n\x07version\x18\x02 \x01(\x05\x12\x1a\n\x12reply_to_stream_id\x18\x03 \x01(\t\x12\x1b\n\x13\x61ttached_stream_ids\x18\x04 \x03(\t\x12\x11\n\tgenerated\x18\x05 \x01(\x08\x1a\x1a\n\nByteHeader\x12\x0c\n\x04name\x18\x01 \x02(\t\x1a\xeb\x02\n\x06Header\x12\x11\n\tstream_id\x18\x01 \x02(\t\x12\x11\n\ttimestamp\x18\x02 \x02(\x03\x12\x11\n\tmime_type\x18\x03 \x02(\t\x12\r\n\x05topic\x18\x04 \x02(\t\x12\x14\n\x0ctotal_length\x18\x05 \x01(\x04\x12\x44\n\nattributes\x18\x06 \x03(\x0b\x32\x30.livekit.proto.DataStream.Header.AttributesEntry\x12;\n\x0btext_header\x18\x07 \x01(\x0b\x32$.livekit.proto.DataStream.TextHeaderH\x00\x12;\n\x0b\x62yte_header\x18\x08 \x01(\x0b\x32$.livekit.proto.DataStream.ByteHeaderH\x00\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x42\x10\n\x0e\x63ontent_header\x1a]\n\x05\x43hunk\x12\x11\n\tstream_id\x18\x01 \x02(\t\x12\x13\n\x0b\x63hunk_index\x18\x02 \x02(\x04\x12\x0f\n\x07\x63ontent\x18\x03 \x02(\x0c\x12\x0f\n\x07version\x18\x04 \x01(\x05\x12\n\n\x02iv\x18\x05 \x01(\x0c\x1a\xa6\x01\n\x07Trailer\x12\x11\n\tstream_id\x18\x01 \x02(\t\x12\x0e\n\x06reason\x18\x02 \x02(\t\x12\x45\n\nattributes\x18\x03 \x03(\x0b\x32\x31.livekit.proto.DataStream.Trailer.AttributesEntry\x1a\x31\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"A\n\rOperationType\x12\n\n\x06\x43REATE\x10\x00\x12\n\n\x06UPDATE\x10\x01\x12\n\n\x06\x44\x45LETE\x10\x02\x12\x0c\n\x08REACTION\x10\x03\"j\n\x18\x44\x61taStreamHeaderReceived\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x30\n\x06header\x18\x02 \x02(\x0b\x32 .livekit.proto.DataStream.Header\"g\n\x17\x44\x61taStreamChunkReceived\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12.\n\x05\x63hunk\x18\x02 \x02(\x0b\x32\x1f.livekit.proto.DataStream.Chunk\"m\n\x19\x44\x61taStreamTrailerReceived\x12\x1c\n\x14participant_identity\x18\x01 \x02(\t\x12\x32\n\x07trailer\x18\x02 \x02(\x0b\x32!.livekit.proto.DataStream.Trailer\"\xc0\x01\n\x17SendStreamHeaderRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x30\n\x06header\x18\x02 \x02(\x0b\x32 .livekit.proto.DataStream.Header\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x02(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"\xbd\x01\n\x16SendStreamChunkRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12.\n\x05\x63hunk\x18\x02 \x02(\x0b\x32\x1f.livekit.proto.DataStream.Chunk\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x02(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\"\xc3\x01\n\x18SendStreamTrailerRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x32\n\x07trailer\x18\x02 \x02(\x0b\x32!.livekit.proto.DataStream.Trailer\x12\x1e\n\x16\x64\x65stination_identities\x18\x03 \x03(\t\x12\x17\n\x0fsender_identity\x18\x04 \x02(\t\x12\x18\n\x10request_async_id\x18\x05 \x01(\x04\",\n\x18SendStreamHeaderResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"+\n\x17SendStreamChunkResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\"-\n\x19SendStreamTrailerResponse\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\";\n\x18SendStreamHeaderCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\":\n\x17SendStreamChunkCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"<\n\x19SendStreamTrailerCallback\x12\x10\n\x08\x61sync_id\x18\x01 \x02(\x04\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\x93\x01\n/SetDataChannelBufferedAmountLowThresholdRequest\x12 \n\x18local_participant_handle\x18\x01 \x02(\x04\x12\x11\n\tthreshold\x18\x02 \x02(\x04\x12+\n\x04kind\x18\x03 \x02(\x0e\x32\x1d.livekit.proto.DataPacketKind\"2\n0SetDataChannelBufferedAmountLowThresholdResponse\"n\n,DataChannelBufferedAmountLowThresholdChanged\x12+\n\x04kind\x18\x01 \x02(\x0e\x32\x1d.livekit.proto.DataPacketKind\x12\x11\n\tthreshold\x18\x02 \x02(\x04\"f\n\x10\x42yteStreamOpened\x12\x34\n\x06reader\x18\x01 \x02(\x0b\x32$.livekit.proto.OwnedByteStreamReader\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\"f\n\x10TextStreamOpened\x12\x34\n\x06reader\x18\x01 \x02(\x0b\x32$.livekit.proto.OwnedTextStreamReader\x12\x1c\n\x14participant_identity\x18\x02 \x02(\t\"H\n\x12\x44\x61taTrackPublished\x12\x32\n\x05track\x18\x01 \x02(\x0b\x32#.livekit.proto.OwnedRemoteDataTrack\"#\n\x14\x44\x61taTrackUnpublished\x12\x0b\n\x03sid\x18\x01 \x02(\t*\xe6\x01\n\x14SimulateScenarioKind\x12\x1d\n\x19SIMULATE_SIGNAL_RECONNECT\x10\x00\x12\x14\n\x10SIMULATE_SPEAKER\x10\x01\x12\x19\n\x15SIMULATE_NODE_FAILURE\x10\x02\x12\x19\n\x15SIMULATE_SERVER_LEAVE\x10\x03\x12\x16\n\x12SIMULATE_MIGRATION\x10\x04\x12\x16\n\x12SIMULATE_FORCE_TCP\x10\x05\x12\x16\n\x12SIMULATE_FORCE_TLS\x10\x06\x12\x1b\n\x17SIMULATE_FULL_RECONNECT\x10\x07*P\n\x10IceTransportType\x12\x13\n\x0fTRANSPORT_RELAY\x10\x00\x12\x14\n\x10TRANSPORT_NOHOST\x10\x01\x12\x11\n\rTRANSPORT_ALL\x10\x02*C\n\x18\x43ontinualGatheringPolicy\x12\x0f\n\x0bGATHER_ONCE\x10\x00\x12\x16\n\x12GATHER_CONTINUALLY\x10\x01*`\n\x11\x43onnectionQuality\x12\x10\n\x0cQUALITY_POOR\x10\x00\x12\x10\n\x0cQUALITY_GOOD\x10\x01\x12\x15\n\x11QUALITY_EXCELLENT\x10\x02\x12\x10\n\x0cQUALITY_LOST\x10\x03*S\n\x0f\x43onnectionState\x12\x15\n\x11\x43ONN_DISCONNECTED\x10\x00\x12\x12\n\x0e\x43ONN_CONNECTED\x10\x01\x12\x15\n\x11\x43ONN_RECONNECTING\x10\x02*3\n\x0e\x44\x61taPacketKind\x12\x0e\n\nKIND_LOSSY\x10\x00\x12\x11\n\rKIND_RELIABLE\x10\x01\x42\x10\xaa\x02\rLiveKit.Proto') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -38,18 +38,18 @@ _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._serialized_options = b'8\001' _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._options = None _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._serialized_options = b'8\001' - _globals['_SIMULATESCENARIOKIND']._serialized_start=14795 - _globals['_SIMULATESCENARIOKIND']._serialized_end=15025 - _globals['_ICETRANSPORTTYPE']._serialized_start=15027 - _globals['_ICETRANSPORTTYPE']._serialized_end=15107 - _globals['_CONTINUALGATHERINGPOLICY']._serialized_start=15109 - _globals['_CONTINUALGATHERINGPOLICY']._serialized_end=15176 - _globals['_CONNECTIONQUALITY']._serialized_start=15178 - _globals['_CONNECTIONQUALITY']._serialized_end=15274 - _globals['_CONNECTIONSTATE']._serialized_start=15276 - _globals['_CONNECTIONSTATE']._serialized_end=15359 - _globals['_DATAPACKETKIND']._serialized_start=15361 - _globals['_DATAPACKETKIND']._serialized_end=15412 + _globals['_SIMULATESCENARIOKIND']._serialized_start=14596 + _globals['_SIMULATESCENARIOKIND']._serialized_end=14826 + _globals['_ICETRANSPORTTYPE']._serialized_start=14828 + _globals['_ICETRANSPORTTYPE']._serialized_end=14908 + _globals['_CONTINUALGATHERINGPOLICY']._serialized_start=14910 + _globals['_CONTINUALGATHERINGPOLICY']._serialized_end=14977 + _globals['_CONNECTIONQUALITY']._serialized_start=14979 + _globals['_CONNECTIONQUALITY']._serialized_end=15075 + _globals['_CONNECTIONSTATE']._serialized_start=15077 + _globals['_CONNECTIONSTATE']._serialized_end=15160 + _globals['_DATAPACKETKIND']._serialized_start=15162 + _globals['_DATAPACKETKIND']._serialized_end=15213 _globals['_CONNECTREQUEST']._serialized_start=156 _globals['_CONNECTREQUEST']._serialized_end=271 _globals['_CONNECTRESPONSE']._serialized_start=273 @@ -161,141 +161,139 @@ _globals['_OWNEDBUFFER']._serialized_start=5571 _globals['_OWNEDBUFFER']._serialized_end=5672 _globals['_ROOMEVENT']._serialized_start=5675 - _globals['_ROOMEVENT']._serialized_end=8697 - _globals['_ROOMINFO']._serialized_start=8700 - _globals['_ROOMINFO']._serialized_end=9029 - _globals['_OWNEDROOM']._serialized_start=9031 - _globals['_OWNEDROOM']._serialized_end=9128 - _globals['_PARTICIPANTSUPDATED']._serialized_start=9130 - _globals['_PARTICIPANTSUPDATED']._serialized_end=9205 - _globals['_PARTICIPANTCONNECTED']._serialized_start=9207 - _globals['_PARTICIPANTCONNECTED']._serialized_end=9276 - _globals['_PARTICIPANTACTIVE']._serialized_start=9278 - _globals['_PARTICIPANTACTIVE']._serialized_end=9327 - _globals['_PARTICIPANTDISCONNECTED']._serialized_start=9329 - _globals['_PARTICIPANTDISCONNECTED']._serialized_end=9444 - _globals['_LOCALTRACKPUBLISHED']._serialized_start=9446 - _globals['_LOCALTRACKPUBLISHED']._serialized_end=9486 - _globals['_LOCALTRACKUNPUBLISHED']._serialized_start=9488 - _globals['_LOCALTRACKUNPUBLISHED']._serialized_end=9536 - _globals['_LOCALTRACKREPUBLISHED']._serialized_start=9538 - _globals['_LOCALTRACKREPUBLISHED']._serialized_end=9662 - _globals['_LOCALTRACKSUBSCRIBED']._serialized_start=9664 - _globals['_LOCALTRACKSUBSCRIBED']._serialized_end=9705 - _globals['_TRACKPUBLISHED']._serialized_start=9707 - _globals['_TRACKPUBLISHED']._serialized_end=9812 - _globals['_TRACKUNPUBLISHED']._serialized_start=9814 - _globals['_TRACKUNPUBLISHED']._serialized_end=9887 - _globals['_TRACKSUBSCRIBED']._serialized_start=9889 - _globals['_TRACKSUBSCRIBED']._serialized_end=9978 - _globals['_TRACKUNSUBSCRIBED']._serialized_start=9980 - _globals['_TRACKUNSUBSCRIBED']._serialized_end=10048 - _globals['_TRACKSUBSCRIPTIONFAILED']._serialized_start=10050 - _globals['_TRACKSUBSCRIPTIONFAILED']._serialized_end=10139 - _globals['_TRACKMUTED']._serialized_start=10141 - _globals['_TRACKMUTED']._serialized_end=10202 - _globals['_TRACKUNMUTED']._serialized_start=10204 - _globals['_TRACKUNMUTED']._serialized_end=10267 - _globals['_E2EESTATECHANGED']._serialized_start=10269 - _globals['_E2EESTATECHANGED']._serialized_end=10364 - _globals['_ACTIVESPEAKERSCHANGED']._serialized_start=10366 - _globals['_ACTIVESPEAKERSCHANGED']._serialized_end=10421 - _globals['_ROOMMETADATACHANGED']._serialized_start=10423 - _globals['_ROOMMETADATACHANGED']._serialized_end=10462 - _globals['_ROOMSIDCHANGED']._serialized_start=10464 - _globals['_ROOMSIDCHANGED']._serialized_end=10493 - _globals['_PARTICIPANTMETADATACHANGED']._serialized_start=10495 - _globals['_PARTICIPANTMETADATACHANGED']._serialized_end=10571 - _globals['_PARTICIPANTATTRIBUTESCHANGED']._serialized_start=10574 - _globals['_PARTICIPANTATTRIBUTESCHANGED']._serialized_end=10746 - _globals['_PARTICIPANTENCRYPTIONSTATUSCHANGED']._serialized_start=10748 - _globals['_PARTICIPANTENCRYPTIONSTATUSCHANGED']._serialized_end=10836 - _globals['_PARTICIPANTNAMECHANGED']._serialized_start=10838 - _globals['_PARTICIPANTNAMECHANGED']._serialized_end=10906 - _globals['_PARTICIPANTPERMISSIONCHANGED']._serialized_start=10908 - _globals['_PARTICIPANTPERMISSIONCHANGED']._serialized_end=11026 - _globals['_CONNECTIONQUALITYCHANGED']._serialized_start=11028 - _globals['_CONNECTIONQUALITYCHANGED']._serialized_end=11135 - _globals['_USERPACKET']._serialized_start=11137 - _globals['_USERPACKET']._serialized_end=11206 - _globals['_CHATMESSAGE']._serialized_start=11208 - _globals['_CHATMESSAGE']._serialized_end=11329 - _globals['_CHATMESSAGERECEIVED']._serialized_start=11331 - _globals['_CHATMESSAGERECEIVED']._serialized_end=11427 - _globals['_SIPDTMF']._serialized_start=11429 - _globals['_SIPDTMF']._serialized_end=11467 - _globals['_DATAPACKETRECEIVED']._serialized_start=11470 - _globals['_DATAPACKETRECEIVED']._serialized_end=11661 - _globals['_TRANSCRIPTIONRECEIVED']._serialized_start=11663 - _globals['_TRANSCRIPTIONRECEIVED']._serialized_end=11790 - _globals['_CONNECTIONSTATECHANGED']._serialized_start=11792 - _globals['_CONNECTIONSTATECHANGED']._serialized_end=11863 - _globals['_CONNECTED']._serialized_start=11865 - _globals['_CONNECTED']._serialized_end=11876 - _globals['_DISCONNECTED']._serialized_start=11878 - _globals['_DISCONNECTED']._serialized_end=11941 - _globals['_RECONNECTING']._serialized_start=11943 - _globals['_RECONNECTING']._serialized_end=11957 - _globals['_RECONNECTED']._serialized_start=11959 - _globals['_RECONNECTED']._serialized_end=11972 - _globals['_TOKENREFRESHED']._serialized_start=11974 - _globals['_TOKENREFRESHED']._serialized_end=12005 - _globals['_ROOMEOS']._serialized_start=12007 - _globals['_ROOMEOS']._serialized_end=12016 - _globals['_DATASTREAM']._serialized_start=12019 - _globals['_DATASTREAM']._serialized_end=12929 - _globals['_DATASTREAM_TEXTHEADER']._serialized_start=12034 - _globals['_DATASTREAM_TEXTHEADER']._serialized_end=12204 - _globals['_DATASTREAM_BYTEHEADER']._serialized_start=12206 - _globals['_DATASTREAM_BYTEHEADER']._serialized_end=12232 - _globals['_DATASTREAM_HEADER']._serialized_start=12235 - _globals['_DATASTREAM_HEADER']._serialized_end=12598 - _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._serialized_start=12531 - _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._serialized_end=12580 - _globals['_DATASTREAM_CHUNK']._serialized_start=12600 - _globals['_DATASTREAM_CHUNK']._serialized_end=12693 - _globals['_DATASTREAM_TRAILER']._serialized_start=12696 - _globals['_DATASTREAM_TRAILER']._serialized_end=12862 - _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._serialized_start=12531 - _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._serialized_end=12580 - _globals['_DATASTREAM_OPERATIONTYPE']._serialized_start=12864 - _globals['_DATASTREAM_OPERATIONTYPE']._serialized_end=12929 - _globals['_DATASTREAMHEADERRECEIVED']._serialized_start=12931 - _globals['_DATASTREAMHEADERRECEIVED']._serialized_end=13037 - _globals['_DATASTREAMCHUNKRECEIVED']._serialized_start=13039 - _globals['_DATASTREAMCHUNKRECEIVED']._serialized_end=13142 - _globals['_DATASTREAMTRAILERRECEIVED']._serialized_start=13144 - _globals['_DATASTREAMTRAILERRECEIVED']._serialized_end=13253 - _globals['_SENDSTREAMHEADERREQUEST']._serialized_start=13256 - _globals['_SENDSTREAMHEADERREQUEST']._serialized_end=13448 - _globals['_SENDSTREAMCHUNKREQUEST']._serialized_start=13451 - _globals['_SENDSTREAMCHUNKREQUEST']._serialized_end=13640 - _globals['_SENDSTREAMTRAILERREQUEST']._serialized_start=13643 - _globals['_SENDSTREAMTRAILERREQUEST']._serialized_end=13838 - _globals['_SENDSTREAMHEADERRESPONSE']._serialized_start=13840 - _globals['_SENDSTREAMHEADERRESPONSE']._serialized_end=13884 - _globals['_SENDSTREAMCHUNKRESPONSE']._serialized_start=13886 - _globals['_SENDSTREAMCHUNKRESPONSE']._serialized_end=13929 - _globals['_SENDSTREAMTRAILERRESPONSE']._serialized_start=13931 - _globals['_SENDSTREAMTRAILERRESPONSE']._serialized_end=13976 - _globals['_SENDSTREAMHEADERCALLBACK']._serialized_start=13978 - _globals['_SENDSTREAMHEADERCALLBACK']._serialized_end=14037 - _globals['_SENDSTREAMCHUNKCALLBACK']._serialized_start=14039 - _globals['_SENDSTREAMCHUNKCALLBACK']._serialized_end=14097 - _globals['_SENDSTREAMTRAILERCALLBACK']._serialized_start=14099 - _globals['_SENDSTREAMTRAILERCALLBACK']._serialized_end=14159 - _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDREQUEST']._serialized_start=14162 - _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDREQUEST']._serialized_end=14309 - _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDRESPONSE']._serialized_start=14311 - _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDRESPONSE']._serialized_end=14361 - _globals['_DATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDCHANGED']._serialized_start=14363 - _globals['_DATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDCHANGED']._serialized_end=14473 - _globals['_BYTESTREAMOPENED']._serialized_start=14475 - _globals['_BYTESTREAMOPENED']._serialized_end=14577 - _globals['_TEXTSTREAMOPENED']._serialized_start=14579 - _globals['_TEXTSTREAMOPENED']._serialized_end=14681 - _globals['_DATATRACKPUBLISHED']._serialized_start=14683 - _globals['_DATATRACKPUBLISHED']._serialized_end=14755 - _globals['_DATATRACKUNPUBLISHED']._serialized_start=14757 - _globals['_DATATRACKUNPUBLISHED']._serialized_end=14792 + _globals['_ROOMEVENT']._serialized_end=8624 + _globals['_ROOMINFO']._serialized_start=8627 + _globals['_ROOMINFO']._serialized_end=8956 + _globals['_OWNEDROOM']._serialized_start=8958 + _globals['_OWNEDROOM']._serialized_end=9055 + _globals['_PARTICIPANTSUPDATED']._serialized_start=9057 + _globals['_PARTICIPANTSUPDATED']._serialized_end=9132 + _globals['_PARTICIPANTCONNECTED']._serialized_start=9134 + _globals['_PARTICIPANTCONNECTED']._serialized_end=9203 + _globals['_PARTICIPANTACTIVE']._serialized_start=9205 + _globals['_PARTICIPANTACTIVE']._serialized_end=9254 + _globals['_PARTICIPANTDISCONNECTED']._serialized_start=9256 + _globals['_PARTICIPANTDISCONNECTED']._serialized_end=9371 + _globals['_LOCALTRACKPUBLISHED']._serialized_start=9373 + _globals['_LOCALTRACKPUBLISHED']._serialized_end=9413 + _globals['_LOCALTRACKUNPUBLISHED']._serialized_start=9415 + _globals['_LOCALTRACKUNPUBLISHED']._serialized_end=9463 + _globals['_LOCALTRACKSUBSCRIBED']._serialized_start=9465 + _globals['_LOCALTRACKSUBSCRIBED']._serialized_end=9506 + _globals['_TRACKPUBLISHED']._serialized_start=9508 + _globals['_TRACKPUBLISHED']._serialized_end=9613 + _globals['_TRACKUNPUBLISHED']._serialized_start=9615 + _globals['_TRACKUNPUBLISHED']._serialized_end=9688 + _globals['_TRACKSUBSCRIBED']._serialized_start=9690 + _globals['_TRACKSUBSCRIBED']._serialized_end=9779 + _globals['_TRACKUNSUBSCRIBED']._serialized_start=9781 + _globals['_TRACKUNSUBSCRIBED']._serialized_end=9849 + _globals['_TRACKSUBSCRIPTIONFAILED']._serialized_start=9851 + _globals['_TRACKSUBSCRIPTIONFAILED']._serialized_end=9940 + _globals['_TRACKMUTED']._serialized_start=9942 + _globals['_TRACKMUTED']._serialized_end=10003 + _globals['_TRACKUNMUTED']._serialized_start=10005 + _globals['_TRACKUNMUTED']._serialized_end=10068 + _globals['_E2EESTATECHANGED']._serialized_start=10070 + _globals['_E2EESTATECHANGED']._serialized_end=10165 + _globals['_ACTIVESPEAKERSCHANGED']._serialized_start=10167 + _globals['_ACTIVESPEAKERSCHANGED']._serialized_end=10222 + _globals['_ROOMMETADATACHANGED']._serialized_start=10224 + _globals['_ROOMMETADATACHANGED']._serialized_end=10263 + _globals['_ROOMSIDCHANGED']._serialized_start=10265 + _globals['_ROOMSIDCHANGED']._serialized_end=10294 + _globals['_PARTICIPANTMETADATACHANGED']._serialized_start=10296 + _globals['_PARTICIPANTMETADATACHANGED']._serialized_end=10372 + _globals['_PARTICIPANTATTRIBUTESCHANGED']._serialized_start=10375 + _globals['_PARTICIPANTATTRIBUTESCHANGED']._serialized_end=10547 + _globals['_PARTICIPANTENCRYPTIONSTATUSCHANGED']._serialized_start=10549 + _globals['_PARTICIPANTENCRYPTIONSTATUSCHANGED']._serialized_end=10637 + _globals['_PARTICIPANTNAMECHANGED']._serialized_start=10639 + _globals['_PARTICIPANTNAMECHANGED']._serialized_end=10707 + _globals['_PARTICIPANTPERMISSIONCHANGED']._serialized_start=10709 + _globals['_PARTICIPANTPERMISSIONCHANGED']._serialized_end=10827 + _globals['_CONNECTIONQUALITYCHANGED']._serialized_start=10829 + _globals['_CONNECTIONQUALITYCHANGED']._serialized_end=10936 + _globals['_USERPACKET']._serialized_start=10938 + _globals['_USERPACKET']._serialized_end=11007 + _globals['_CHATMESSAGE']._serialized_start=11009 + _globals['_CHATMESSAGE']._serialized_end=11130 + _globals['_CHATMESSAGERECEIVED']._serialized_start=11132 + _globals['_CHATMESSAGERECEIVED']._serialized_end=11228 + _globals['_SIPDTMF']._serialized_start=11230 + _globals['_SIPDTMF']._serialized_end=11268 + _globals['_DATAPACKETRECEIVED']._serialized_start=11271 + _globals['_DATAPACKETRECEIVED']._serialized_end=11462 + _globals['_TRANSCRIPTIONRECEIVED']._serialized_start=11464 + _globals['_TRANSCRIPTIONRECEIVED']._serialized_end=11591 + _globals['_CONNECTIONSTATECHANGED']._serialized_start=11593 + _globals['_CONNECTIONSTATECHANGED']._serialized_end=11664 + _globals['_CONNECTED']._serialized_start=11666 + _globals['_CONNECTED']._serialized_end=11677 + _globals['_DISCONNECTED']._serialized_start=11679 + _globals['_DISCONNECTED']._serialized_end=11742 + _globals['_RECONNECTING']._serialized_start=11744 + _globals['_RECONNECTING']._serialized_end=11758 + _globals['_RECONNECTED']._serialized_start=11760 + _globals['_RECONNECTED']._serialized_end=11773 + _globals['_TOKENREFRESHED']._serialized_start=11775 + _globals['_TOKENREFRESHED']._serialized_end=11806 + _globals['_ROOMEOS']._serialized_start=11808 + _globals['_ROOMEOS']._serialized_end=11817 + _globals['_DATASTREAM']._serialized_start=11820 + _globals['_DATASTREAM']._serialized_end=12730 + _globals['_DATASTREAM_TEXTHEADER']._serialized_start=11835 + _globals['_DATASTREAM_TEXTHEADER']._serialized_end=12005 + _globals['_DATASTREAM_BYTEHEADER']._serialized_start=12007 + _globals['_DATASTREAM_BYTEHEADER']._serialized_end=12033 + _globals['_DATASTREAM_HEADER']._serialized_start=12036 + _globals['_DATASTREAM_HEADER']._serialized_end=12399 + _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._serialized_start=12332 + _globals['_DATASTREAM_HEADER_ATTRIBUTESENTRY']._serialized_end=12381 + _globals['_DATASTREAM_CHUNK']._serialized_start=12401 + _globals['_DATASTREAM_CHUNK']._serialized_end=12494 + _globals['_DATASTREAM_TRAILER']._serialized_start=12497 + _globals['_DATASTREAM_TRAILER']._serialized_end=12663 + _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._serialized_start=12332 + _globals['_DATASTREAM_TRAILER_ATTRIBUTESENTRY']._serialized_end=12381 + _globals['_DATASTREAM_OPERATIONTYPE']._serialized_start=12665 + _globals['_DATASTREAM_OPERATIONTYPE']._serialized_end=12730 + _globals['_DATASTREAMHEADERRECEIVED']._serialized_start=12732 + _globals['_DATASTREAMHEADERRECEIVED']._serialized_end=12838 + _globals['_DATASTREAMCHUNKRECEIVED']._serialized_start=12840 + _globals['_DATASTREAMCHUNKRECEIVED']._serialized_end=12943 + _globals['_DATASTREAMTRAILERRECEIVED']._serialized_start=12945 + _globals['_DATASTREAMTRAILERRECEIVED']._serialized_end=13054 + _globals['_SENDSTREAMHEADERREQUEST']._serialized_start=13057 + _globals['_SENDSTREAMHEADERREQUEST']._serialized_end=13249 + _globals['_SENDSTREAMCHUNKREQUEST']._serialized_start=13252 + _globals['_SENDSTREAMCHUNKREQUEST']._serialized_end=13441 + _globals['_SENDSTREAMTRAILERREQUEST']._serialized_start=13444 + _globals['_SENDSTREAMTRAILERREQUEST']._serialized_end=13639 + _globals['_SENDSTREAMHEADERRESPONSE']._serialized_start=13641 + _globals['_SENDSTREAMHEADERRESPONSE']._serialized_end=13685 + _globals['_SENDSTREAMCHUNKRESPONSE']._serialized_start=13687 + _globals['_SENDSTREAMCHUNKRESPONSE']._serialized_end=13730 + _globals['_SENDSTREAMTRAILERRESPONSE']._serialized_start=13732 + _globals['_SENDSTREAMTRAILERRESPONSE']._serialized_end=13777 + _globals['_SENDSTREAMHEADERCALLBACK']._serialized_start=13779 + _globals['_SENDSTREAMHEADERCALLBACK']._serialized_end=13838 + _globals['_SENDSTREAMCHUNKCALLBACK']._serialized_start=13840 + _globals['_SENDSTREAMCHUNKCALLBACK']._serialized_end=13898 + _globals['_SENDSTREAMTRAILERCALLBACK']._serialized_start=13900 + _globals['_SENDSTREAMTRAILERCALLBACK']._serialized_end=13960 + _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDREQUEST']._serialized_start=13963 + _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDREQUEST']._serialized_end=14110 + _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDRESPONSE']._serialized_start=14112 + _globals['_SETDATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDRESPONSE']._serialized_end=14162 + _globals['_DATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDCHANGED']._serialized_start=14164 + _globals['_DATACHANNELBUFFEREDAMOUNTLOWTHRESHOLDCHANGED']._serialized_end=14274 + _globals['_BYTESTREAMOPENED']._serialized_start=14276 + _globals['_BYTESTREAMOPENED']._serialized_end=14378 + _globals['_TEXTSTREAMOPENED']._serialized_start=14380 + _globals['_TEXTSTREAMOPENED']._serialized_end=14482 + _globals['_DATATRACKPUBLISHED']._serialized_start=14484 + _globals['_DATATRACKPUBLISHED']._serialized_end=14556 + _globals['_DATATRACKUNPUBLISHED']._serialized_start=14558 + _globals['_DATATRACKUNPUBLISHED']._serialized_end=14593 # @@protoc_insertion_point(module_scope) diff --git a/livekit-rtc/livekit/rtc/_proto/room_pb2.pyi b/livekit-rtc/livekit/rtc/_proto/room_pb2.pyi index 9a5c3e3e..f7f36c7d 100644 --- a/livekit-rtc/livekit/rtc/_proto/room_pb2.pyi +++ b/livekit-rtc/livekit/rtc/_proto/room_pb2.pyi @@ -1439,7 +1439,6 @@ class RoomEvent(google.protobuf.message.Message): PARTICIPANT_ACTIVE_FIELD_NUMBER: builtins.int DATA_TRACK_PUBLISHED_FIELD_NUMBER: builtins.int DATA_TRACK_UNPUBLISHED_FIELD_NUMBER: builtins.int - LOCAL_TRACK_REPUBLISHED_FIELD_NUMBER: builtins.int room_handle: builtins.int @property def participant_connected(self) -> global___ParticipantConnected: ... @@ -1541,8 +1540,6 @@ class RoomEvent(google.protobuf.message.Message): def data_track_published(self) -> global___DataTrackPublished: ... @property def data_track_unpublished(self) -> global___DataTrackUnpublished: ... - @property - def local_track_republished(self) -> global___LocalTrackRepublished: ... def __init__( self, *, @@ -1590,11 +1587,10 @@ class RoomEvent(google.protobuf.message.Message): participant_active: global___ParticipantActive | None = ..., data_track_published: global___DataTrackPublished | None = ..., data_track_unpublished: global___DataTrackUnpublished | None = ..., - local_track_republished: global___LocalTrackRepublished | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["active_speakers_changed", b"active_speakers_changed", "byte_stream_opened", b"byte_stream_opened", "chat_message", b"chat_message", "connection_quality_changed", b"connection_quality_changed", "connection_state_changed", b"connection_state_changed", "data_channel_low_threshold_changed", b"data_channel_low_threshold_changed", "data_packet_received", b"data_packet_received", "data_track_published", b"data_track_published", "data_track_unpublished", b"data_track_unpublished", "disconnected", b"disconnected", "e2ee_state_changed", b"e2ee_state_changed", "eos", b"eos", "local_track_published", b"local_track_published", "local_track_republished", b"local_track_republished", "local_track_subscribed", b"local_track_subscribed", "local_track_unpublished", b"local_track_unpublished", "message", b"message", "moved", b"moved", "participant_active", b"participant_active", "participant_attributes_changed", b"participant_attributes_changed", "participant_connected", b"participant_connected", "participant_disconnected", b"participant_disconnected", "participant_encryption_status_changed", b"participant_encryption_status_changed", "participant_metadata_changed", b"participant_metadata_changed", "participant_name_changed", b"participant_name_changed", "participant_permission_changed", b"participant_permission_changed", "participants_updated", b"participants_updated", "reconnected", b"reconnected", "reconnecting", b"reconnecting", "room_handle", b"room_handle", "room_metadata_changed", b"room_metadata_changed", "room_sid_changed", b"room_sid_changed", "room_updated", b"room_updated", "stream_chunk_received", b"stream_chunk_received", "stream_header_received", b"stream_header_received", "stream_trailer_received", b"stream_trailer_received", "text_stream_opened", b"text_stream_opened", "token_refreshed", b"token_refreshed", "track_muted", b"track_muted", "track_published", b"track_published", "track_subscribed", b"track_subscribed", "track_subscription_failed", b"track_subscription_failed", "track_unmuted", b"track_unmuted", "track_unpublished", b"track_unpublished", "track_unsubscribed", b"track_unsubscribed", "transcription_received", b"transcription_received"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["active_speakers_changed", b"active_speakers_changed", "byte_stream_opened", b"byte_stream_opened", "chat_message", b"chat_message", "connection_quality_changed", b"connection_quality_changed", "connection_state_changed", b"connection_state_changed", "data_channel_low_threshold_changed", b"data_channel_low_threshold_changed", "data_packet_received", b"data_packet_received", "data_track_published", b"data_track_published", "data_track_unpublished", b"data_track_unpublished", "disconnected", b"disconnected", "e2ee_state_changed", b"e2ee_state_changed", "eos", b"eos", "local_track_published", b"local_track_published", "local_track_republished", b"local_track_republished", "local_track_subscribed", b"local_track_subscribed", "local_track_unpublished", b"local_track_unpublished", "message", b"message", "moved", b"moved", "participant_active", b"participant_active", "participant_attributes_changed", b"participant_attributes_changed", "participant_connected", b"participant_connected", "participant_disconnected", b"participant_disconnected", "participant_encryption_status_changed", b"participant_encryption_status_changed", "participant_metadata_changed", b"participant_metadata_changed", "participant_name_changed", b"participant_name_changed", "participant_permission_changed", b"participant_permission_changed", "participants_updated", b"participants_updated", "reconnected", b"reconnected", "reconnecting", b"reconnecting", "room_handle", b"room_handle", "room_metadata_changed", b"room_metadata_changed", "room_sid_changed", b"room_sid_changed", "room_updated", b"room_updated", "stream_chunk_received", b"stream_chunk_received", "stream_header_received", b"stream_header_received", "stream_trailer_received", b"stream_trailer_received", "text_stream_opened", b"text_stream_opened", "token_refreshed", b"token_refreshed", "track_muted", b"track_muted", "track_published", b"track_published", "track_subscribed", b"track_subscribed", "track_subscription_failed", b"track_subscription_failed", "track_unmuted", b"track_unmuted", "track_unpublished", b"track_unpublished", "track_unsubscribed", b"track_unsubscribed", "transcription_received", b"transcription_received"]) -> None: ... - def WhichOneof(self, oneof_group: typing.Literal["message", b"message"]) -> typing.Literal["participant_connected", "participant_disconnected", "local_track_published", "local_track_unpublished", "local_track_subscribed", "track_published", "track_unpublished", "track_subscribed", "track_unsubscribed", "track_subscription_failed", "track_muted", "track_unmuted", "active_speakers_changed", "room_metadata_changed", "room_sid_changed", "participant_metadata_changed", "participant_name_changed", "participant_attributes_changed", "connection_quality_changed", "connection_state_changed", "disconnected", "reconnecting", "reconnected", "e2ee_state_changed", "eos", "data_packet_received", "transcription_received", "chat_message", "stream_header_received", "stream_chunk_received", "stream_trailer_received", "data_channel_low_threshold_changed", "byte_stream_opened", "text_stream_opened", "room_updated", "moved", "participants_updated", "participant_encryption_status_changed", "participant_permission_changed", "token_refreshed", "participant_active", "data_track_published", "data_track_unpublished", "local_track_republished"] | None: ... + def HasField(self, field_name: typing.Literal["active_speakers_changed", b"active_speakers_changed", "byte_stream_opened", b"byte_stream_opened", "chat_message", b"chat_message", "connection_quality_changed", b"connection_quality_changed", "connection_state_changed", b"connection_state_changed", "data_channel_low_threshold_changed", b"data_channel_low_threshold_changed", "data_packet_received", b"data_packet_received", "data_track_published", b"data_track_published", "data_track_unpublished", b"data_track_unpublished", "disconnected", b"disconnected", "e2ee_state_changed", b"e2ee_state_changed", "eos", b"eos", "local_track_published", b"local_track_published", "local_track_subscribed", b"local_track_subscribed", "local_track_unpublished", b"local_track_unpublished", "message", b"message", "moved", b"moved", "participant_active", b"participant_active", "participant_attributes_changed", b"participant_attributes_changed", "participant_connected", b"participant_connected", "participant_disconnected", b"participant_disconnected", "participant_encryption_status_changed", b"participant_encryption_status_changed", "participant_metadata_changed", b"participant_metadata_changed", "participant_name_changed", b"participant_name_changed", "participant_permission_changed", b"participant_permission_changed", "participants_updated", b"participants_updated", "reconnected", b"reconnected", "reconnecting", b"reconnecting", "room_handle", b"room_handle", "room_metadata_changed", b"room_metadata_changed", "room_sid_changed", b"room_sid_changed", "room_updated", b"room_updated", "stream_chunk_received", b"stream_chunk_received", "stream_header_received", b"stream_header_received", "stream_trailer_received", b"stream_trailer_received", "text_stream_opened", b"text_stream_opened", "token_refreshed", b"token_refreshed", "track_muted", b"track_muted", "track_published", b"track_published", "track_subscribed", b"track_subscribed", "track_subscription_failed", b"track_subscription_failed", "track_unmuted", b"track_unmuted", "track_unpublished", b"track_unpublished", "track_unsubscribed", b"track_unsubscribed", "transcription_received", b"transcription_received"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["active_speakers_changed", b"active_speakers_changed", "byte_stream_opened", b"byte_stream_opened", "chat_message", b"chat_message", "connection_quality_changed", b"connection_quality_changed", "connection_state_changed", b"connection_state_changed", "data_channel_low_threshold_changed", b"data_channel_low_threshold_changed", "data_packet_received", b"data_packet_received", "data_track_published", b"data_track_published", "data_track_unpublished", b"data_track_unpublished", "disconnected", b"disconnected", "e2ee_state_changed", b"e2ee_state_changed", "eos", b"eos", "local_track_published", b"local_track_published", "local_track_subscribed", b"local_track_subscribed", "local_track_unpublished", b"local_track_unpublished", "message", b"message", "moved", b"moved", "participant_active", b"participant_active", "participant_attributes_changed", b"participant_attributes_changed", "participant_connected", b"participant_connected", "participant_disconnected", b"participant_disconnected", "participant_encryption_status_changed", b"participant_encryption_status_changed", "participant_metadata_changed", b"participant_metadata_changed", "participant_name_changed", b"participant_name_changed", "participant_permission_changed", b"participant_permission_changed", "participants_updated", b"participants_updated", "reconnected", b"reconnected", "reconnecting", b"reconnecting", "room_handle", b"room_handle", "room_metadata_changed", b"room_metadata_changed", "room_sid_changed", b"room_sid_changed", "room_updated", b"room_updated", "stream_chunk_received", b"stream_chunk_received", "stream_header_received", b"stream_header_received", "stream_trailer_received", b"stream_trailer_received", "text_stream_opened", b"text_stream_opened", "token_refreshed", b"token_refreshed", "track_muted", b"track_muted", "track_published", b"track_published", "track_subscribed", b"track_subscribed", "track_subscription_failed", b"track_subscription_failed", "track_unmuted", b"track_unmuted", "track_unpublished", b"track_unpublished", "track_unsubscribed", b"track_unsubscribed", "transcription_received", b"transcription_received"]) -> None: ... + def WhichOneof(self, oneof_group: typing.Literal["message", b"message"]) -> typing.Literal["participant_connected", "participant_disconnected", "local_track_published", "local_track_unpublished", "local_track_subscribed", "track_published", "track_unpublished", "track_subscribed", "track_unsubscribed", "track_subscription_failed", "track_muted", "track_unmuted", "active_speakers_changed", "room_metadata_changed", "room_sid_changed", "participant_metadata_changed", "participant_name_changed", "participant_attributes_changed", "connection_quality_changed", "connection_state_changed", "disconnected", "reconnecting", "reconnected", "e2ee_state_changed", "eos", "data_packet_received", "transcription_received", "chat_message", "stream_header_received", "stream_chunk_received", "stream_trailer_received", "data_channel_low_threshold_changed", "byte_stream_opened", "text_stream_opened", "room_updated", "moved", "participants_updated", "participant_encryption_status_changed", "participant_permission_changed", "token_refreshed", "participant_active", "data_track_published", "data_track_unpublished"] | None: ... global___RoomEvent = RoomEvent @@ -1771,38 +1767,6 @@ class LocalTrackUnpublished(google.protobuf.message.Message): global___LocalTrackUnpublished = LocalTrackUnpublished -@typing.final -class LocalTrackRepublished(google.protobuf.message.Message): - """Fired when the SDK auto-republishes a local track during a full - reconnect. The FfiPublication handle is preserved across the cycle — - language bindings should look up the existing publication object by - `previous_sid` (its old SID), update its TrackPublicationInfo in place - with `info`, and rekey it under the new SID. Apps holding a cached - reference to the publication continue to see a valid object whose - reads/writes hit current state. - """ - - DESCRIPTOR: google.protobuf.descriptor.Descriptor - - PUBLICATION_HANDLE_FIELD_NUMBER: builtins.int - PREVIOUS_SID_FIELD_NUMBER: builtins.int - INFO_FIELD_NUMBER: builtins.int - publication_handle: builtins.int - previous_sid: builtins.str - @property - def info(self) -> track_pb2.TrackPublicationInfo: ... - def __init__( - self, - *, - publication_handle: builtins.int | None = ..., - previous_sid: builtins.str | None = ..., - info: track_pb2.TrackPublicationInfo | None = ..., - ) -> None: ... - def HasField(self, field_name: typing.Literal["info", b"info", "previous_sid", b"previous_sid", "publication_handle", b"publication_handle"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["info", b"info", "previous_sid", b"previous_sid", "publication_handle", b"publication_handle"]) -> None: ... - -global___LocalTrackRepublished = LocalTrackRepublished - @typing.final class LocalTrackSubscribed(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor