Crate opentalk_janus_client

source ·
Expand description

This crate wraps the Janus WebSocket asynchronous API to provide a more or less idiomatic Rust API.

For this the client internally resolves futures based on the incoming responses and their respective transaction identifier. This is hidden to provide an API where you can simply call a function and .await the response. Thus this creates needs to be run in a async/.await runtime. Currently we only support the tokio runtime.

§Examples

 let (sink, _) = mpsc::channel(1);
 let connection = lapin::Connection::connect("amqp://janus-backend:5672", lapin::ConnectionProperties::default()).await.unwrap();
 let channel = connection.create_channel().await.unwrap();
 let config = RabbitMqConfig::new_from_channel(channel, "janus-gateway".into(), "to-janus".into(), "from-janus".into(), "opentalk-signaling".into());
 let client = Client::new(config, ClientId(Arc::from("")), sink).await.unwrap();
 let session = client.create_session().await.unwrap();
 let echo_handle = session
     .attach_to_plugin(JanusPlugin::Echotest, None)
     .await
     .unwrap();

 let echo = echo_handle
     .send(outgoing::EchoPluginUnnamed {
             audio: Some(true),
             ..Default::default()
     })
     .await.unwrap();
 println!("Echo {:?}, JSEP: {:?}", &echo.0, &echo.1);

Furtermore you can wrap the API and build upon that similar to spreed

pub struct SubscriberClient(Handle);
impl SubscriberClient {
    /// Joins a Room
    pub async fn join_room(&self, candidate: String ) {
        let room_id: RoomId = 2.into();
        let feed_id: FeedId = 1.into();
        let request = VideoRoomPluginJoinSubscriber::new(room_id, feed_id);
        self.0.send(request).await;
    }
}

pub struct PublisherClient(Handle);
impl PublisherClient {
    /// Sends the candidate SDP string to Janus
    pub async fn send_candidates(&self, candidate: String ) {
        self.0.trickle(TrickleMessage::Candidate(TrickleCandidate{
            candidate: "candidate:..".to_owned(),
            sdp_m_line_index: 1
        })).await;
    }
}
tokio_test::block_on(async {
let (sink, _) = mpsc::channel(1);
let connection = lapin::Connection::connect("amqp://janus-backend:5672", lapin::ConnectionProperties::default()).await.unwrap();
let channel = connection.create_channel().await.unwrap();
let config = RabbitMqConfig::new_from_channel(channel, "janus-gateway".into(), "to-janus".into(), "from-janus".into(), "opentalk-signaling".into());
let client = opentalk_janus_client::Client::new(config, ClientId(Arc::from("")), sink).await.unwrap();
let session = client.create_session().await.unwrap();

let echo_handle = session
    .attach_to_plugin(JanusPlugin::VideoRoom, None)
    .await
    .unwrap();
let publisher = PublisherClient(echo_handle);

let echo_handle = session
    .attach_to_plugin(JanusPlugin::VideoRoom, None)
    .await
    .unwrap();
let subscriber = SubscriberClient(echo_handle);
});
}

§Features

Specific plugins are hidden behind feature flags. Supported Janus plugins can be enabled with the following cargo features

  • echotest for the EchoTest Janus plugin
  • videoroom for the VideoRoom Janus plugin

By default echotest and videoroom are enabled.

Re-exports§

Modules§

Macros§

  • Helper macro to compare a [Serialize] implementor with a JSON literal

Structs§