added prelude & cleaned imports (#27)

* wip

* wip

* wip

* wip

* wip

* wip
This commit is contained in:
Théo Monnom
2023-01-10 22:57:27 +01:00
committed by GitHub
parent 1168e5ae89
commit 4c5828b9c0
31 changed files with 345 additions and 329 deletions
+15
View File
@@ -0,0 +1,15 @@
use livekit::prelude::*;
use livekit::{RoomResult, SimulateScenario};
#[derive(Debug)]
pub enum AsyncCmd {
RoomConnect { url: String, token: String },
RoomDisconnect,
SimulateScenario { scenario: SimulateScenario },
}
#[derive(Debug)]
pub enum UiCmd {
ConnectResult { result: RoomResult<()> },
RoomEvent { event: RoomEvent },
}
+2 -6
View File
@@ -3,12 +3,8 @@ use crate::video_renderer::VideoRenderer;
use crate::{events::AsyncCmd, video_grid::VideoGrid}; use crate::{events::AsyncCmd, video_grid::VideoGrid};
use egui::{Rounding, Stroke}; use egui::{Rounding, Stroke};
use egui_wgpu::WgpuConfiguration; use egui_wgpu::WgpuConfiguration;
use livekit::room::id::{ParticipantSid, TrackSid}; use livekit::prelude::*;
use livekit::room::participant::ParticipantTrait; use livekit::SimulateScenario;
use livekit::room::room_session::ConnectionState;
use livekit::room::track::remote_track::RemoteTrackHandle;
use livekit::room::track::TrackTrait;
use livekit::room::{Room, RoomEvent, RoomEvents, SimulateScenario};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{ use std::sync::{
+2 -1
View File
@@ -1,4 +1,5 @@
use livekit::room::{RoomEvent, RoomResult, SimulateScenario}; use livekit::prelude::*;
use livekit::{RoomResult, SimulateScenario};
#[derive(Debug)] #[derive(Debug)]
pub enum AsyncCmd { pub enum AsyncCmd {
+2 -4
View File
@@ -1,7 +1,5 @@
use livekit::webrtc::media_stream::VideoTrack; use livekit::prelude::*;
use livekit::webrtc::video_frame_buffer::PlanarYuv8Buffer; use livekit::webrtc::video_frame_buffer::*;
use livekit::webrtc::video_frame_buffer::PlanarYuvBuffer;
use livekit::webrtc::video_frame_buffer::VideoFrameBufferTrait;
use livekit::webrtc::yuv_helper; use livekit::webrtc::yuv_helper;
use std::convert::TryInto; use std::convert::TryInto;
use std::num::NonZeroU32; use std::num::NonZeroU32;
+1 -1
View File
@@ -1,6 +1,6 @@
use std::error::Error; use std::error::Error;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::sync::{Arc, Mutex}; use std::sync::Mutex;
use cxx::UniquePtr; use cxx::UniquePtr;
use log::trace; use log::trace;
+2
View File
@@ -10,3 +10,5 @@ pub mod video_frame;
pub mod video_frame_buffer; pub mod video_frame_buffer;
pub mod webrtc; pub mod webrtc;
pub mod yuv_helper; pub mod yuv_helper;
pub mod prelude;
+18
View File
@@ -0,0 +1,18 @@
pub use crate::data_channel::{DataChannel, DataChannelInit, DataState};
pub use crate::jsep::{IceCandidate, SessionDescription};
pub use crate::media_stream::{
AudioTrack, MediaStream, MediaStreamTrackHandle, MediaStreamTrackTrait, VideoTrack,
};
pub use crate::peer_connection::{
IceConnectionState, IceGatheringState, PeerConnection, PeerConnectionState,
RTCOfferAnswerOptions, SignalingState,
};
pub use crate::peer_connection_factory::{
ContinualGatheringPolicy, ICEServer, IceTransportsType, PeerConnectionFactory, RTCConfiguration,
};
pub use crate::rtc_error::RTCError;
pub use crate::rtp_receiver::RtpReceiver;
pub use crate::rtp_transceiver::RtpTransceiver;
pub use crate::video_frame::{VideoFrame, VideoRotation};
pub use crate::video_frame_buffer::*;
pub use crate::webrtc::RTCRuntime;
+6 -1
View File
@@ -6,8 +6,13 @@ pub mod proto {
mod rtc_engine; mod rtc_engine;
mod signal_client; mod signal_client;
mod room;
pub mod room;
pub mod webrtc { pub mod webrtc {
pub use livekit_webrtc::*; pub use livekit_webrtc::*;
} }
pub use room::*;
/// `use livekit::prelude::*;` to import livekit types
pub mod prelude;
+26
View File
@@ -0,0 +1,26 @@
pub use crate::participant::{
LocalParticipant, Participant, ParticipantEvent, ParticipantTrait, RemoteParticipant,
};
pub use crate::{ConnectionState, Room, RoomError, RoomEvent, RoomEvents, RoomSession};
pub use crate::publication::{
LocalTrackPublication, RemoteTrackPublication, TrackPublication, TrackPublicationTrait,
};
pub use crate::track::{
AudioTrackHandle, LocalAudioTrack, LocalTrackHandle, LocalVideoTrack, RemoteAudioTrack,
RemoteTrackHandle, RemoteVideoTrack, StreamState, TrackEvent, TrackHandle, TrackKind,
TrackSource, TrackTrait, VideoTrackHandle,
};
pub use crate::id::*;
pub use crate::webrtc::{
data_channel::DataChannel,
media_stream::{
AudioTrack, MediaStream, MediaStreamTrackHandle, MediaStreamTrackTrait, VideoTrack,
},
rtp_receiver::RtpReceiver,
rtp_transceiver::RtpTransceiver,
};
+7 -17
View File
@@ -1,12 +1,6 @@
use self::participant::ConnectionQuality; use crate::prelude::*;
use self::room_session::{ConnectionState, RoomSession, SessionHandle}; use crate::participant::ConnectionQuality;
use crate::proto::data_packet; use crate::proto;
use crate::room::id::TrackSid;
use crate::room::participant::remote_participant::RemoteParticipant;
use crate::room::participant::Participant;
use crate::room::publication::RemoteTrackPublication;
use crate::room::publication::TrackPublication;
use crate::room::track::remote_track::RemoteTrackHandle;
use crate::rtc_engine::EngineError; use crate::rtc_engine::EngineError;
use std::fmt::Debug; use std::fmt::Debug;
use std::sync::Arc; use std::sync::Arc;
@@ -21,6 +15,8 @@ pub mod publication;
pub mod room_session; pub mod room_session;
pub mod track; pub mod track;
pub use room_session::*;
pub type RoomEvents = mpsc::UnboundedReceiver<RoomEvent>; pub type RoomEvents = mpsc::UnboundedReceiver<RoomEvent>;
pub type RoomEmitter = mpsc::UnboundedSender<RoomEvent>; pub type RoomEmitter = mpsc::UnboundedSender<RoomEvent>;
pub type RoomResult<T> = Result<T, RoomError>; pub type RoomResult<T> = Result<T, RoomError>;
@@ -33,12 +29,6 @@ pub enum RoomError {
Internal(String), Internal(String),
} }
#[derive(Error, Debug, Clone)]
pub enum TrackError {
#[error("could not find published track with sid: {0}")]
TrackNotFound(String),
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum RoomEvent { pub enum RoomEvent {
ParticipantConnected(Arc<RemoteParticipant>), ParticipantConnected(Arc<RemoteParticipant>),
@@ -62,7 +52,7 @@ pub enum RoomEvent {
participant: Arc<RemoteParticipant>, participant: Arc<RemoteParticipant>,
}, },
TrackSubscriptionFailed { TrackSubscriptionFailed {
error: TrackError, error: track::TrackError,
sid: TrackSid, sid: TrackSid,
participant: Arc<RemoteParticipant>, participant: Arc<RemoteParticipant>,
}, },
@@ -83,7 +73,7 @@ pub enum RoomEvent {
}, },
DataReceived { DataReceived {
payload: Arc<Vec<u8>>, payload: Arc<Vec<u8>>,
kind: data_packet::Kind, kind: proto::data_packet::Kind,
participant: Arc<RemoteParticipant>, participant: Arc<RemoteParticipant>,
}, },
ConnectionStateChanged(ConnectionState), ConnectionStateChanged(ConnectionState),
@@ -1,12 +1,9 @@
use super::ConnectionQuality; use super::{
use crate::proto::{data_packet, DataPacket, ParticipantInfo, UserPacket}; impl_participant_trait, ConnectionQuality, ParticipantInternalTrait, ParticipantShared,
use crate::room::id::{ParticipantIdentity, ParticipantSid, TrackSid};
use crate::room::participant::{
impl_participant_trait, ParticipantEvent, ParticipantInternalTrait, ParticipantShared,
ParticipantTrait,
}; };
use crate::room::publication::TrackPublication; use crate::prelude::*;
use crate::room::RoomError; use crate::proto;
use crate::publication::TrackPublication;
use crate::rtc_engine::RTCEngine; use crate::rtc_engine::RTCEngine;
use parking_lot::RwLockReadGuard; use parking_lot::RwLockReadGuard;
use std::collections::HashMap; use std::collections::HashMap;
@@ -37,11 +34,11 @@ impl LocalParticipant {
pub async fn publish_data( pub async fn publish_data(
&self, &self,
data: &[u8], data: &[u8],
kind: data_packet::Kind, kind: proto::data_packet::Kind,
) -> Result<(), RoomError> { ) -> Result<(), RoomError> {
let data = DataPacket { let data = proto::DataPacket {
kind: kind as i32, kind: kind as i32,
value: Some(data_packet::Value::User(UserPacket { value: Some(proto::data_packet::Value::User(proto::UserPacket {
participant_sid: self.sid().to_string(), participant_sid: self.sid().to_string(),
payload: data.to_vec(), payload: data.to_vec(),
destination_sids: vec![], destination_sids: vec![],
@@ -56,7 +53,7 @@ impl LocalParticipant {
} }
impl ParticipantInternalTrait for LocalParticipant { impl ParticipantInternalTrait for LocalParticipant {
fn update_info(self: &Arc<Self>, info: ParticipantInfo, _emit_events: bool) { fn update_info(self: &Arc<Self>, info: proto::ParticipantInfo, _emit_events: bool) {
self.shared.update_info(info); self.shared.update_info(info);
} }
+11 -15
View File
@@ -1,23 +1,19 @@
use super::publication::RemoteTrackPublication; use crate::prelude::*;
use super::TrackError;
use crate::proto; use crate::proto;
use crate::proto::ParticipantInfo; use crate::track::TrackError;
use crate::room::id::{ParticipantIdentity, ParticipantSid, TrackSid};
use crate::room::participant::local_participant::LocalParticipant;
use crate::room::participant::remote_participant::RemoteParticipant;
use crate::room::publication::{TrackPublication, TrackPublicationTrait};
use crate::room::track::remote_track::RemoteTrackHandle;
use livekit_utils::enum_dispatch; use livekit_utils::enum_dispatch;
use livekit_utils::observer::Dispatcher; use livekit_utils::observer::Dispatcher;
use parking_lot::{Mutex, RwLock, RwLockReadGuard}; use parking_lot::{Mutex, RwLock, RwLockReadGuard};
use proto::data_packet;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU8, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU8, Ordering};
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::mpsc; use tokio::sync::mpsc;
pub mod local_participant; mod local_participant;
pub mod remote_participant; mod remote_participant;
pub use local_participant::*;
pub use remote_participant::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ParticipantEvent { pub enum ParticipantEvent {
@@ -41,7 +37,7 @@ pub enum ParticipantEvent {
}, },
DataReceived { DataReceived {
payload: Arc<Vec<u8>>, payload: Arc<Vec<u8>>,
kind: data_packet::Kind, kind: proto::data_packet::Kind,
}, },
SpeakingChanged { SpeakingChanged {
speaking: bool, speaking: bool,
@@ -120,7 +116,7 @@ impl ParticipantShared {
} }
} }
pub(crate) fn update_info(&self, info: ParticipantInfo) { pub(crate) fn update_info(&self, info: proto::ParticipantInfo) {
*self.sid.lock() = info.sid.into(); *self.sid.lock() = info.sid.into();
*self.identity.lock() = info.identity.into(); *self.identity.lock() = info.identity.into();
*self.name.lock() = info.name; *self.name.lock() = info.name;
@@ -154,7 +150,7 @@ pub(crate) trait ParticipantInternalTrait {
fn set_speaking(&self, speaking: bool); fn set_speaking(&self, speaking: bool);
fn set_audio_level(&self, level: f32); fn set_audio_level(&self, level: f32);
fn set_connection_quality(&self, quality: ConnectionQuality); fn set_connection_quality(&self, quality: ConnectionQuality);
fn update_info(self: &Arc<Self>, info: ParticipantInfo, emit_events: bool); fn update_info(self: &Arc<Self>, info: proto::ParticipantInfo, emit_events: bool);
} }
pub trait ParticipantTrait { pub trait ParticipantTrait {
@@ -180,7 +176,7 @@ pub enum Participant {
impl Participant { impl Participant {
enum_dispatch!( enum_dispatch!(
[Local, Remote] [Local, Remote]
fnc!(pub(crate), update_info, &Self, [info: ParticipantInfo, emit_events: bool], ()); fnc!(pub(crate), update_info, &Self, [info: proto::ParticipantInfo, emit_events: bool], ());
fnc!(pub(crate), set_speaking, &Self, [speaking: bool], ()); fnc!(pub(crate), set_speaking, &Self, [speaking: bool], ());
fnc!(pub(crate), set_audio_level, &Self, [audio_level: f32], ()); fnc!(pub(crate), set_audio_level, &Self, [audio_level: f32], ());
fnc!(pub(crate), set_connection_quality, &Self, [quality: ConnectionQuality], ()); fnc!(pub(crate), set_connection_quality, &Self, [quality: ConnectionQuality], ());
@@ -1,19 +1,11 @@
use super::ConnectionQuality; use super::{
use crate::proto::{data_packet, DataPacket, ParticipantInfo, UserPacket}; impl_participant_trait, ConnectionQuality, ParticipantInternalTrait, ParticipantShared,
use crate::room::id::{ParticipantIdentity, ParticipantSid, TrackSid};
use crate::room::participant::{
impl_participant_trait, ParticipantEvent, ParticipantInternalTrait, ParticipantShared,
ParticipantTrait,
}; };
use crate::room::publication::{ use crate::prelude::*;
RemoteTrackPublication, TrackPublication, TrackPublicationInternalTrait, TrackPublicationTrait, use crate::proto;
}; use crate::publication::TrackPublicationInternalTrait;
use crate::room::track::remote_audio_track::RemoteAudioTrack; use crate::track::TrackError;
use crate::room::track::remote_track::RemoteTrackHandle; use livekit_webrtc::prelude::*;
use crate::room::track::remote_video_track::RemoteVideoTrack;
use crate::room::track::{TrackKind, TrackTrait};
use crate::room::TrackError;
use livekit_webrtc::media_stream::MediaStreamTrackHandle;
use parking_lot::RwLockReadGuard; use parking_lot::RwLockReadGuard;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
@@ -55,7 +47,7 @@ impl RemoteParticipant {
/// Called by the RoomSession when receiving data by the RTCSession /// Called by the RoomSession when receiving data by the RTCSession
/// It is just used to emit the Data event on the participant dispatcher. /// It is just used to emit the Data event on the participant dispatcher.
pub(crate) fn on_data_received(&self, data: Arc<Vec<u8>>, kind: data_packet::Kind) { pub(crate) fn on_data_received(&self, data: Arc<Vec<u8>>, kind: proto::data_packet::Kind) {
self.shared self.shared
.dispatcher .dispatcher
.lock() .lock()
@@ -172,7 +164,7 @@ impl RemoteParticipant {
} }
impl ParticipantInternalTrait for RemoteParticipant { impl ParticipantInternalTrait for RemoteParticipant {
fn update_info(self: &Arc<Self>, info: ParticipantInfo, emit_events: bool) { fn update_info(self: &Arc<Self>, info: proto::ParticipantInfo, emit_events: bool) {
self.shared.update_info(info.clone()); self.shared.update_info(info.clone());
let mut valid_tracks = HashSet::<TrackSid>::new(); let mut valid_tracks = HashSet::<TrackSid>::new();
+19 -18
View File
@@ -1,10 +1,5 @@
use crate::proto::TrackType; use crate::prelude::*;
use crate::proto::{TrackInfo, TrackSource as ProtoTrackSource}; use crate::proto;
use crate::room::id::ParticipantSid;
use crate::room::id::TrackSid;
use crate::room::track::local_track::LocalTrackHandle;
use crate::room::track::remote_track::RemoteTrackHandle;
use crate::room::track::{TrackHandle, TrackKind, TrackSource, TrackTrait};
use livekit_utils::enum_dispatch; use livekit_utils::enum_dispatch;
use livekit_utils::observer::Dispatcher; use livekit_utils::observer::Dispatcher;
use parking_lot::Mutex; use parking_lot::Mutex;
@@ -16,7 +11,7 @@ use super::track::{TrackDimension, TrackEvent};
pub(crate) trait TrackPublicationInternalTrait { pub(crate) trait TrackPublicationInternalTrait {
fn update_track(&self, track: Option<TrackHandle>); fn update_track(&self, track: Option<TrackHandle>);
fn update_info(&self, info: TrackInfo); fn update_info(&self, info: proto::TrackInfo);
} }
pub trait TrackPublicationTrait { pub trait TrackPublicationTrait {
@@ -46,7 +41,7 @@ pub(super) struct TrackPublicationShared {
impl TrackPublicationShared { impl TrackPublicationShared {
pub fn new( pub fn new(
info: TrackInfo, info: proto::TrackInfo,
participant: ParticipantSid, participant: ParticipantSid,
track: Option<TrackHandle>, track: Option<TrackHandle>,
) -> Arc<Self> { ) -> Arc<Self> {
@@ -54,9 +49,11 @@ impl TrackPublicationShared {
track: Mutex::new(track), track: Mutex::new(track),
name: Mutex::new(info.name), name: Mutex::new(info.name),
sid: Mutex::new(info.sid.into()), sid: Mutex::new(info.sid.into()),
kind: AtomicU8::new(TrackKind::from(TrackType::from_i32(info.r#type).unwrap()) as u8), kind: AtomicU8::new(
TrackKind::from(proto::TrackType::from_i32(info.r#type).unwrap()) as u8,
),
source: AtomicU8::new(TrackSource::from( source: AtomicU8::new(TrackSource::from(
ProtoTrackSource::from_i32(info.source).unwrap(), proto::TrackSource::from_i32(info.source).unwrap(),
) as u8), ) as u8),
simulcasted: AtomicBool::new(info.simulcast), simulcasted: AtomicBool::new(info.simulcast),
dimension: Mutex::new(TrackDimension(info.width, info.height)), dimension: Mutex::new(TrackDimension(info.width, info.height)),
@@ -106,17 +103,17 @@ impl TrackPublicationShared {
} }
} }
pub fn update_info(&self, info: TrackInfo) { pub fn update_info(&self, info: proto::TrackInfo) {
*self.name.lock() = info.name; *self.name.lock() = info.name;
*self.sid.lock() = info.sid.into(); *self.sid.lock() = info.sid.into();
*self.dimension.lock() = TrackDimension(info.width, info.height); *self.dimension.lock() = TrackDimension(info.width, info.height);
*self.mime_type.lock() = info.mime_type; *self.mime_type.lock() = info.mime_type;
self.kind.store( self.kind.store(
TrackKind::from(TrackType::from_i32(info.r#type).unwrap()) as u8, TrackKind::from(proto::TrackType::from_i32(info.r#type).unwrap()) as u8,
Ordering::SeqCst, Ordering::SeqCst,
); );
self.source.store( self.source.store(
TrackSource::from(ProtoTrackSource::from_i32(info.source).unwrap()) as u8, TrackSource::from(proto::TrackSource::from_i32(info.source).unwrap()) as u8,
Ordering::SeqCst, Ordering::SeqCst,
); );
self.simulcasted.store(info.simulcast, Ordering::SeqCst); self.simulcasted.store(info.simulcast, Ordering::SeqCst);
@@ -156,7 +153,7 @@ impl TrackPublicationInternalTrait for TrackPublication {
enum_dispatch!( enum_dispatch!(
[Local, Remote] [Local, Remote]
fnc!(update_track, &Self, [track: Option<TrackHandle>], ()); fnc!(update_track, &Self, [track: Option<TrackHandle>], ());
fnc!(update_info, &Self, [info: TrackInfo], ()); fnc!(update_info, &Self, [info: proto::TrackInfo], ());
); );
} }
@@ -222,7 +219,7 @@ impl TrackPublicationInternalTrait for LocalTrackPublication {
self.shared.update_track(track); self.shared.update_track(track);
} }
fn update_info(&self, info: TrackInfo) { fn update_info(&self, info: proto::TrackInfo) {
self.shared.update_info(info); self.shared.update_info(info);
} }
} }
@@ -233,7 +230,11 @@ pub struct RemoteTrackPublication {
} }
impl RemoteTrackPublication { impl RemoteTrackPublication {
pub fn new(info: TrackInfo, participant: ParticipantSid, track: Option<TrackHandle>) -> Self { pub fn new(
info: proto::TrackInfo,
participant: ParticipantSid,
track: Option<TrackHandle>,
) -> Self {
Self { Self {
shared: TrackPublicationShared::new(info, participant, track), shared: TrackPublicationShared::new(info, participant, track),
} }
@@ -253,7 +254,7 @@ impl TrackPublicationInternalTrait for RemoteTrackPublication {
self.shared.update_track(track); self.shared.update_track(track);
} }
fn update_info(&self, info: TrackInfo) { fn update_info(&self, info: proto::TrackInfo) {
self.shared.update_info(info); self.shared.update_info(info);
} }
} }
+6 -9
View File
@@ -1,12 +1,9 @@
use super::id::{ParticipantIdentity, ParticipantSid}; use crate::participant::{ConnectionQuality, ParticipantInternalTrait};
use super::participant::local_participant::LocalParticipant; use crate::prelude::*;
use super::participant::remote_participant::RemoteParticipant; use crate::proto;
use super::participant::{ConnectionQuality, Participant, ParticipantEvent};
use super::participant::{ParticipantInternalTrait, ParticipantTrait};
use super::{RoomEmitter, RoomError, RoomEvent, RoomResult, SimulateScenario};
use crate::proto::{self, participant_info, SpeakerInfo};
use crate::rtc_engine::{EngineEvent, EngineEvents, EngineResult, RTCEngine}; use crate::rtc_engine::{EngineEvent, EngineEvents, EngineResult, RTCEngine};
use crate::signal_client::SignalOptions; use crate::signal_client::SignalOptions;
use crate::{RoomEmitter, RoomError, RoomEvent, RoomResult, SimulateScenario};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::atomic::{AtomicU8, Ordering};
@@ -365,7 +362,7 @@ impl SessionInner {
let remote_participant = self.get_participant(&pi.sid.clone().into()); let remote_participant = self.get_participant(&pi.sid.clone().into());
if let Some(remote_participant) = remote_participant { if let Some(remote_participant) = remote_participant {
if pi.state == participant_info::State::Disconnected as i32 { if pi.state == proto::participant_info::State::Disconnected as i32 {
// Participant disconnected // Participant disconnected
info!("Participant disconnected: {}", pi.sid); info!("Participant disconnected: {}", pi.sid);
self.clone() self.clone()
@@ -394,7 +391,7 @@ impl SessionInner {
/// Active speakers changed /// Active speakers changed
/// Update the participants & sort the active_speakers by audio_level /// Update the participants & sort the active_speakers by audio_level
#[instrument(level = Level::DEBUG)] #[instrument(level = Level::DEBUG)]
fn handle_speakers_changed(&self, speakers_info: Vec<SpeakerInfo>) { fn handle_speakers_changed(&self, speakers_info: Vec<proto::SpeakerInfo>) {
let mut speakers = Vec::new(); let mut speakers = Vec::new();
for speaker in speakers_info { for speaker in speakers_info {
+1 -3
View File
@@ -1,6 +1,4 @@
use crate::room::track::local_audio_track::LocalAudioTrack; use crate::prelude::*;
use crate::room::track::remote_audio_track::RemoteAudioTrack;
use crate::room::track::TrackHandle;
use std::sync::Arc; use std::sync::Arc;
#[derive(Clone)] #[derive(Clone)]
+1 -1
View File
@@ -1,4 +1,4 @@
use crate::room::track::{impl_track_trait, TrackShared}; use super::{impl_track_trait, TrackShared};
#[derive(Debug)] #[derive(Debug)]
pub struct LocalAudioTrack { pub struct LocalAudioTrack {
+1 -3
View File
@@ -1,6 +1,4 @@
use crate::room::track::local_audio_track::LocalAudioTrack; use crate::prelude::*;
use crate::room::track::local_video_track::LocalVideoTrack;
use crate::room::track::TrackHandle;
use std::sync::Arc; use std::sync::Arc;
#[derive(Clone)] #[derive(Clone)]
+1 -1
View File
@@ -1,4 +1,4 @@
use crate::room::track::{impl_track_trait, TrackShared}; use super::{impl_track_trait, TrackShared};
#[derive(Debug)] #[derive(Debug)]
pub struct LocalVideoTrack { pub struct LocalVideoTrack {
+29 -18
View File
@@ -1,15 +1,11 @@
use crate::proto::{TrackSource as ProtoTrackSource, TrackType}; use crate::prelude::*;
use crate::room::id::TrackSid; use crate::proto;
use crate::room::track::local_audio_track::LocalAudioTrack;
use crate::room::track::local_video_track::LocalVideoTrack;
use crate::room::track::remote_audio_track::RemoteAudioTrack;
use crate::room::track::remote_video_track::RemoteVideoTrack;
use livekit_utils::enum_dispatch; use livekit_utils::enum_dispatch;
use livekit_utils::observer::Dispatcher; use livekit_utils::observer::Dispatcher;
use livekit_webrtc::media_stream::{MediaStreamTrackHandle, MediaStreamTrackTrait};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::Arc; use std::sync::Arc;
use thiserror::Error;
use tokio::sync::mpsc; use tokio::sync::mpsc;
pub mod audio_track; pub mod audio_track;
@@ -21,6 +17,21 @@ pub mod remote_track;
pub mod remote_video_track; pub mod remote_video_track;
pub mod video_track; pub mod video_track;
pub use audio_track::*;
pub use local_audio_track::*;
pub use local_track::*;
pub use local_video_track::*;
pub use remote_audio_track::*;
pub use remote_track::*;
pub use remote_video_track::*;
pub use video_track::*;
#[derive(Error, Debug, Clone)]
pub enum TrackError {
#[error("could not find published track with sid: {0}")]
TrackNotFound(String),
}
#[derive(Debug)] #[derive(Debug)]
pub enum TrackKind { pub enum TrackKind {
Unknown, Unknown,
@@ -38,11 +49,11 @@ impl From<u8> for TrackKind {
} }
} }
impl From<TrackType> for TrackKind { impl From<proto::TrackType> for TrackKind {
fn from(r#type: TrackType) -> Self { fn from(r#type: proto::TrackType) -> Self {
match r#type { match r#type {
TrackType::Audio => Self::Audio, proto::TrackType::Audio => Self::Audio,
TrackType::Video => Self::Video, proto::TrackType::Video => Self::Video,
_ => Self::Unknown, _ => Self::Unknown,
} }
} }
@@ -86,14 +97,14 @@ impl From<u8> for TrackSource {
} }
} }
impl From<ProtoTrackSource> for TrackSource { impl From<proto::TrackSource> for TrackSource {
fn from(source: ProtoTrackSource) -> Self { fn from(source: proto::TrackSource) -> Self {
match source { match source {
ProtoTrackSource::Camera => Self::Camera, proto::TrackSource::Camera => Self::Camera,
ProtoTrackSource::Microphone => Self::Microphone, proto::TrackSource::Microphone => Self::Microphone,
ProtoTrackSource::ScreenShare => Self::Screenshare, proto::TrackSource::ScreenShare => Self::Screenshare,
ProtoTrackSource::ScreenShareAudio => Self::ScreenshareAudio, proto::TrackSource::ScreenShareAudio => Self::ScreenshareAudio,
ProtoTrackSource::Unknown => Self::Unknown, proto::TrackSource::Unknown => Self::Unknown,
} }
} }
} }
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::room::track::{impl_track_trait, TrackShared}; use super::{impl_track_trait, TrackShared};
use livekit_webrtc::media_stream::{AudioTrack, MediaStreamTrackHandle}; use crate::prelude::*;
use std::sync::Arc; use std::sync::Arc;
#[derive(Debug)] #[derive(Debug)]
+3 -9
View File
@@ -1,13 +1,7 @@
use std::sync::Arc; use crate::prelude::*;
use super::{StreamState, TrackKind};
use crate::room::id::TrackSid;
use crate::room::track::remote_audio_track::RemoteAudioTrack;
use crate::room::track::remote_video_track::RemoteVideoTrack;
use crate::room::track::{TrackHandle, TrackEvent};
use tokio::sync::mpsc;
use livekit_utils::enum_dispatch; use livekit_utils::enum_dispatch;
use std::sync::Arc;
use super::TrackTrait; use tokio::sync::mpsc;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum RemoteTrackHandle { pub enum RemoteTrackHandle {
+2 -3
View File
@@ -1,8 +1,7 @@
use livekit_webrtc::media_stream::{MediaStreamTrackHandle, VideoTrack}; use super::{impl_track_trait, TrackShared};
use crate::prelude::*;
use std::sync::Arc; use std::sync::Arc;
use crate::room::track::{impl_track_trait, TrackShared};
#[derive(Debug)] #[derive(Debug)]
pub struct RemoteVideoTrack { pub struct RemoteVideoTrack {
shared: TrackShared, shared: TrackShared,
+1 -3
View File
@@ -1,6 +1,4 @@
use crate::room::track::local_video_track::LocalVideoTrack; use crate::prelude::*;
use crate::room::track::remote_video_track::RemoteVideoTrack;
use crate::room::track::TrackHandle;
use std::sync::Arc; use std::sync::Arc;
#[derive(Clone)] #[derive(Clone)]
+2 -4
View File
@@ -1,9 +1,7 @@
use std::fmt::{Debug, Formatter};
use tracing::trace;
use livekit_webrtc::peer_connection_factory::PeerConnectionFactory; use livekit_webrtc::peer_connection_factory::PeerConnectionFactory;
use livekit_webrtc::webrtc::RTCRuntime; use livekit_webrtc::webrtc::RTCRuntime;
use std::fmt::{Debug, Formatter};
use tracing::trace;
/// SAFETY: The order of initialization and deletion is important for LKRuntime. /// SAFETY: The order of initialization and deletion is important for LKRuntime.
/// See the C++ constructors & destructors of these fields /// See the C++ constructors & destructors of these fields
+21 -28
View File
@@ -1,30 +1,24 @@
use crate::prelude::*;
use crate::proto;
use crate::rtc_engine::lk_runtime::LKRuntime;
use crate::rtc_engine::rtc_session::{RTCSession, SessionEvent, SessionEvents, SessionInfo};
use crate::signal_client::{SignalError, SignalOptions};
use futures::future::BoxFuture; use futures::future::BoxFuture;
use futures::FutureExt; use futures::FutureExt;
use lazy_static::lazy_static;
use livekit_webrtc::data_channel::DataSendError; use livekit_webrtc::data_channel::DataSendError;
use livekit_webrtc::jsep::SdpParseError; use livekit_webrtc::jsep::SdpParseError;
use livekit_webrtc::media_stream::{MediaStream, MediaStreamTrackHandle}; use livekit_webrtc::prelude::*;
use livekit_webrtc::rtc_error::RTCError;
use livekit_webrtc::rtp_receiver::RtpReceiver;
use parking_lot::Mutex; use parking_lot::Mutex;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use std::time::Duration; use std::time::Duration;
use thiserror::Error; use thiserror::Error;
use tokio::sync::RwLock as AsyncRwLock; use tokio::sync::RwLock as AsyncRwLock;
use tokio::sync::{mpsc, oneshot};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tokio::time::{interval, Interval}; use tokio::time::{interval, Interval};
use tracing::{error, info, warn};
use lazy_static::lazy_static;
use tokio::sync::{mpsc, oneshot};
use tracing::{error, info, trace, warn};
use crate::proto::{
self as proto, data_packet, DataPacket, JoinResponse, ParticipantUpdate, SpeakerInfo,
};
use crate::rtc_engine::lk_runtime::LKRuntime;
use crate::signal_client::{SignalError, SignalOptions};
use self::rtc_session::{RTCSession, SessionEvent, SessionEvents, SessionInfo};
mod lk_runtime; mod lk_runtime;
mod pc_transport; mod pc_transport;
@@ -80,10 +74,10 @@ pub enum EngineEvent {
Data { Data {
participant_sid: String, participant_sid: String,
payload: Vec<u8>, payload: Vec<u8>,
kind: data_packet::Kind, kind: proto::data_packet::Kind,
}, },
SpeakersChanged { SpeakersChanged {
speakers: Vec<SpeakerInfo>, speakers: Vec<proto::SpeakerInfo>,
}, },
ConnectionQuality { ConnectionQuality {
updates: Vec<proto::ConnectionQualityInfo>, updates: Vec<proto::ConnectionQualityInfo>,
@@ -133,21 +127,20 @@ pub struct RTCEngine {
impl RTCEngine { impl RTCEngine {
pub fn new() -> (Self, EngineEvents) { pub fn new() -> (Self, EngineEvents) {
let mut lk_runtime = None; let lk_runtime = {
{
let mut lk_runtime_ref = LK_RUNTIME.lock(); let mut lk_runtime_ref = LK_RUNTIME.lock();
lk_runtime = lk_runtime_ref.upgrade(); if let Some(lk_runtime) = lk_runtime_ref.upgrade() {
lk_runtime
if lk_runtime.is_none() { } else {
let new_runtime = Arc::new(LKRuntime::default()); let new_runtime = Arc::new(LKRuntime::default());
*lk_runtime_ref = Arc::downgrade(&new_runtime); *lk_runtime_ref = Arc::downgrade(&new_runtime);
lk_runtime = Some(new_runtime); new_runtime
} }
} };
let (engine_emitter, engine_events) = mpsc::channel(8); let (engine_emitter, engine_events) = mpsc::channel(8);
let inner = Arc::new(EngineInner { let inner = Arc::new(EngineInner {
lk_runtime: lk_runtime.unwrap(), lk_runtime,
session_info: Default::default(), session_info: Default::default(),
running_handle: Default::default(), running_handle: Default::default(),
opened: Default::default(), opened: Default::default(),
@@ -178,8 +171,8 @@ impl RTCEngine {
#[tracing::instrument(skip(data))] #[tracing::instrument(skip(data))]
pub async fn publish_data( pub async fn publish_data(
&self, &self,
data: &DataPacket, data: &proto::DataPacket,
kind: data_packet::Kind, kind: proto::data_packet::Kind,
) -> EngineResult<()> { ) -> EngineResult<()> {
self.inner.wait_reconnection().await?; self.inner.wait_reconnection().await?;
self.inner self.inner
@@ -207,7 +200,7 @@ impl RTCEngine {
Ok(()) Ok(())
} }
pub fn join_response(&self) -> Option<JoinResponse> { pub fn join_response(&self) -> Option<proto::JoinResponse> {
if let Some(info) = self.inner.session_info.lock().as_ref() { if let Some(info) = self.inner.session_info.lock().as_ref() {
Some(info.join_response.clone()) Some(info.join_response.clone())
} else { } else {
+5 -12
View File
@@ -1,18 +1,11 @@
use crate::proto;
use livekit_webrtc::prelude::*;
use std::fmt::{Debug, Formatter}; use std::fmt::{Debug, Formatter};
use std::future::Future; use std::future::Future;
use std::pin::Pin; use std::pin::Pin;
use std::time::Duration; use std::time::Duration;
use tracing::{event, Level}; use tracing::{event, Level};
use livekit_webrtc::jsep::{IceCandidate, SessionDescription};
use livekit_webrtc::peer_connection::{
IceConnectionState, PeerConnection, RTCOfferAnswerOptions, SignalingState,
};
use livekit_webrtc::rtc_error::RTCError;
use crate::proto::SignalTarget;
const NEGOTIATION_FREQUENCY: Duration = Duration::from_millis(150); const NEGOTIATION_FREQUENCY: Duration = Duration::from_millis(150);
pub type OnOfferHandler = Box< pub type OnOfferHandler = Box<
@@ -22,7 +15,7 @@ pub type OnOfferHandler = Box<
>; >;
pub struct PCTransport { pub struct PCTransport {
signal_target: SignalTarget, signal_target: proto::SignalTarget,
peer_connection: PeerConnection, peer_connection: PeerConnection,
pending_candidates: Vec<IceCandidate>, pending_candidates: Vec<IceCandidate>,
on_offer_handler: Option<OnOfferHandler>, on_offer_handler: Option<OnOfferHandler>,
@@ -37,7 +30,7 @@ impl Debug for PCTransport {
} }
impl PCTransport { impl PCTransport {
pub fn new(peer_connection: PeerConnection, signal_target: SignalTarget) -> Self { pub fn new(peer_connection: PeerConnection, signal_target: proto::SignalTarget) -> Self {
Self { Self {
signal_target, signal_target,
peer_connection, peer_connection,
@@ -58,7 +51,7 @@ impl PCTransport {
&mut self.peer_connection &mut self.peer_connection
} }
pub fn signal_target(&self) -> SignalTarget { pub fn signal_target(&self) -> proto::SignalTarget {
self.signal_target.clone() self.signal_target.clone()
} }
+19 -20
View File
@@ -1,19 +1,15 @@
use livekit_webrtc::data_channel::{DataChannel, OnMessageHandler}; use super::pc_transport::PCTransport;
use livekit_webrtc::jsep::{IceCandidate, SessionDescription}; use crate::proto;
use livekit_webrtc::media_stream::MediaStream; use crate::rtc_engine::pc_transport::OnOfferHandler;
use livekit_webrtc::data_channel::OnMessageHandler;
use livekit_webrtc::peer_connection::{ use livekit_webrtc::peer_connection::{
OnAddTrackHandler, OnConnectionChangeHandler, OnDataChannelHandler, OnIceCandidateErrorHandler, OnAddTrackHandler, OnConnectionChangeHandler, OnDataChannelHandler, OnIceCandidateErrorHandler,
OnIceCandidateHandler, PeerConnectionState, OnIceCandidateHandler, PeerConnectionState,
}; };
use livekit_webrtc::rtp_receiver::RtpReceiver; use livekit_webrtc::prelude::*;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tracing::error; use tracing::error;
use crate::proto::SignalTarget;
use crate::rtc_engine::pc_transport::OnOfferHandler;
use super::pc_transport::PCTransport;
pub type RTCEmitter = mpsc::UnboundedSender<RTCEvent>; pub type RTCEmitter = mpsc::UnboundedSender<RTCEvent>;
pub type RTCEvents = mpsc::UnboundedReceiver<RTCEvent>; pub type RTCEvents = mpsc::UnboundedReceiver<RTCEvent>;
@@ -21,25 +17,25 @@ pub type RTCEvents = mpsc::UnboundedReceiver<RTCEvent>;
pub enum RTCEvent { pub enum RTCEvent {
IceCandidate { IceCandidate {
ice_candidate: IceCandidate, ice_candidate: IceCandidate,
target: SignalTarget, target: proto::SignalTarget,
}, },
ConnectionChange { ConnectionChange {
state: PeerConnectionState, state: PeerConnectionState,
target: SignalTarget, target: proto::SignalTarget,
}, },
DataChannel { DataChannel {
data_channel: DataChannel, data_channel: DataChannel,
target: SignalTarget, target: proto::SignalTarget,
}, },
// TODO (theomonnom): Move Offer to PCTransport // TODO (theomonnom): Move Offer to PCTransport
Offer { Offer {
offer: SessionDescription, offer: SessionDescription,
target: SignalTarget, target: proto::SignalTarget,
}, },
AddTrack { AddTrack {
rtp_receiver: RtpReceiver, rtp_receiver: RtpReceiver,
streams: Vec<MediaStream>, streams: Vec<MediaStream>,
target: SignalTarget, target: proto::SignalTarget,
}, },
Data { Data {
data: Vec<u8>, data: Vec<u8>,
@@ -50,13 +46,16 @@ pub enum RTCEvent {
/// Handlers used to forward events to a channel /// Handlers used to forward events to a channel
/// Every callback here is called on the signaling thread /// Every callback here is called on the signaling thread
fn on_connection_change(target: SignalTarget, emitter: RTCEmitter) -> OnConnectionChangeHandler { fn on_connection_change(
target: proto::SignalTarget,
emitter: RTCEmitter,
) -> OnConnectionChangeHandler {
Box::new(move |state| { Box::new(move |state| {
let _ = emitter.send(RTCEvent::ConnectionChange { state, target }); let _ = emitter.send(RTCEvent::ConnectionChange { state, target });
}) })
} }
fn on_ice_candidate(target: SignalTarget, emitter: RTCEmitter) -> OnIceCandidateHandler { fn on_ice_candidate(target: proto::SignalTarget, emitter: RTCEmitter) -> OnIceCandidateHandler {
Box::new(move |ice_candidate| { Box::new(move |ice_candidate| {
let _ = emitter.send(RTCEvent::IceCandidate { let _ = emitter.send(RTCEvent::IceCandidate {
ice_candidate, ice_candidate,
@@ -65,7 +64,7 @@ fn on_ice_candidate(target: SignalTarget, emitter: RTCEmitter) -> OnIceCandidate
}) })
} }
fn on_offer(target: SignalTarget, emitter: RTCEmitter) -> OnOfferHandler { fn on_offer(target: proto::SignalTarget, emitter: RTCEmitter) -> OnOfferHandler {
Box::new(move |offer| { Box::new(move |offer| {
let _ = emitter.send(RTCEvent::Offer { offer, target }); let _ = emitter.send(RTCEvent::Offer { offer, target });
@@ -73,7 +72,7 @@ fn on_offer(target: SignalTarget, emitter: RTCEmitter) -> OnOfferHandler {
}) })
} }
fn on_data_channel(target: SignalTarget, emitter: RTCEmitter) -> OnDataChannelHandler { fn on_data_channel(target: proto::SignalTarget, emitter: RTCEmitter) -> OnDataChannelHandler {
Box::new(move |mut data_channel| { Box::new(move |mut data_channel| {
data_channel.on_message(on_message(emitter.clone())); data_channel.on_message(on_message(emitter.clone()));
@@ -84,7 +83,7 @@ fn on_data_channel(target: SignalTarget, emitter: RTCEmitter) -> OnDataChannelHa
}) })
} }
fn on_add_track(target: SignalTarget, emitter: RTCEmitter) -> OnAddTrackHandler { fn on_add_track(target: proto::SignalTarget, emitter: RTCEmitter) -> OnAddTrackHandler {
Box::new(move |rtp_receiver, streams| { Box::new(move |rtp_receiver, streams| {
let _ = emitter.send(RTCEvent::AddTrack { let _ = emitter.send(RTCEvent::AddTrack {
rtp_receiver, rtp_receiver,
@@ -95,7 +94,7 @@ fn on_add_track(target: SignalTarget, emitter: RTCEmitter) -> OnAddTrackHandler
} }
fn on_ice_candidate_error( fn on_ice_candidate_error(
target: SignalTarget, target: proto::SignalTarget,
_emitter: RTCEmitter, _emitter: RTCEmitter,
) -> OnIceCandidateErrorHandler { ) -> OnIceCandidateErrorHandler {
Box::new(move |address, port, url, error_code, error_text| { Box::new(move |address, port, url, error_code, error_text| {
+108 -101
View File
@@ -1,38 +1,21 @@
use livekit_webrtc::media_stream::{MediaStream, MediaStreamTrackHandle}; use super::{rtc_events, EngineError, EngineResult, SimulateScenario};
use livekit_webrtc::rtp_receiver::RtpReceiver;
use parking_lot::Mutex;
use std::convert::TryInto;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::Arc;
use std::time::Duration;
use tokio::task::JoinHandle;
use tokio::sync::{mpsc, watch, Mutex as AsyncMutex};
use tokio::time::sleep;
use prost::Message;
use serde::{Deserialize, Serialize};
use tracing::{debug, error, trace, warn};
use crate::{proto, signal_client};
use livekit_webrtc::data_channel::{DataChannel, DataChannelInit, DataState};
use livekit_webrtc::jsep::{IceCandidate, SessionDescription};
use livekit_webrtc::peer_connection::{
IceConnectionState, PeerConnectionState, RTCOfferAnswerOptions,
};
use livekit_webrtc::peer_connection_factory::RTCConfiguration;
use crate::proto::data_packet::Value;
use crate::proto::{
data_packet, signal_request, signal_response, CandidateProtocol, DataPacket, DisconnectReason,
JoinResponse, SignalTarget, TrickleRequest,
};
use crate::rtc_engine::lk_runtime::LKRuntime; use crate::rtc_engine::lk_runtime::LKRuntime;
use crate::rtc_engine::pc_transport::PCTransport; use crate::rtc_engine::pc_transport::PCTransport;
use crate::rtc_engine::rtc_events::{RTCEvent, RTCEvents}; use crate::rtc_engine::rtc_events::{RTCEvent, RTCEvents};
use crate::signal_client::{SignalClient, SignalEvent, SignalEvents, SignalOptions}; use crate::signal_client::{SignalClient, SignalEvent, SignalEvents, SignalOptions};
use crate::{proto, signal_client};
use super::{rtc_events, EngineError, EngineResult, SimulateScenario}; use livekit_webrtc::prelude::*;
use parking_lot::Mutex;
use prost::Message;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::{mpsc, watch, Mutex as AsyncMutex};
use tokio::task::JoinHandle;
use tokio::time::sleep;
use tracing::{debug, error, trace, warn};
pub const MAX_ICE_CONNECT_TIMEOUT: Duration = Duration::from_secs(15); pub const MAX_ICE_CONNECT_TIMEOUT: Duration = Duration::from_secs(15);
pub const LOSSY_DC_LABEL: &str = "_lossy"; pub const LOSSY_DC_LABEL: &str = "_lossy";
@@ -65,7 +48,7 @@ pub enum SessionEvent {
// TODO(theomonnom): Move entirely the reconnection logic on mod.rs // TODO(theomonnom): Move entirely the reconnection logic on mod.rs
Close { Close {
source: String, source: String,
reason: DisconnectReason, reason: proto::DisconnectReason,
can_reconnect: bool, can_reconnect: bool,
full_reconnect: bool, full_reconnect: bool,
retry_now: bool, retry_now: bool,
@@ -110,7 +93,7 @@ pub struct SessionInfo {
pub url: String, pub url: String,
pub token: String, pub token: String,
pub options: SignalOptions, pub options: SignalOptions,
pub join_response: JoinResponse, pub join_response: proto::JoinResponse,
} }
/// Fields shared with rtc_task and signal_task /// Fields shared with rtc_task and signal_task
@@ -171,14 +154,14 @@ impl RTCSession {
lk_runtime lk_runtime
.pc_factory .pc_factory
.create_peer_connection(rtc_config.clone())?, .create_peer_connection(rtc_config.clone())?,
SignalTarget::Publisher, proto::SignalTarget::Publisher,
); );
let mut subscriber_pc = PCTransport::new( let mut subscriber_pc = PCTransport::new(
lk_runtime lk_runtime
.pc_factory .pc_factory
.create_peer_connection(rtc_config.clone())?, .create_peer_connection(rtc_config.clone())?,
SignalTarget::Subscriber, proto::SignalTarget::Subscriber,
); );
let mut lossy_dc = publisher_pc.peer_connection().create_data_channel( let mut lossy_dc = publisher_pc.peer_connection().create_data_channel(
@@ -257,8 +240,8 @@ impl RTCSession {
pub async fn publish_data( pub async fn publish_data(
&self, &self,
data: &DataPacket, data: &proto::DataPacket,
kind: data_packet::Kind, kind: proto::data_packet::Kind,
) -> Result<(), EngineError> { ) -> Result<(), EngineError> {
self.inner.publish_data(data, kind).await self.inner.publish_data(data, kind).await
} }
@@ -301,7 +284,7 @@ impl RTCSession {
&self.inner.signal_client &self.inner.signal_client
} }
pub fn data_channel(&self, kind: data_packet::Kind) -> &DataChannel { pub fn data_channel(&self, kind: proto::data_packet::Kind) -> &DataChannel {
&self.inner.data_channel(kind) &self.inner.data_channel(kind)
} }
} }
@@ -347,7 +330,13 @@ impl SessionInner {
} }
} }
SignalEvent::Close => { SignalEvent::Close => {
self.on_session_disconnected("SignalClient closed", DisconnectReason::UnknownReason, true, false, false); self.on_session_disconnected(
"SignalClient closed",
proto::DisconnectReason::UnknownReason,
true,
false,
false
);
} }
} }
} else { } else {
@@ -362,9 +351,9 @@ impl SessionInner {
} }
} }
async fn on_signal_event(&self, event: signal_response::Message) -> EngineResult<()> { async fn on_signal_event(&self, event: proto::signal_response::Message) -> EngineResult<()> {
match event { match event {
signal_response::Message::Answer(answer) => { proto::signal_response::Message::Answer(answer) => {
trace!("received publisher answer: {:?}", answer); trace!("received publisher answer: {:?}", answer);
let answer = SessionDescription::from(answer.r#type.parse().unwrap(), &answer.sdp)?; let answer = SessionDescription::from(answer.r#type.parse().unwrap(), &answer.sdp)?;
self.publisher_pc self.publisher_pc
@@ -373,7 +362,7 @@ impl SessionInner {
.set_remote_description(answer) .set_remote_description(answer)
.await?; .await?;
} }
signal_response::Message::Offer(offer) => { proto::signal_response::Message::Offer(offer) => {
trace!("received subscriber offer: {:?}", offer); trace!("received subscriber offer: {:?}", offer);
let offer = SessionDescription::from(offer.r#type.parse().unwrap(), &offer.sdp)?; let offer = SessionDescription::from(offer.r#type.parse().unwrap(), &offer.sdp)?;
let answer = self let answer = self
@@ -384,14 +373,16 @@ impl SessionInner {
.await?; .await?;
self.signal_client self.signal_client
.send(signal_request::Message::Answer(proto::SessionDescription { .send(proto::signal_request::Message::Answer(
r#type: "answer".to_string(), proto::SessionDescription {
sdp: answer.to_string(), r#type: "answer".to_string(),
})) sdp: answer.to_string(),
},
))
.await; .await;
} }
signal_response::Message::Trickle(trickle) => { proto::signal_response::Message::Trickle(trickle) => {
let target = SignalTarget::from_i32(trickle.target).unwrap(); let target = proto::SignalTarget::from_i32(trickle.target).unwrap();
let ice_candidate = { let ice_candidate = {
let json = serde_json::from_str::<IceCandidateJSON>(&trickle.candidate_init)?; let json = serde_json::from_str::<IceCandidateJSON>(&trickle.candidate_init)?;
IceCandidate::from(&json.sdpMid, json.sdpMLineIndex, &json.candidate)? IceCandidate::from(&json.sdpMid, json.sdpMLineIndex, &json.candidate)?
@@ -399,7 +390,7 @@ impl SessionInner {
trace!("received ice_candidate {:?} {:?}", target, ice_candidate); trace!("received ice_candidate {:?} {:?}", target, ice_candidate);
if target == SignalTarget::Publisher { if target == proto::SignalTarget::Publisher {
self.publisher_pc self.publisher_pc
.lock() .lock()
.await .await
@@ -413,7 +404,7 @@ impl SessionInner {
.await?; .await?;
} }
} }
signal_response::Message::Leave(leave) => { proto::signal_response::Message::Leave(leave) => {
self.on_session_disconnected( self.on_session_disconnected(
"received leave", "received leave",
leave.reason(), leave.reason(),
@@ -422,17 +413,17 @@ impl SessionInner {
true, true,
); );
} }
signal_response::Message::Update(update) => { proto::signal_response::Message::Update(update) => {
let _ = self.emitter.send(SessionEvent::ParticipantUpdate { let _ = self.emitter.send(SessionEvent::ParticipantUpdate {
updates: update.participants, updates: update.participants,
}); });
} }
signal_response::Message::SpeakersChanged(speaker) => { proto::signal_response::Message::SpeakersChanged(speaker) => {
let _ = self.emitter.send(SessionEvent::SpeakersChanged { let _ = self.emitter.send(SessionEvent::SpeakersChanged {
speakers: speaker.speakers, speakers: speaker.speakers,
}); });
} }
signal_response::Message::ConnectionQuality(quality) => { proto::signal_response::Message::ConnectionQuality(quality) => {
let _ = self.emitter.send(SessionEvent::ConnectionQuality { let _ = self.emitter.send(SessionEvent::ConnectionQuality {
updates: quality.updates, updates: quality.updates,
}); });
@@ -450,20 +441,22 @@ impl SessionInner {
target, target,
} => { } => {
self.signal_client self.signal_client
.send(signal_request::Message::Trickle(TrickleRequest { .send(proto::signal_request::Message::Trickle(
candidate_init: serde_json::to_string(&IceCandidateJSON { proto::TrickleRequest {
sdpMid: ice_candidate.sdp_mid(), candidate_init: serde_json::to_string(&IceCandidateJSON {
sdpMLineIndex: ice_candidate.sdp_mline_index(), sdpMid: ice_candidate.sdp_mid(),
candidate: ice_candidate.candidate(), sdpMLineIndex: ice_candidate.sdp_mline_index(),
})?, candidate: ice_candidate.candidate(),
target: target as i32, })?,
})) target: target as i32,
},
))
.await; .await;
} }
RTCEvent::ConnectionChange { state, target } => { RTCEvent::ConnectionChange { state, target } => {
trace!("connection change, {:?} {:?}", state, target); trace!("connection change, {:?} {:?}", state, target);
let is_primary = self.info.join_response.subscriber_primary let is_primary = self.info.join_response.subscriber_primary
&& target == SignalTarget::Subscriber; && target == proto::SignalTarget::Subscriber;
if is_primary && state == PeerConnectionState::Connected { if is_primary && state == PeerConnectionState::Connected {
let old_state = self let old_state = self
@@ -478,7 +471,7 @@ impl SessionInner {
self.on_session_disconnected( self.on_session_disconnected(
"pc_state failed", "pc_state failed",
DisconnectReason::UnknownReason, proto::DisconnectReason::UnknownReason,
true, true,
false, false,
false, false,
@@ -494,10 +487,12 @@ impl SessionInner {
RTCEvent::Offer { offer, target: _ } => { RTCEvent::Offer { offer, target: _ } => {
// Send the publisher offer to the server // Send the publisher offer to the server
self.signal_client self.signal_client
.send(signal_request::Message::Offer(proto::SessionDescription { .send(proto::signal_request::Message::Offer(
r#type: "offer".to_string(), proto::SessionDescription {
sdp: offer.to_string(), r#type: "offer".to_string(),
})) sdp: offer.to_string(),
},
))
.await; .await;
} }
RTCEvent::AddTrack { RTCEvent::AddTrack {
@@ -522,16 +517,16 @@ impl SessionInner {
))?; ))?;
} }
let data = DataPacket::decode(&*data)?; let data = proto::DataPacket::decode(&*data)?;
match data.value.unwrap() { match data.value.unwrap() {
Value::User(user) => { proto::data_packet::Value::User(user) => {
let _ = self.emitter.send(SessionEvent::Data { let _ = self.emitter.send(SessionEvent::Data {
participant_sid: user.participant_sid, participant_sid: user.participant_sid,
payload: user.payload, payload: user.payload,
kind: data_packet::Kind::from_i32(data.kind).unwrap(), kind: proto::data_packet::Kind::from_i32(data.kind).unwrap(),
}); });
} }
Value::Speaker(_) => {} proto::data_packet::Value::Speaker(_) => {}
} }
} }
} }
@@ -544,7 +539,7 @@ impl SessionInner {
fn on_session_disconnected( fn on_session_disconnected(
&self, &self,
source: &str, source: &str,
reason: DisconnectReason, reason: proto::DisconnectReason,
can_reconnect: bool, can_reconnect: bool,
retry_now: bool, retry_now: bool,
full_reconnect: bool, full_reconnect: bool,
@@ -574,52 +569,64 @@ impl SessionInner {
} }
SimulateScenario::Speaker => { SimulateScenario::Speaker => {
self.signal_client self.signal_client
.send(signal_request::Message::Simulate(proto::SimulateScenario { .send(proto::signal_request::Message::Simulate(
scenario: Some(proto::simulate_scenario::Scenario::SpeakerUpdate(3)), proto::SimulateScenario {
})) scenario: Some(proto::simulate_scenario::Scenario::SpeakerUpdate(3)),
},
))
.await; .await;
} }
SimulateScenario::NodeFailure => { SimulateScenario::NodeFailure => {
self.signal_client self.signal_client
.send(signal_request::Message::Simulate(proto::SimulateScenario { .send(proto::signal_request::Message::Simulate(
scenario: Some(proto::simulate_scenario::Scenario::NodeFailure(true)), proto::SimulateScenario {
})) scenario: Some(proto::simulate_scenario::Scenario::NodeFailure(true)),
},
))
.await; .await;
} }
SimulateScenario::ServerLeave => { SimulateScenario::ServerLeave => {
self.signal_client self.signal_client
.send(signal_request::Message::Simulate(proto::SimulateScenario { .send(proto::signal_request::Message::Simulate(
scenario: Some(proto::simulate_scenario::Scenario::ServerLeave(true)), proto::SimulateScenario {
})) scenario: Some(proto::simulate_scenario::Scenario::ServerLeave(true)),
},
))
.await; .await;
} }
SimulateScenario::Migration => { SimulateScenario::Migration => {
self.signal_client self.signal_client
.send(signal_request::Message::Simulate(proto::SimulateScenario { .send(proto::signal_request::Message::Simulate(
scenario: Some(proto::simulate_scenario::Scenario::Migration(true)), proto::SimulateScenario {
})) scenario: Some(proto::simulate_scenario::Scenario::Migration(true)),
},
))
.await; .await;
} }
SimulateScenario::ForceTcp => { SimulateScenario::ForceTcp => {
self.signal_client self.signal_client
.send(signal_request::Message::Simulate(proto::SimulateScenario { .send(proto::signal_request::Message::Simulate(
scenario: Some( proto::SimulateScenario {
proto::simulate_scenario::Scenario::SwitchCandidateProtocol( scenario: Some(
CandidateProtocol::Tcp as i32, proto::simulate_scenario::Scenario::SwitchCandidateProtocol(
proto::CandidateProtocol::Tcp as i32,
),
), ),
), },
})) ))
.await; .await;
} }
SimulateScenario::ForceTls => { SimulateScenario::ForceTls => {
self.signal_client self.signal_client
.send(signal_request::Message::Simulate(proto::SimulateScenario { .send(proto::signal_request::Message::Simulate(
scenario: Some( proto::SimulateScenario {
proto::simulate_scenario::Scenario::SwitchCandidateProtocol( scenario: Some(
CandidateProtocol::Tls as i32, proto::simulate_scenario::Scenario::SwitchCandidateProtocol(
proto::CandidateProtocol::Tls as i32,
),
), ),
), },
})) ))
.await; .await;
} }
} }
@@ -628,8 +635,8 @@ impl SessionInner {
#[tracing::instrument(skip(data))] #[tracing::instrument(skip(data))]
async fn publish_data( async fn publish_data(
&self, &self,
data: &DataPacket, data: &proto::DataPacket,
kind: data_packet::Kind, kind: proto::data_packet::Kind,
) -> Result<(), EngineError> { ) -> Result<(), EngineError> {
self.ensure_publisher_connected(kind).await?; self.ensure_publisher_connected(kind).await?;
self.data_channel(kind) self.data_channel(kind)
@@ -705,7 +712,7 @@ impl SessionInner {
/// Ensure the Publisher PC is connected, if not, start the negotiation /// Ensure the Publisher PC is connected, if not, start the negotiation
/// This is required when sending data to the server /// This is required when sending data to the server
async fn ensure_publisher_connected(&self, kind: data_packet::Kind) -> EngineResult<()> { async fn ensure_publisher_connected(&self, kind: proto::data_packet::Kind) -> EngineResult<()> {
if !self.info.join_response.subscriber_primary { if !self.info.join_response.subscriber_primary {
return Ok(()); return Ok(());
} }
@@ -750,8 +757,8 @@ impl SessionInner {
} }
} }
fn data_channel(&self, kind: data_packet::Kind) -> &DataChannel { fn data_channel(&self, kind: proto::data_packet::Kind) -> &DataChannel {
if kind == data_packet::Kind::Reliable { if kind == proto::data_packet::Kind::Reliable {
&self.reliable_dc &self.reliable_dc
} else { } else {
&self.lossy_dc &self.lossy_dc
+8 -12
View File
@@ -1,13 +1,9 @@
use std::fmt::Debug; use crate::proto;
use std::time::Duration;
use crate::proto::{signal_request, signal_response, JoinResponse};
use crate::signal_client::signal_stream::SignalStream; use crate::signal_client::signal_stream::SignalStream;
use livekit_webrtc::peer_connection_factory::{ use livekit_webrtc::prelude::*;
ContinualGatheringPolicy, ICEServer, IceTransportsType, RTCConfiguration,
};
use parking_lot::RwLock; use parking_lot::RwLock;
use std::fmt::Debug;
use std::time::Duration;
use thiserror::Error; use thiserror::Error;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use tokio_tungstenite::tungstenite::Error as WsError; use tokio_tungstenite::tungstenite::Error as WsError;
@@ -37,7 +33,7 @@ pub enum SignalError {
#[derive(Debug)] #[derive(Debug)]
pub enum SignalEvent { pub enum SignalEvent {
Open, Open,
Signal(signal_response::Message), Signal(proto::signal_response::Message),
Close, Close,
} }
@@ -98,7 +94,7 @@ impl SignalClient {
} }
#[instrument(level = Level::DEBUG)] #[instrument(level = Level::DEBUG)]
pub async fn send(&self, signal: signal_request::Message) { pub async fn send(&self, signal: proto::signal_request::Message) {
if let Some(stream) = self.stream.read().as_ref() { if let Some(stream) = self.stream.read().as_ref() {
if stream.send(signal).await.is_ok() { if stream.send(signal).await.is_ok() {
return; return;
@@ -118,8 +114,8 @@ impl SignalClient {
} }
} }
impl From<JoinResponse> for RTCConfiguration { impl From<proto::JoinResponse> for RTCConfiguration {
fn from(join_response: JoinResponse) -> Self { fn from(join_response: proto::JoinResponse) -> Self {
Self { Self {
ice_servers: { ice_servers: {
let mut servers = vec![]; let mut servers = vec![];
+6 -8
View File
@@ -1,19 +1,17 @@
use crate::proto;
use crate::signal_client::{SignalEmitter, SignalEvent, SignalOptions, SignalResult};
use futures_util::stream::{SplitSink, SplitStream}; use futures_util::stream::{SplitSink, SplitStream};
use futures_util::{SinkExt, StreamExt}; use futures_util::{SinkExt, StreamExt};
use prost::Message as ProstMessage; use prost::Message as ProstMessage;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tokio::sync::{mpsc, oneshot}; use tokio::sync::{mpsc, oneshot};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use tokio_tungstenite::tungstenite::protocol::frame::coding::CloseCode; use tokio_tungstenite::tungstenite::protocol::frame::coding::CloseCode;
use tokio_tungstenite::tungstenite::protocol::CloseFrame; use tokio_tungstenite::tungstenite::protocol::CloseFrame;
use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::tungstenite::Message;
use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream}; use tokio_tungstenite::{connect_async, MaybeTlsStream, WebSocketStream};
use tracing::{event, Level}; use tracing::{event, Level};
use crate::proto::{signal_request, SignalRequest, SignalResponse};
use crate::signal_client::{SignalEmitter, SignalEvent, SignalOptions, SignalResult};
pub const PROTOCOL_VERSION: u32 = 8; pub const PROTOCOL_VERSION: u32 = 8;
type WebSocket = WebSocketStream<MaybeTlsStream<TcpStream>>; type WebSocket = WebSocketStream<MaybeTlsStream<TcpStream>>;
@@ -21,7 +19,7 @@ type WebSocket = WebSocketStream<MaybeTlsStream<TcpStream>>;
#[derive(Debug)] #[derive(Debug)]
enum InternalMessage { enum InternalMessage {
Signal { Signal {
signal: signal_request::Message, signal: proto::signal_request::Message,
response_chn: oneshot::Sender<SignalResult<()>>, response_chn: oneshot::Sender<SignalResult<()>>,
}, },
Pong { Pong {
@@ -107,7 +105,7 @@ impl SignalStream {
/// Send a SignalRequest to the websocket /// Send a SignalRequest to the websocket
/// It also waits for the message to be sent /// It also waits for the message to be sent
pub async fn send(&self, signal: signal_request::Message) -> SignalResult<()> { pub async fn send(&self, signal: proto::signal_request::Message) -> SignalResult<()> {
let (send, recv) = oneshot::channel(); let (send, recv) = oneshot::channel();
let msg = InternalMessage::Signal { let msg = InternalMessage::Signal {
signal, signal,
@@ -133,7 +131,7 @@ impl SignalStream {
event!(Level::TRACE, "sending SignalRequest: {:?}", signal); event!(Level::TRACE, "sending SignalRequest: {:?}", signal);
let data = Message::Binary( let data = Message::Binary(
SignalRequest { proto::SignalRequest {
message: Some(signal), message: Some(signal),
} }
.encode_to_vec(), .encode_to_vec(),
@@ -178,7 +176,7 @@ impl SignalStream {
while let Some(msg) = ws_reader.next().await { while let Some(msg) = ws_reader.next().await {
match msg { match msg {
Ok(Message::Binary(data)) => { Ok(Message::Binary(data)) => {
let res = SignalResponse::decode(data.as_slice()) let res = proto::SignalResponse::decode(data.as_slice())
.expect("failed to decode SignalResponse"); .expect("failed to decode SignalResponse");
let msg = res.message.unwrap(); let msg = res.message.unwrap();