Added verbosity option, added participant_left event

This commit is contained in:
Jasper Hugo 2021-08-15 18:24:06 +07:00
parent 0c18a319e7
commit 56463c6100
7 changed files with 56 additions and 35 deletions

26
Cargo.lock generated
View File

@ -473,7 +473,7 @@ dependencies = [
[[package]] [[package]]
name = "gst-meet" name = "gst-meet"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cocoa", "cocoa",
@ -663,7 +663,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "lib-gst-meet" name = "lib-gst-meet"
version = "0.1.0" version = "0.2.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@ -751,15 +751,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "matchers"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
dependencies = [
"regex-automata",
]
[[package]] [[package]]
name = "matches" name = "matches"
version = "0.1.9" version = "0.1.9"
@ -1225,15 +1216,6 @@ dependencies = [
"regex-syntax", "regex-syntax",
] ]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax",
]
[[package]] [[package]]
name = "regex-syntax" name = "regex-syntax"
version = "0.6.25" version = "0.6.25"
@ -1651,14 +1633,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab69019741fca4d98be3c62d2b75254528b5432233fd8a4d2739fec20278de48" checksum = "ab69019741fca4d98be3c62d2b75254528b5432233fd8a4d2739fec20278de48"
dependencies = [ dependencies = [
"chrono", "chrono",
"lazy_static",
"matchers",
"parking_lot", "parking_lot",
"regex",
"sharded-slab", "sharded-slab",
"smallvec", "smallvec",
"thread_local", "thread_local",
"tracing",
"tracing-core", "tracing-core",
"tracing-log", "tracing-log",
] ]

View File

@ -57,14 +57,14 @@ gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
demuxer.audio_0 ! queue ! vorbisdec ! audioconvert ! audioresample ! opusenc name=audio" demuxer.audio_0 ! queue ! vorbisdec ! audioconvert ! audioresample ! opusenc name=audio"
``` ```
Stream the default macOS video & audio inputs to the conference, encoding as VP8 and Opus, display incoming video streams and play back incoming audio (a very basic, but completely native, Jitsi Meet conference!): Stream the default video & audio inputs to the conference, encoding as VP8 and Opus, composite incoming video streams and play back incoming audio (a very basic, but completely native, Jitsi Meet conference!):
``` ```
gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \ gst-meet --web-socket-url=wss://your.jitsi.domain/xmpp-websocket \
--xmpp-domain=your.jitsi.domain \ --xmpp-domain=your.jitsi.domain \
--room-name=roomname \ --room-name=roomname \
--send-pipeline="avfvideosrc ! queue ! videoconvert ! vp8enc buffer-size=1000 deadline=1 name=video --send-pipeline="autovideosrc ! queue ! videoconvert ! vp8enc buffer-size=1000 deadline=1 name=video
osxaudiosrc ! queue ! audioconvert ! audioresample ! opusenc name=audio" \ autoaudiosrc ! queue ! audioconvert ! audioresample ! opusenc name=audio" \
--recv-pipeline-participant-template="opusdec name=audio ! autoaudiosink --recv-pipeline-participant-template="opusdec name=audio ! autoaudiosink
vp8dec name=video ! videoconvert ! autovideosink" vp8dec name=video ! videoconvert ! autovideosink"
``` ```

View File

