1- from ctypes import *
21import asyncio
32from pyee .asyncio import AsyncIOEventEmitter
43from ._ffi_client import (FfiClient , FfiHandle )
5- from .participant import (Participant , LocalParticipant , RemoteParticipant )
6- from .track_publication import (RemoteTrackPublication , LocalTrackPublication )
74from ._proto import ffi_pb2 as proto_ffi
85from ._proto import room_pb2 as proto_room
96from ._proto import participant_pb2 as proto_participant
7+ from .participant import (Participant , LocalParticipant , RemoteParticipant )
8+ from .track_publication import (RemoteTrackPublication , LocalTrackPublication )
9+ from .track import (RemoteAudioTrack , RemoteVideoTrack )
10+ from livekit import TrackKind
11+ import weakref
1012
1113
1214class ConnectError (Exception ):
@@ -21,6 +23,10 @@ def __init__(self):
2123 self ._room_info : proto_room .RoomInfo = None
2224 self ._participants : dict [str , RemoteParticipant ] = {}
2325
26+ def __del__ (self ):
27+ ffi_client = FfiClient ()
28+ ffi_client .remove_listener ('room_event' , self ._on_room_event )
29+
2430 async def connect (self , url : str , token : str ):
2531 # TODO(theomonnom): We should be more flexible about the event loop
2632 ffi_client = FfiClient ()
@@ -37,6 +43,10 @@ async def connect(self, url: str, token: str):
3743
3844 def on_connect_callback (cb : proto_room .ConnectCallback ):
3945 if cb .async_id == async_id :
46+ # add existing participants
47+ for participant_info in cb .room .participants :
48+ self ._create_remote_participant (participant_info )
49+
4050 future .set_result (cb )
4151 ffi_client .remove_listener ('connect' , on_connect_callback )
4252
@@ -49,7 +59,7 @@ def on_connect_callback(cb: proto_room.ConnectCallback):
4959 self ._ffi_handle = FfiHandle (resp .room .handle .id )
5060 self ._room_info = resp .room
5161 self ._close_future = asyncio .Future ()
52- ffi_client .add_listener ('room ' , self ._on_room_event )
62+ ffi_client .add_listener ('room_event ' , self ._on_room_event )
5363
5464 async def close (self ):
5565 self ._ffi_handle = None
@@ -74,15 +84,47 @@ def _on_room_event(self, event: proto_room.RoomEvent):
7484 publication = RemoteTrackPublication (
7585 event .track_published .publication )
7686 participant ._tracks [publication .sid ] = publication
77- self .emit ('track_published' , publication )
87+ self .emit ('track_published' , publication , participant )
7888 elif which == 'track_unpublished' :
7989 participant = self ._participants [event .track_unpublished .participant_sid ]
90+ publication = participant ._tracks .pop (
91+ event .track_unpublished .publication_sid )
92+ self .emit ('track_unpublished' , publication , participant )
93+ elif which == 'track_subscribed' :
94+ track_info = event .track_subscribed .track
95+ participant = self ._participants [event .track_subscribed .participant_sid ]
96+ publication = participant ._tracks [track_info .sid ]
97+
98+ if track_info .kind == TrackKind .KIND_VIDEO :
99+ video_track = RemoteVideoTrack (
100+ track_info , weakref .ref (self ), weakref .ref (participant ))
101+ publication ._track = video_track
102+ self .emit ('track_subscribed' , video_track ,
103+ publication , participant )
104+ elif track_info .kind == TrackKind .KIND_AUDIO :
105+ audio_track = RemoteAudioTrack (
106+ track_info , weakref .ref (self ), weakref .ref (participant ))
107+ publication ._track = audio_track
108+ self .emit ('track_subscribed' , audio_track ,
109+ publication , participant )
110+ elif which == 'track_unsubscribed' :
111+ participant = self ._participants [event .track_unsubscribed .participant_sid ]
112+ publication = participant ._tracks [event .track_unsubscribed .track_sid ]
113+ track = publication ._track
114+ publication ._track = None
115+ self .emit ('track_unsubscribed' , track , publication , participant )
80116
81117 def _create_remote_participant (self , info : proto_participant .ParticipantInfo ) -> RemoteParticipant :
118+ if info .sid in self ._participants :
119+ raise Exception ('participant already exists' )
120+
82121 participant = RemoteParticipant (info )
83122 self ._participants [participant .sid ] = participant
84123
85- # TODO(publications)
124+ # add existing track publications
125+ for publication_info in info .publications :
126+ publication = RemoteTrackPublication (publication_info )
127+ participant ._tracks [publication .sid ] = publication
86128
87129 return participant
88130
0 commit comments