1use futures::StreamExt;
2use gpui::{actions, keymap::Binding, Menu, MenuItem};
3use live_kit_client::{LocalVideoTrack, RemoteVideoTrackUpdate, Room};
4use live_kit_server::token::{self, VideoGrant};
5use log::LevelFilter;
6use simplelog::SimpleLogger;
7
8actions!(capture, [Quit]);
9
10fn main() {
11 SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
12
13 gpui::App::new(()).unwrap().run(|cx| {
14 cx.platform().activate(true);
15 cx.add_global_action(quit);
16
17 cx.add_bindings([Binding::new("cmd-q", Quit, None)]);
18 cx.set_menus(vec![Menu {
19 name: "Zed",
20 items: vec![MenuItem::Action {
21 name: "Quit",
22 action: Box::new(Quit),
23 }],
24 }]);
25
26 let live_kit_url = std::env::var("LIVE_KIT_URL").unwrap_or("http://localhost:7880".into());
27 let live_kit_key = std::env::var("LIVE_KIT_KEY").unwrap_or("devkey".into());
28 let live_kit_secret = std::env::var("LIVE_KIT_SECRET").unwrap_or("secret".into());
29
30 cx.spawn(|cx| async move {
31 let user_a_token = token::create(
32 &live_kit_key,
33 &live_kit_secret,
34 Some("test-participant-1"),
35 VideoGrant::to_join("test-room"),
36 )
37 .unwrap();
38 let room_a = Room::new();
39 room_a.connect(&live_kit_url, &user_a_token).await.unwrap();
40
41 let user2_token = token::create(
42 &live_kit_key,
43 &live_kit_secret,
44 Some("test-participant-2"),
45 VideoGrant::to_join("test-room"),
46 )
47 .unwrap();
48 let room_b = Room::new();
49 room_b.connect(&live_kit_url, &user2_token).await.unwrap();
50
51 let mut track_changes = room_b.remote_video_track_updates();
52
53 let displays = room_a.display_sources().await.unwrap();
54 let display = displays.into_iter().next().unwrap();
55
56 let track_a = LocalVideoTrack::screen_share_for_display(&display);
57 let track_a_publication = room_a.publish_video_track(&track_a).await.unwrap();
58
59 if let RemoteVideoTrackUpdate::Subscribed(track) = track_changes.next().await.unwrap() {
60 let remote_tracks = room_b.remote_video_tracks("test-participant-1");
61 assert_eq!(remote_tracks.len(), 1);
62 assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1");
63 dbg!(track.sid());
64 assert_eq!(track.publisher_id(), "test-participant-1");
65 } else {
66 panic!("unexpected message");
67 }
68
69 let remote_track = room_b
70 .remote_video_tracks("test-participant-1")
71 .pop()
72 .unwrap();
73 room_a.unpublish_track(track_a_publication);
74 if let RemoteVideoTrackUpdate::Unsubscribed {
75 publisher_id,
76 track_id,
77 } = track_changes.next().await.unwrap()
78 {
79 assert_eq!(publisher_id, "test-participant-1");
80 assert_eq!(remote_track.sid(), track_id);
81 assert_eq!(room_b.remote_video_tracks("test-participant-1").len(), 0);
82 } else {
83 panic!("unexpected message");
84 }
85
86 cx.platform().quit();
87 })
88 .detach();
89 });
90}
91
92fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
93 cx.platform().quit();
94}