participant.rs

  1use crate::{
  2    AudioStream, LocalAudioTrack, LocalTrackPublication, LocalVideoTrack, Participant,
  3    ParticipantIdentity, RemoteTrack, RemoteTrackPublication, TrackSid,
  4    test::{Room, WeakRoom},
  5};
  6use anyhow::Result;
  7use collections::HashMap;
  8use gpui::{
  9    AsyncApp, DevicePixels, ScreenCaptureSource, ScreenCaptureStream, SourceMetadata, size,
 10};
 11
 12#[derive(Clone, Debug)]
 13pub struct LocalParticipant {
 14    pub(crate) identity: ParticipantIdentity,
 15    pub(crate) room: Room,
 16}
 17
 18#[derive(Clone, Debug)]
 19pub struct RemoteParticipant {
 20    pub(crate) identity: ParticipantIdentity,
 21    pub(crate) room: WeakRoom,
 22}
 23
 24impl Participant {
 25    pub fn identity(&self) -> ParticipantIdentity {
 26        match self {
 27            Participant::Local(participant) => participant.identity.clone(),
 28            Participant::Remote(participant) => participant.identity.clone(),
 29        }
 30    }
 31}
 32
 33impl LocalParticipant {
 34    pub async fn unpublish_track(&self, track: TrackSid, _cx: &AsyncApp) -> Result<()> {
 35        self.room
 36            .test_server()
 37            .unpublish_track(self.room.token(), &track)
 38            .await
 39    }
 40
 41    pub(crate) async fn publish_microphone_track(
 42        &self,
 43        _cx: &AsyncApp,
 44    ) -> Result<(LocalTrackPublication, AudioStream)> {
 45        let this = self.clone();
 46        let server = this.room.test_server();
 47        let sid = server
 48            .publish_audio_track(this.room.token(), &LocalAudioTrack {})
 49            .await?;
 50
 51        Ok((
 52            LocalTrackPublication {
 53                room: self.room.downgrade(),
 54                sid,
 55            },
 56            AudioStream {},
 57        ))
 58    }
 59
 60    pub async fn publish_screenshare_track(
 61        &self,
 62        _source: &dyn ScreenCaptureSource,
 63        _cx: &mut AsyncApp,
 64    ) -> Result<(LocalTrackPublication, Box<dyn ScreenCaptureStream>)> {
 65        let this = self.clone();
 66        let server = this.room.test_server();
 67        let sid = server
 68            .publish_video_track(this.room.token(), LocalVideoTrack {})
 69            .await?;
 70        Ok((
 71            LocalTrackPublication {
 72                room: self.room.downgrade(),
 73                sid,
 74            },
 75            Box::new(TestScreenCaptureStream {}),
 76        ))
 77    }
 78}
 79
 80impl RemoteParticipant {
 81    pub fn track_publications(&self) -> HashMap<TrackSid, RemoteTrackPublication> {
 82        if let Some(room) = self.room.upgrade() {
 83            let server = room.test_server();
 84            let audio = server
 85                .audio_tracks(room.token())
 86                .unwrap()
 87                .into_iter()
 88                .filter(|track| track.publisher_id() == self.identity)
 89                .map(|track| {
 90                    (
 91                        track.sid(),
 92                        RemoteTrackPublication {
 93                            sid: track.sid(),
 94                            room: self.room.clone(),
 95                            track: RemoteTrack::Audio(track),
 96                        },
 97                    )
 98                });
 99            let video = server
100                .video_tracks(room.token())
101                .unwrap()
102                .into_iter()
103                .filter(|track| track.publisher_id() == self.identity)
104                .map(|track| {
105                    (
106                        track.sid(),
107                        RemoteTrackPublication {
108                            sid: track.sid(),
109                            room: self.room.clone(),
110                            track: RemoteTrack::Video(track),
111                        },
112                    )
113                });
114            audio.chain(video).collect()
115        } else {
116            HashMap::default()
117        }
118    }
119
120    pub fn identity(&self) -> ParticipantIdentity {
121        self.identity.clone()
122    }
123}
124
125struct TestScreenCaptureStream;
126
127impl ScreenCaptureStream for TestScreenCaptureStream {
128    fn metadata(&self) -> Result<SourceMetadata> {
129        Ok(SourceMetadata {
130            id: 0,
131            is_main: None,
132            label: None,
133            resolution: size(DevicePixels(1), DevicePixels(1)),
134        })
135    }
136}