mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 19:44:04 +03:00
Mute mics by default
Fix bug when file ends in line with 1 more digit displayed than previous lines Remove stale UI elements from voice call development
This commit is contained in:
parent
07dc82409b
commit
5ceb258b3e
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1052,6 +1052,10 @@ dependencies = [
|
||||
"media",
|
||||
"postage",
|
||||
"project",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"settings",
|
||||
"util",
|
||||
]
|
||||
@ -6470,7 +6474,7 @@ name = "search"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags",
|
||||
"client",
|
||||
"collections",
|
||||
"editor",
|
||||
|
@ -66,6 +66,11 @@
|
||||
// 3. Draw all invisible symbols:
|
||||
// "all"
|
||||
"show_whitespaces": "selection",
|
||||
// Settings related to calls in Zed
|
||||
"calls": {
|
||||
// Join calls with the microphone muted by default
|
||||
"mute_on_join": true
|
||||
},
|
||||
// Scrollbar related settings
|
||||
"scrollbar": {
|
||||
// When to show the scrollbar in the editor.
|
||||
|
@ -36,6 +36,10 @@ anyhow.workspace = true
|
||||
async-broadcast = "0.4"
|
||||
futures.workspace = true
|
||||
postage.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_derive.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
client = { path = "../client", features = ["test-support"] }
|
||||
|
@ -1,9 +1,11 @@
|
||||
pub mod participant;
|
||||
pub mod room;
|
||||
pub mod call_settings;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use call_settings::CallSettings;
|
||||
use client::{proto, ClickhouseEvent, Client, TelemetrySettings, TypedEnvelope, User, UserStore};
|
||||
use collections::HashSet;
|
||||
use futures::{future::Shared, FutureExt};
|
||||
@ -19,6 +21,8 @@ pub use participant::ParticipantLocation;
|
||||
pub use room::Room;
|
||||
|
||||
pub fn init(client: Arc<Client>, user_store: ModelHandle<UserStore>, cx: &mut AppContext) {
|
||||
settings::register::<CallSettings>(cx);
|
||||
|
||||
let active_call = cx.add_model(|cx| ActiveCall::new(client, user_store, cx));
|
||||
cx.set_global(active_call);
|
||||
}
|
||||
|
27
crates/call/src/call_settings.rs
Normal file
27
crates/call/src/call_settings.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde_derive::{Serialize, Deserialize};
|
||||
use settings::Setting;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct CallSettings {
|
||||
pub mute_on_join: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
pub struct CallSettingsContent {
|
||||
pub mute_on_join: Option<bool>,
|
||||
}
|
||||
|
||||
impl Setting for CallSettings {
|
||||
const KEY: Option<&'static str> = Some("calls");
|
||||
|
||||
type FileContent = CallSettingsContent;
|
||||
|
||||
fn load(
|
||||
default_value: &Self::FileContent,
|
||||
user_values: &[&Self::FileContent],
|
||||
_: &gpui::AppContext,
|
||||
) -> anyhow::Result<Self> {
|
||||
Self::load_via_json_merge(default_value, user_values)
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
call_settings::CallSettings,
|
||||
participant::{LocalParticipant, ParticipantLocation, RemoteParticipant, RemoteVideoTrack},
|
||||
IncomingCall,
|
||||
};
|
||||
@ -19,7 +20,7 @@ use live_kit_client::{
|
||||
};
|
||||
use postage::stream::Stream;
|
||||
use project::Project;
|
||||
use std::{future::Future, mem, pin::Pin, sync::Arc, time::Duration};
|
||||
use std::{future::Future, mem, pin::Pin, sync::Arc, time::Duration, panic::Location};
|
||||
use util::{post_inc, ResultExt, TryFutureExt};
|
||||
|
||||
pub const RECONNECT_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
@ -153,8 +154,10 @@ impl Room {
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
connect.await?;
|
||||
|
||||
this.update(&mut cx, |this, cx| this.share_microphone(cx))
|
||||
.await?;
|
||||
if !cx.read(|cx| settings::get::<CallSettings>(cx).mute_on_join) {
|
||||
this.update(&mut cx, |this, cx| this.share_microphone(cx))
|
||||
.await?;
|
||||
}
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
@ -656,7 +659,7 @@ impl Room {
|
||||
peer_id,
|
||||
projects: participant.projects,
|
||||
location,
|
||||
muted: false,
|
||||
muted: true,
|
||||
speaking: false,
|
||||
video_tracks: Default::default(),
|
||||
audio_tracks: Default::default(),
|
||||
@ -670,6 +673,10 @@ impl Room {
|
||||
live_kit.room.remote_video_tracks(&user.id.to_string());
|
||||
let audio_tracks =
|
||||
live_kit.room.remote_audio_tracks(&user.id.to_string());
|
||||
let publications = live_kit
|
||||
.room
|
||||
.remote_audio_track_publications(&user.id.to_string());
|
||||
|
||||
for track in video_tracks {
|
||||
this.remote_video_track_updated(
|
||||
RemoteVideoTrackUpdate::Subscribed(track),
|
||||
@ -677,9 +684,15 @@ impl Room {
|
||||
)
|
||||
.log_err();
|
||||
}
|
||||
for track in audio_tracks {
|
||||
|
||||
for (track, publication) in
|
||||
audio_tracks.iter().zip(publications.iter())
|
||||
{
|
||||
this.remote_audio_track_updated(
|
||||
RemoteAudioTrackUpdate::Subscribed(track),
|
||||
RemoteAudioTrackUpdate::Subscribed(
|
||||
track.clone(),
|
||||
publication.clone(),
|
||||
),
|
||||
cx,
|
||||
)
|
||||
.log_err();
|
||||
@ -819,8 +832,8 @@ impl Room {
|
||||
cx.notify();
|
||||
}
|
||||
RemoteAudioTrackUpdate::MuteChanged { track_id, muted } => {
|
||||
let mut found = false;
|
||||
for participant in &mut self.remote_participants.values_mut() {
|
||||
let mut found = false;
|
||||
for track in participant.audio_tracks.values() {
|
||||
if track.sid() == track_id {
|
||||
found = true;
|
||||
@ -832,16 +845,20 @@ impl Room {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
}
|
||||
RemoteAudioTrackUpdate::Subscribed(track) => {
|
||||
RemoteAudioTrackUpdate::Subscribed(track, publication) => {
|
||||
let user_id = track.publisher_id().parse()?;
|
||||
let track_id = track.sid().to_string();
|
||||
let participant = self
|
||||
.remote_participants
|
||||
.get_mut(&user_id)
|
||||
.ok_or_else(|| anyhow!("subscribed to track by unknown participant"))?;
|
||||
|
||||
participant.audio_tracks.insert(track_id.clone(), track);
|
||||
participant.muted = publication.is_muted();
|
||||
|
||||
cx.emit(Event::RemoteAudioTracksChanged {
|
||||
participant_id: participant.peer_id,
|
||||
});
|
||||
@ -1053,7 +1070,7 @@ impl Room {
|
||||
self.live_kit
|
||||
.as_ref()
|
||||
.and_then(|live_kit| match &live_kit.microphone_track {
|
||||
LocalTrack::None => None,
|
||||
LocalTrack::None => Some(true),
|
||||
LocalTrack::Pending { muted, .. } => Some(*muted),
|
||||
LocalTrack::Published { muted, .. } => Some(*muted),
|
||||
})
|
||||
@ -1070,7 +1087,9 @@ impl Room {
|
||||
self.live_kit.as_ref().map(|live_kit| live_kit.deafened)
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn share_microphone(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
dbg!(Location::caller());
|
||||
if self.status.is_offline() {
|
||||
return Task::ready(Err(anyhow!("room is offline")));
|
||||
} else if self.is_sharing_mic() {
|
||||
@ -1244,6 +1263,10 @@ impl Room {
|
||||
pub fn toggle_mute(&mut self, cx: &mut ModelContext<Self>) -> Result<Task<Result<()>>> {
|
||||
let should_mute = !self.is_muted();
|
||||
if let Some(live_kit) = self.live_kit.as_mut() {
|
||||
if matches!(live_kit.microphone_track, LocalTrack::None) {
|
||||
return Ok(self.share_microphone(cx));
|
||||
}
|
||||
|
||||
let (ret_task, old_muted) = live_kit.set_mute(should_mute, cx)?;
|
||||
live_kit.muted_by_user = should_mute;
|
||||
|
||||
|
@ -652,10 +652,10 @@ impl CollabTitlebarItem {
|
||||
let is_muted = room.read(cx).is_muted();
|
||||
if is_muted {
|
||||
icon = "icons/radix/mic-mute.svg";
|
||||
tooltip = "Unmute microphone\nRight click for options";
|
||||
tooltip = "Unmute microphone";
|
||||
} else {
|
||||
icon = "icons/radix/mic.svg";
|
||||
tooltip = "Mute microphone\nRight click for options";
|
||||
tooltip = "Mute microphone";
|
||||
}
|
||||
|
||||
let titlebar = &theme.titlebar;
|
||||
@ -705,10 +705,10 @@ impl CollabTitlebarItem {
|
||||
let is_deafened = room.read(cx).is_deafened().unwrap_or(false);
|
||||
if is_deafened {
|
||||
icon = "icons/radix/speaker-off.svg";
|
||||
tooltip = "Unmute speakers\nRight click for options";
|
||||
tooltip = "Unmute speakers";
|
||||
} else {
|
||||
icon = "icons/radix/speaker-loud.svg";
|
||||
tooltip = "Mute speakers\nRight click for options";
|
||||
tooltip = "Mute speakers";
|
||||
}
|
||||
|
||||
let titlebar = &theme.titlebar;
|
||||
|
@ -18,13 +18,7 @@ use workspace::AppState;
|
||||
|
||||
actions!(
|
||||
collab,
|
||||
[
|
||||
ToggleScreenSharing,
|
||||
ToggleMute,
|
||||
ToggleDeafen,
|
||||
LeaveCall,
|
||||
ShareMicrophone
|
||||
]
|
||||
[ToggleScreenSharing, ToggleMute, ToggleDeafen, LeaveCall]
|
||||
);
|
||||
|
||||
pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
||||
@ -40,7 +34,6 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut AppContext) {
|
||||
cx.add_global_action(toggle_screen_sharing);
|
||||
cx.add_global_action(toggle_mute);
|
||||
cx.add_global_action(toggle_deafen);
|
||||
cx.add_global_action(share_microphone);
|
||||
}
|
||||
|
||||
pub fn toggle_screen_sharing(_: &ToggleScreenSharing, cx: &mut AppContext) {
|
||||
@ -85,10 +78,3 @@ pub fn toggle_deafen(_: &ToggleDeafen, cx: &mut AppContext) {
|
||||
.log_err();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn share_microphone(_: &ShareMicrophone, cx: &mut AppContext) {
|
||||
if let Some(room) = ActiveCall::global(cx).read(cx).room().cloned() {
|
||||
room.update(cx, Room::share_microphone)
|
||||
.detach_and_log_err(cx)
|
||||
}
|
||||
}
|
||||
|
@ -1311,7 +1311,7 @@ impl EditorElement {
|
||||
}
|
||||
|
||||
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &ViewContext<Editor>) -> f32 {
|
||||
let digit_count = (snapshot.max_buffer_row() as f32).log10().floor() as usize + 1;
|
||||
let digit_count = (snapshot.max_buffer_row() as f32 + 1.).log10().floor() as usize + 1;
|
||||
let style = &self.style;
|
||||
|
||||
cx.text_layout_cache()
|
||||
|
@ -6,7 +6,7 @@ import ScreenCaptureKit
|
||||
class LKRoomDelegate: RoomDelegate {
|
||||
var data: UnsafeRawPointer
|
||||
var onDidDisconnect: @convention(c) (UnsafeRawPointer) -> Void
|
||||
var onDidSubscribeToRemoteAudioTrack: @convention(c) (UnsafeRawPointer, CFString, CFString, UnsafeRawPointer) -> Void
|
||||
var onDidSubscribeToRemoteAudioTrack: @convention(c) (UnsafeRawPointer, CFString, CFString, UnsafeRawPointer, UnsafeRawPointer) -> Void
|
||||
var onDidUnsubscribeFromRemoteAudioTrack: @convention(c) (UnsafeRawPointer, CFString, CFString) -> Void
|
||||
var onMuteChangedFromRemoteAudioTrack: @convention(c) (UnsafeRawPointer, CFString, Bool) -> Void
|
||||
var onActiveSpeakersChanged: @convention(c) (UnsafeRawPointer, CFArray) -> Void
|
||||
@ -16,7 +16,7 @@ class LKRoomDelegate: RoomDelegate {
|
||||
init(
|
||||
data: UnsafeRawPointer,
|
||||
onDidDisconnect: @escaping @convention(c) (UnsafeRawPointer) -> Void,
|
||||
onDidSubscribeToRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, CFString, UnsafeRawPointer) -> Void,
|
||||
onDidSubscribeToRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, CFString, UnsafeRawPointer, UnsafeRawPointer) -> Void,
|
||||
onDidUnsubscribeFromRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, CFString) -> Void,
|
||||
onMuteChangedFromRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, Bool) -> Void,
|
||||
onActiveSpeakersChanged: @convention(c) (UnsafeRawPointer, CFArray) -> Void,
|
||||
@ -43,7 +43,7 @@ class LKRoomDelegate: RoomDelegate {
|
||||
if track.kind == .video {
|
||||
self.onDidSubscribeToRemoteVideoTrack(self.data, participant.identity as CFString, track.sid! as CFString, Unmanaged.passUnretained(track).toOpaque())
|
||||
} else if track.kind == .audio {
|
||||
self.onDidSubscribeToRemoteAudioTrack(self.data, participant.identity as CFString, track.sid! as CFString, Unmanaged.passUnretained(track).toOpaque())
|
||||
self.onDidSubscribeToRemoteAudioTrack(self.data, participant.identity as CFString, track.sid! as CFString, Unmanaged.passUnretained(track).toOpaque(), Unmanaged.passUnretained(publication).toOpaque())
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,12 +52,12 @@ class LKRoomDelegate: RoomDelegate {
|
||||
self.onMuteChangedFromRemoteAudioTrack(self.data, publication.sid as CFString, muted)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func room(_ room: Room, didUpdate speakers: [Participant]) {
|
||||
guard let speaker_ids = speakers.compactMap({ $0.identity as CFString }) as CFArray? else { return }
|
||||
self.onActiveSpeakersChanged(self.data, speaker_ids)
|
||||
}
|
||||
|
||||
|
||||
func room(_ room: Room, participant: RemoteParticipant, didUnsubscribe publication: RemoteTrackPublication, track: Track) {
|
||||
if track.kind == .video {
|
||||
self.onDidUnsubscribeFromRemoteVideoTrack(self.data, participant.identity as CFString, track.sid! as CFString)
|
||||
@ -104,7 +104,7 @@ class LKVideoRenderer: NSObject, VideoRenderer {
|
||||
public func LKRoomDelegateCreate(
|
||||
data: UnsafeRawPointer,
|
||||
onDidDisconnect: @escaping @convention(c) (UnsafeRawPointer) -> Void,
|
||||
onDidSubscribeToRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, CFString, UnsafeRawPointer) -> Void,
|
||||
onDidSubscribeToRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, CFString, UnsafeRawPointer, UnsafeRawPointer) -> Void,
|
||||
onDidUnsubscribeFromRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, CFString) -> Void,
|
||||
onMuteChangedFromRemoteAudioTrack: @escaping @convention(c) (UnsafeRawPointer, CFString, Bool) -> Void,
|
||||
onActiveSpeakerChanged: @escaping @convention(c) (UnsafeRawPointer, CFArray) -> Void,
|
||||
@ -180,39 +180,39 @@ public func LKRoomUnpublishTrack(room: UnsafeRawPointer, publication: UnsafeRawP
|
||||
@_cdecl("LKRoomAudioTracksForRemoteParticipant")
|
||||
public func LKRoomAudioTracksForRemoteParticipant(room: UnsafeRawPointer, participantId: CFString) -> CFArray? {
|
||||
let room = Unmanaged<Room>.fromOpaque(room).takeUnretainedValue()
|
||||
|
||||
|
||||
for (_, participant) in room.remoteParticipants {
|
||||
if participant.identity == participantId as String {
|
||||
return participant.audioTracks.compactMap { $0.track as? RemoteAudioTrack } as CFArray?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@_cdecl("LKRoomAudioTrackPublicationsForRemoteParticipant")
|
||||
public func LKRoomAudioTrackPublicationsForRemoteParticipant(room: UnsafeRawPointer, participantId: CFString) -> CFArray? {
|
||||
let room = Unmanaged<Room>.fromOpaque(room).takeUnretainedValue()
|
||||
|
||||
|
||||
for (_, participant) in room.remoteParticipants {
|
||||
if participant.identity == participantId as String {
|
||||
return participant.audioTracks.compactMap { $0 as? RemoteTrackPublication } as CFArray?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@_cdecl("LKRoomVideoTracksForRemoteParticipant")
|
||||
public func LKRoomVideoTracksForRemoteParticipant(room: UnsafeRawPointer, participantId: CFString) -> CFArray? {
|
||||
let room = Unmanaged<Room>.fromOpaque(room).takeUnretainedValue()
|
||||
|
||||
|
||||
for (_, participant) in room.remoteParticipants {
|
||||
if participant.identity == participantId as String {
|
||||
return participant.videoTracks.compactMap { $0.track as? RemoteVideoTrack } as CFArray?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ public func LKLocalAudioTrackCreateTrack() -> UnsafeMutableRawPointer {
|
||||
echoCancellation: true,
|
||||
noiseSuppression: true
|
||||
))
|
||||
|
||||
|
||||
return Unmanaged.passRetained(track).toOpaque()
|
||||
}
|
||||
|
||||
@ -276,7 +276,7 @@ public func LKLocalTrackPublicationSetMute(
|
||||
callback_data: UnsafeRawPointer
|
||||
) {
|
||||
let publication = Unmanaged<LocalTrackPublication>.fromOpaque(publication).takeUnretainedValue()
|
||||
|
||||
|
||||
if muted {
|
||||
publication.mute().then {
|
||||
on_complete(callback_data, nil)
|
||||
@ -307,3 +307,21 @@ public func LKRemoteTrackPublicationSetEnabled(
|
||||
on_complete(callback_data, error.localizedDescription as CFString)
|
||||
}
|
||||
}
|
||||
|
||||
@_cdecl("LKRemoteTrackPublicationIsMuted")
|
||||
public func LKRemoteTrackPublicationIsMuted(
|
||||
publication: UnsafeRawPointer
|
||||
) -> Bool {
|
||||
let publication = Unmanaged<RemoteTrackPublication>.fromOpaque(publication).takeUnretainedValue()
|
||||
|
||||
return publication.muted
|
||||
}
|
||||
|
||||
@_cdecl("LKRemoteTrackPublicationGetSid")
|
||||
public func LKRemoteTrackPublicationGetSid(
|
||||
publication: UnsafeRawPointer
|
||||
) -> CFString {
|
||||
let publication = Unmanaged<RemoteTrackPublication>.fromOpaque(publication).takeUnretainedValue()
|
||||
|
||||
return publication.sid as CFString
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ fn main() {
|
||||
let audio_track = LocalAudioTrack::create();
|
||||
let audio_track_publication = room_a.publish_audio_track(&audio_track).await.unwrap();
|
||||
|
||||
if let RemoteAudioTrackUpdate::Subscribed(track) =
|
||||
if let RemoteAudioTrackUpdate::Subscribed(track, _) =
|
||||
audio_track_updates.next().await.unwrap()
|
||||
{
|
||||
let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
|
||||
|
@ -26,6 +26,7 @@ extern "C" {
|
||||
publisher_id: CFStringRef,
|
||||
track_id: CFStringRef,
|
||||
remote_track: *const c_void,
|
||||
remote_publication: *const c_void,
|
||||
),
|
||||
on_did_unsubscribe_from_remote_audio_track: extern "C" fn(
|
||||
callback_data: *mut c_void,
|
||||
@ -125,6 +126,9 @@ extern "C" {
|
||||
on_complete: extern "C" fn(callback_data: *mut c_void, error: CFStringRef),
|
||||
callback_data: *mut c_void,
|
||||
);
|
||||
|
||||
fn LKRemoteTrackPublicationIsMuted(publication: *const c_void) -> bool;
|
||||
fn LKRemoteTrackPublicationGetSid(publication: *const c_void) -> CFStringRef;
|
||||
}
|
||||
|
||||
pub type Sid = String;
|
||||
@ -372,10 +376,11 @@ impl Room {
|
||||
rx
|
||||
}
|
||||
|
||||
fn did_subscribe_to_remote_audio_track(&self, track: RemoteAudioTrack) {
|
||||
fn did_subscribe_to_remote_audio_track(&self, track: RemoteAudioTrack, publication: RemoteTrackPublication) {
|
||||
let track = Arc::new(track);
|
||||
let publication = Arc::new(publication);
|
||||
self.remote_audio_track_subscribers.lock().retain(|tx| {
|
||||
tx.unbounded_send(RemoteAudioTrackUpdate::Subscribed(track.clone()))
|
||||
tx.unbounded_send(RemoteAudioTrackUpdate::Subscribed(track.clone(), publication.clone()))
|
||||
.is_ok()
|
||||
});
|
||||
}
|
||||
@ -501,13 +506,15 @@ impl RoomDelegate {
|
||||
publisher_id: CFStringRef,
|
||||
track_id: CFStringRef,
|
||||
track: *const c_void,
|
||||
publication: *const c_void,
|
||||
) {
|
||||
let room = unsafe { Weak::from_raw(room as *mut Room) };
|
||||
let publisher_id = unsafe { CFString::wrap_under_get_rule(publisher_id).to_string() };
|
||||
let track_id = unsafe { CFString::wrap_under_get_rule(track_id).to_string() };
|
||||
let track = RemoteAudioTrack::new(track, track_id, publisher_id);
|
||||
let publication = RemoteTrackPublication::new(publication);
|
||||
if let Some(room) = room.upgrade() {
|
||||
room.did_subscribe_to_remote_audio_track(track);
|
||||
room.did_subscribe_to_remote_audio_track(track, publication);
|
||||
}
|
||||
let _ = Weak::into_raw(room);
|
||||
}
|
||||
@ -682,6 +689,14 @@ impl RemoteTrackPublication {
|
||||
Self(native_track_publication)
|
||||
}
|
||||
|
||||
pub fn sid(&self) -> String {
|
||||
unsafe { CFString::wrap_under_get_rule(LKRemoteTrackPublicationGetSid(self.0)).to_string() }
|
||||
}
|
||||
|
||||
pub fn is_muted(&self) -> bool {
|
||||
unsafe { LKRemoteTrackPublicationIsMuted(self.0) }
|
||||
}
|
||||
|
||||
pub fn set_enabled(&self, enabled: bool) -> impl Future<Output = Result<()>> {
|
||||
let (tx, rx) = futures::channel::oneshot::channel();
|
||||
|
||||
@ -832,7 +847,7 @@ pub enum RemoteVideoTrackUpdate {
|
||||
pub enum RemoteAudioTrackUpdate {
|
||||
ActiveSpeakersChanged { speakers: Vec<Sid> },
|
||||
MuteChanged { track_id: Sid, muted: bool },
|
||||
Subscribed(Arc<RemoteAudioTrack>),
|
||||
Subscribed(Arc<RemoteAudioTrack>, Arc<RemoteTrackPublication>),
|
||||
Unsubscribed { publisher_id: Sid, track_id: Sid },
|
||||
}
|
||||
|
||||
|
@ -216,6 +216,8 @@ impl TestServer {
|
||||
publisher_id: identity.clone(),
|
||||
});
|
||||
|
||||
let publication = Arc::new(RemoteTrackPublication);
|
||||
|
||||
room.audio_tracks.push(track.clone());
|
||||
|
||||
for (id, client_room) in &room.client_rooms {
|
||||
@ -225,7 +227,7 @@ impl TestServer {
|
||||
.lock()
|
||||
.audio_track_updates
|
||||
.0
|
||||
.try_broadcast(RemoteAudioTrackUpdate::Subscribed(track.clone()))
|
||||
.try_broadcast(RemoteAudioTrackUpdate::Subscribed(track.clone(), publication.clone()))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
@ -501,6 +503,14 @@ impl RemoteTrackPublication {
|
||||
pub fn set_enabled(&self, _enabled: bool) -> impl Future<Output = Result<()>> {
|
||||
async { Ok(()) }
|
||||
}
|
||||
|
||||
pub fn is_muted(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn sid(&self) -> String {
|
||||
"".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -579,7 +589,7 @@ pub enum RemoteVideoTrackUpdate {
|
||||
pub enum RemoteAudioTrackUpdate {
|
||||
ActiveSpeakersChanged { speakers: Vec<Sid> },
|
||||
MuteChanged { track_id: Sid, muted: bool },
|
||||
Subscribed(Arc<RemoteAudioTrack>),
|
||||
Subscribed(Arc<RemoteAudioTrack>, Arc<RemoteTrackPublication>),
|
||||
Unsubscribed { publisher_id: Sid, track_id: Sid },
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user