aboutsummaryrefslogtreecommitdiff
path: root/client-native-export/src
diff options
context:
space:
mode:
Diffstat (limited to 'client-native-export/src')
-rw-r--r--client-native-export/src/main.rs155
1 files changed, 155 insertions, 0 deletions
diff --git a/client-native-export/src/main.rs b/client-native-export/src/main.rs
new file mode 100644
index 0000000..f4dffd6
--- /dev/null
+++ b/client-native-export/src/main.rs
@@ -0,0 +1,155 @@
+/*
+ This file is part of keks-meet (https://codeberg.org/metamuffin/keks-meet)
+ which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
+ Copyright (C) 2022 metamuffin <metamuffin@disroot.org>
+*/
+#![feature(box_syntax)]
+
+use clap::Parser;
+use client_native_lib::{
+ instance::Instance,
+ peer::{Peer, TransportChannel},
+ protocol::ProvideInfo,
+ webrtc::{
+ rtcp::payload_feedbacks::picture_loss_indication::PictureLossIndication,
+ rtp::{codecs::h264::H264Packet, packetizer::Depacketizer},
+ track::track_remote::TrackRemote,
+ },
+ Config, DynFut, EventHandler,
+};
+use log::{debug, error, info, warn};
+use std::{
+ io::{stdout, Write},
+ sync::Arc,
+ time::Duration,
+};
+
+fn main() {
+ env_logger::builder()
+ .filter_module("rift", log::LevelFilter::Info)
+ .filter_module("client_native_lib", log::LevelFilter::Info)
+ .parse_env("LOG")
+ .init();
+ tokio::runtime::Builder::new_multi_thread()
+ .enable_all()
+ .build()
+ .unwrap()
+ .block_on(run())
+}
+
+#[derive(Parser, Clone)]
+pub struct Args {
+ /// keks-meet server used for establishing p2p connection
+ #[clap(long, default_value = "wss://meet.metamuffin.org")]
+ signaling_uri: String,
+ /// username for the `identify` packet
+ #[clap(short, long, default_value = "guest")]
+ username: String,
+ /// pre-shared secret (aka. room name)
+ #[clap(short, long)]
+ secret: String,
+}
+
+async fn run() {
+ let args = Args::parse();
+
+ let inst = Instance::new(
+ Config {
+ secret: args.secret.clone(),
+ signaling_uri: args.signaling_uri.clone(),
+ username: args.username.clone(),
+ },
+ Arc::new(Handler {
+ _args: Arc::new(args.clone()),
+ }),
+ )
+ .await;
+
+ inst.spawn_ping().await;
+ inst.receive_loop().await;
+
+ tokio::signal::ctrl_c().await.unwrap();
+ error!("interrupt received, exiting");
+}
+
+#[derive(Clone)]
+struct Handler {
+ _args: Arc<Args>,
+}
+
+impl EventHandler for Handler {
+ fn peer_join(&self, _peer: Arc<Peer>) -> client_native_lib::DynFut<()> {
+ Box::pin(async move {})
+ }
+
+ fn peer_leave(&self, _peer: Arc<Peer>) -> client_native_lib::DynFut<()> {
+ Box::pin(async move {})
+ }
+
+ fn resource_added(
+ &self,
+ peer: Arc<Peer>,
+ info: client_native_lib::protocol::ProvideInfo,
+ ) -> DynFut<()> {
+ let id = info.id.clone();
+ Box::pin(async move {
+ if info.kind == "track" {
+ peer.request_resource(id).await;
+ }
+ })
+ }
+ fn resource_removed(&self, _peer: Arc<Peer>, _id: String) -> DynFut<()> {
+ Box::pin(async {})
+ }
+
+ fn resource_connected(
+ &self,
+ peer: Arc<Peer>,
+ _resource: &ProvideInfo,
+ channel: TransportChannel,
+ ) -> client_native_lib::DynFut<()> {
+ // let resource = resource.clone();
+ // let s = self.clone();
+ let peer = Arc::downgrade(&peer);
+ Box::pin(async move {
+ match channel {
+ TransportChannel::Track(track) => {
+ let media_ssrc = track.ssrc();
+ let peer = peer.clone();
+ tokio::spawn(async move {
+ loop {
+ tokio::time::sleep(Duration::from_secs(3)).await;
+ let peer = peer.upgrade().unwrap();
+ let r = peer
+ .peer_connection
+ .write_rtcp(&[Box::new(PictureLossIndication {
+ sender_ssrc: 0,
+ media_ssrc,
+ })])
+ .await;
+ if r.is_err() {
+ break;
+ }
+ debug!("trigger keyframe");
+ }
+ });
+
+ export(track).await.unwrap();
+ }
+ TransportChannel::DataChannel(_) => warn!("wrong type"),
+ }
+ })
+ }
+}
+
+async fn export(track: Arc<TrackRemote>) -> anyhow::Result<()> {
+ let mut cached_packet = H264Packet::default();
+ info!("depacketizing rtp to stdout");
+ loop {
+ let (packet, _) = track.read_rtp().await?;
+ if !packet.payload.is_empty() {
+ let raw_payload = cached_packet.depacketize(&packet.payload)?;
+ stdout().write_all(&raw_payload)?;
+ }
+ }
+}