@ -18,7 +18,6 @@ tokio-stream = { version = "0.1", default-features = false }
tracing = { version = "0.1", default-features = false, features = ["attributes", "std"] } tracing = { version = "0.1", default-features = false, features = ["attributes", "std"] }
tracing-subscriber = { version = "0.2", default-features = false, features = [ tracing-subscriber = { version = "0.2", default-features = false, features = [
"chrono", "chrono",
"env-filter",
"fmt", "fmt",
"smallvec", "smallvec",
"parking_lot", "parking_lot",

View File

@ -38,6 +38,8 @@ struct Opt {
send_pipeline: Option<String>, send_pipeline: Option<String>,
#[structopt(long)] #[structopt(long)]
recv_pipeline_participant_template: Option<String>, recv_pipeline_participant_template: Option<String>,
#[structopt(short, long, parse(from_occurrences))]
verbose: u8,
} }
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
@ -70,10 +72,14 @@ fn main() {
} }
async fn main_inner() -> Result<()> { async fn main_inner() -> Result<()> {
init_tracing();
let opt = Opt::from_args(); let opt = Opt::from_args();
init_tracing(match opt.verbose {
0 => tracing::Level::INFO,
1 => tracing::Level::DEBUG,
_ => tracing::Level::TRACE,
});
glib::log_set_default_handler(glib::rust_log_handler); glib::log_set_default_handler(glib::rust_log_handler);
let main_loop = glib::MainLoop::new(None, false); let main_loop = glib::MainLoop::new(None, false);
gstreamer::init().unwrap(); gstreamer::init().unwrap();
@ -189,6 +195,15 @@ async fn main_inner() -> Result<()> {
}) })
}) })
.await; .await;
conference
.on_participant_left(move |participant| {
Box::pin(async move {
info!("Participant left: {:?}", participant);
Ok(())
})
})
.await;
conference conference
.set_pipeline_state(gstreamer::State::Playing) .set_pipeline_state(gstreamer::State::Playing)
@ -215,9 +230,9 @@ async fn main_inner() -> Result<()> {
Ok(()) Ok(())
} }
fn init_tracing() { fn init_tracing(level: tracing::Level) {
tracing_subscriber::fmt() tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) .with_max_level(level)
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE) .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE)
.with_target(false) .with_target(false)
.init(); .init();

View File

@ -104,6 +104,7 @@ pub(crate) struct JitsiConferenceInner {
+ Sync, + Sync,
>, >,
>, >,
on_participant_left: Option<Arc<dyn (Fn(Participant) -> Pin<Box<dyn Future<Output = Result<()>> + Send>>) + Send + Sync>>,
state: JitsiConferenceState, state: JitsiConferenceState,
connected_tx: Option<oneshot::Sender<()>>, connected_tx: Option<oneshot::Sender<()>>,
connected_rx: Option<oneshot::Receiver<()>>, connected_rx: Option<oneshot::Receiver<()>>,
@ -137,6 +138,7 @@ impl JitsiConference {
state: JitsiConferenceState::Discovering, state: JitsiConferenceState::Discovering,
participants: HashMap::new(), participants: HashMap::new(),
on_participant: None, on_participant: None,
on_participant_left: None,
jingle_session: None, jingle_session: None,
connected_tx: Some(tx), connected_tx: Some(tx),
connected_rx: Some(rx), connected_rx: Some(rx),
@ -316,6 +318,17 @@ impl JitsiConference {
} }
} }
} }
#[tracing::instrument(level = "trace", skip(f))]
pub async fn on_participant_left(
&self,
f: impl (Fn(Participant) -> Pin<Box<dyn Future<Output = Result<()>> + Send>>)
+ Send
+ Sync
+ 'static,
) {
self.inner.lock().await.on_participant_left = Some(Arc::new(f));
}
} }
#[async_trait] #[async_trait]
@ -560,6 +573,16 @@ impl StanzaFilter for JitsiConference {
} }
} }
} }
else if presence.type_ == presence::Type::Unavailable {
locked_inner.participants.remove(&from.resource.clone());
debug!("participant left: {:?}", jid);
if let Some(f) = &locked_inner.on_participant_left {
debug!("calling on_participant_left with old participant");
if let Err(e) = f(participant).await {
warn!("on_participant_left failed: {:?}", e);
}
}
}
} }
} }
} }

View File

@ -311,8 +311,8 @@ impl JingleSession {
} }
} }
ice_agent.connect_candidate_gathering_done(move |ice_agent, a| { ice_agent.connect_candidate_gathering_done(move |_agent, candidates| {
debug!("ICE candidate-gathering-done {}", a); debug!("ICE candidate-gathering-done {:?}", candidates);
}); });
debug!("gathering ICE candidates"); debug!("gathering ICE candidates");

View File

@ -5,6 +5,12 @@ mkShell {
pkg-config pkg-config
glib glib
gst_all_1.gstreamer gst_all_1.gstreamer
gst_all_1.gst-plugins-base
gst_all_1.gst-plugins-good
gst_all_1.gst-plugins-bad
libnice libnice
]; ] ++ (if stdenv.isDarwin then [
darwin.apple_sdk.frameworks.AppKit
darwin.apple_sdk.frameworks.Security
] else []);
} }