17 releases (4 breaking)
new 0.4.0 | May 6, 2025 |
---|---|
0.3.5 | Apr 29, 2025 |
0.3.1 | Mar 27, 2025 |
0.3.0 | Feb 27, 2025 |
0.0.5 | Nov 18, 2024 |
#61 in Video
647 downloads per month
160KB
3.5K
SLoC
Rheomesh
Rheomesh is a WebRTC SFU library that provides a simple API for building real-time communication applications. This provides an SDK to help you build a WebRTC SFU server. Here is an example SFU server for video streaming.
Install
Add your Cargo.toml
like this:
[dependencies]
rheomesh = { version = "0" }
Usage
Create router and transports
First of all, please create a worker and router. Worker accomodates multiple routers. You only need to launch one worker per server. Router accommodates multiple transports and they can communicate with each other. That means transports belonging to the same Router can send/receive their media. Router is like a meeting room.
use rheomesh::worker::Worker;
use rheomesh::config::{WorkerConfig};
//...
async fn new() {
let worker = Worker::new(WorkerConfig::default()).await.unwrap();
let config = MediaConfig::default();
let mut w = worker.lock().await;
let router = w.new_router(config);
}
Next, please create publish and subscribe transports.
use rheomesh::config::WebRTCTransportConfig
async fn new() {
//...
let mut config = WebRTCTransportConfig::default();
config.configuration.ice_servers = vec![RTCIceServer {
urls: vec!["stun:stun.l.google.com:19302".to_owned()],
..Default::default()
}];
let publish_transport = router.lock().await.create_publish_transport(config.clone()).await;
let subscribe_transport = router.lock().await.create_subscribe_transport(config.clone()).await;
}
Handle publish events
Bind on_ice_candidate
callback
publish_transport
.on_ice_candidate(Box::new(move |candidate| {
let init = candidate.to_json().expect("failed to parse candidate");
// Send `init` message to client. The client have to call `addIceCandidate` method with this parameter.
}))
.await;
Please send init
to client. The corresponding client-side handler is here.
Handle RTCIceCandidateInit
On the other hand, you will receive RTCIceCandidateInit
message from client, here.
let _ = publish_transport
.add_ice_candidate(candidate)
.await
.expect("failed to add ICE candidate");
Handle offer
message
Then, server will receive offer
from client, the corresponding client-side handler is here.
let answer = publish_transport
.get_answer(offer)
.await
.expect("failed to connect publish_transport");
// Send `answer` message to client. The client have to call `setAnswer` method.
Please send answer
to client. The corresponding client-side handler is here.
Publish
Finally, please handle publish event with publisher_id
. You can obtain publisher_id
from publisher
object in client-side.
let publisher = publish_transport.publish(publisher_id).await;
Handle subscribe events
Bind on_ice_candidate
and on_negotiation_needed
callback
subscribe_transport
.on_ice_candidate(Box::new(move |candidate| {
let init = candidate.to_json().expect("failed to parse candidate");
// Send `init` message to client. The client have to call `addIceCandidate` method with this parameter.
}))
.await;
subscribe_transport
.on_negotiation_needed(Box::new(move |offer| {
// Send `offer` message to client. The client have to call `setOffer` method.
}))
Please send init
to client. The corresponding client-side handler is here.
Handle RTCIceCandidateInit
On the other hand, you will receive RTCIceCandidateInit
message from client, here.
let _ = subscribe_transport
.add_ice_candidate(candidate)
.await
.expect("failed to add ICE candidate");
Subscribe
Then, please call subscribe
method.
let (subscriber, offer) = subscribe_transport
.subscribe(track_id)
.await
.expect("failed to connect subscribe_transport");
// Send `offer` message to client. The client have to call `setOffer` method.
Please send offer
message to client. The corresponding client-side handler is here.
Handle answer
message
Finally, server will receive answer
from client, the corresponding client-side handler is here.
let _ = subscribe_transport
.set_answer(answer)
.await
.expect("failed to set answer");
Dependencies
~35–48MB
~1M SLoC