feat: ✨ rtc peer connection offer
This commit is contained in:
parent
7434d131c4
commit
0aa65f0f60
17 changed files with 389 additions and 59 deletions
|
@ -1,20 +1,20 @@
|
|||
use leptos::{
|
||||
IntoView, ev,
|
||||
html::{ElementChild, button},
|
||||
IntoView,
|
||||
attr::Value,
|
||||
ev,
|
||||
html::{ElementChild, button, form, input},
|
||||
logging::log,
|
||||
prelude::{OnAttribute, Read, Show, ShowProps, ToChildren},
|
||||
prelude::{BindAttribute, Get, OnAttribute, Read, Show, ShowProps, ToChildren, signal},
|
||||
server::LocalResource,
|
||||
task::spawn_local,
|
||||
};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{
|
||||
HtmlAudioElement, MediaStream, MediaStreamConstraints, MediaStreamTrack, MediaTrackConstraints,
|
||||
wasm_bindgen::{JsCast, JsValue},
|
||||
window,
|
||||
};
|
||||
use web_sys::HtmlAudioElement;
|
||||
|
||||
use crate::{media::audio, rtc::offer, signal::start_signalling};
|
||||
|
||||
pub fn app() -> impl IntoView {
|
||||
let audio_stream = LocalResource::new(|| media());
|
||||
let audio_stream = LocalResource::new(|| audio());
|
||||
let props = ShowProps::builder()
|
||||
.when(move || audio_stream.read().is_some())
|
||||
.children(ToChildren::to_children(move || {
|
||||
|
@ -38,47 +38,42 @@ pub fn app() -> impl IntoView {
|
|||
}))
|
||||
.fallback(|| button().child("Sad Button"))
|
||||
.build();
|
||||
Show(props)
|
||||
(Show(props), signalling(), rtc())
|
||||
}
|
||||
|
||||
async fn media() -> MediaStream {
|
||||
let media_devices = window().unwrap().navigator().media_devices().unwrap();
|
||||
let media_stream_constraints = MediaStreamConstraints::new();
|
||||
let media_track_constraints = MediaTrackConstraints::new();
|
||||
fn signalling() -> impl IntoView {
|
||||
let signalling_server_input_data = signal(String::new());
|
||||
let signalling_trigger = move || {
|
||||
spawn_local(start_signalling(
|
||||
"Zurna Dürüm".to_string(),
|
||||
signalling_server_input_data.0.get(),
|
||||
))
|
||||
};
|
||||
let signalling_server_input = form()
|
||||
.child(
|
||||
input()
|
||||
.bind(Value, signalling_server_input_data)
|
||||
.placeholder("0.0.0.0:4546")
|
||||
.r#type("text"),
|
||||
)
|
||||
.on(ev::submit, move |event| {
|
||||
event.prevent_default();
|
||||
signalling_trigger()
|
||||
});
|
||||
|
||||
media_stream_constraints.set_audio(&JsValue::TRUE);
|
||||
|
||||
media_track_constraints.set_echo_cancellation(&JsValue::FALSE);
|
||||
media_track_constraints.set_noise_suppression(&JsValue::FALSE);
|
||||
media_track_constraints.set_auto_gain_control(&JsValue::FALSE);
|
||||
|
||||
let media_stream_promise = media_devices
|
||||
.get_user_media_with_constraints(&media_stream_constraints)
|
||||
.unwrap();
|
||||
let media_stream = JsFuture::from(media_stream_promise)
|
||||
.await
|
||||
.unwrap()
|
||||
.dyn_into::<MediaStream>()
|
||||
.unwrap();
|
||||
let audio_stream_tracks = media_stream.get_audio_tracks();
|
||||
let audio_stream_tracks = audio_stream_tracks
|
||||
.iter()
|
||||
.map(|audio_track| audio_track.dyn_into::<MediaStreamTrack>().unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
log!(
|
||||
"{:#?}\n audio_stream_track_count = {}",
|
||||
audio_stream_tracks,
|
||||
audio_stream_tracks.len()
|
||||
);
|
||||
let audio_stream_track = audio_stream_tracks.first().unwrap();
|
||||
let audio_stream_track_apply_constraints_promise = audio_stream_track
|
||||
.apply_constraints_with_constraints(&media_track_constraints)
|
||||
.unwrap();
|
||||
JsFuture::from(audio_stream_track_apply_constraints_promise)
|
||||
.await
|
||||
.unwrap();
|
||||
let audio_stream = MediaStream::new().unwrap();
|
||||
log!("{:#?}", audio_stream_track.get_constraints());
|
||||
audio_stream.add_track(audio_stream_track);
|
||||
audio_stream
|
||||
let signalling_submit_button = button()
|
||||
.on(ev::click, move |_| signalling_trigger())
|
||||
.child("Signal");
|
||||
(signalling_server_input, signalling_submit_button)
|
||||
}
|
||||
|
||||
fn rtc() -> impl IntoView {
|
||||
let rtc_trigger = || {
|
||||
spawn_local(offer());
|
||||
};
|
||||
|
||||
let rtc_start_button = button()
|
||||
.on(ev::click, move |_| rtc_trigger())
|
||||
.child("RTC Offer");
|
||||
rtc_start_button
|
||||
}
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
pub mod gui;
|
||||
pub mod media;
|
||||
pub mod rtc;
|
||||
pub mod signal;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use leptos::mount::mount_to_body;
|
||||
use rust_communication::gui::app;
|
||||
use rust_communication_client::gui::app;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
|
|
49
client/src/media.rs
Normal file
49
client/src/media.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
use leptos::logging::log;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{
|
||||
MediaStream, MediaStreamConstraints, MediaStreamTrack, MediaTrackConstraints,
|
||||
wasm_bindgen::{JsCast, JsValue},
|
||||
window,
|
||||
};
|
||||
|
||||
pub async fn audio() -> MediaStream {
|
||||
let media_devices = window().unwrap().navigator().media_devices().unwrap();
|
||||
let media_stream_constraints = MediaStreamConstraints::new();
|
||||
let media_track_constraints = MediaTrackConstraints::new();
|
||||
|
||||
media_stream_constraints.set_audio(&JsValue::TRUE);
|
||||
|
||||
media_track_constraints.set_echo_cancellation(&JsValue::FALSE);
|
||||
media_track_constraints.set_noise_suppression(&JsValue::FALSE);
|
||||
media_track_constraints.set_auto_gain_control(&JsValue::FALSE);
|
||||
|
||||
let media_stream_promise = media_devices
|
||||
.get_user_media_with_constraints(&media_stream_constraints)
|
||||
.unwrap();
|
||||
let media_stream = JsFuture::from(media_stream_promise)
|
||||
.await
|
||||
.unwrap()
|
||||
.dyn_into::<MediaStream>()
|
||||
.unwrap();
|
||||
let audio_stream_tracks = media_stream.get_audio_tracks();
|
||||
let audio_stream_tracks = audio_stream_tracks
|
||||
.iter()
|
||||
.map(|audio_track| audio_track.dyn_into::<MediaStreamTrack>().unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
log!(
|
||||
"{:#?}\n audio_stream_track_count = {}",
|
||||
audio_stream_tracks,
|
||||
audio_stream_tracks.len()
|
||||
);
|
||||
let audio_stream_track = audio_stream_tracks.first().unwrap();
|
||||
let audio_stream_track_apply_constraints_promise = audio_stream_track
|
||||
.apply_constraints_with_constraints(&media_track_constraints)
|
||||
.unwrap();
|
||||
JsFuture::from(audio_stream_track_apply_constraints_promise)
|
||||
.await
|
||||
.unwrap();
|
||||
let audio_stream = MediaStream::new().unwrap();
|
||||
log!("{:#?}", audio_stream_track.get_constraints());
|
||||
audio_stream.add_track(audio_stream_track);
|
||||
audio_stream
|
||||
}
|
38
client/src/rtc.rs
Normal file
38
client/src/rtc.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use leptos::logging::log;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{
|
||||
RtcConfiguration, RtcIceServer, RtcPeerConnection, RtcSessionDescriptionInit,
|
||||
js_sys::{Array, Reflect},
|
||||
wasm_bindgen::{JsCast, JsValue},
|
||||
};
|
||||
|
||||
pub async fn offer() {
|
||||
let ice_server_addresses = vec![JsValue::from("stun:stun.l.google.com:19302")]
|
||||
.into_iter()
|
||||
.collect::<Array>();
|
||||
let ice_server = RtcIceServer::new();
|
||||
ice_server.set_urls(&JsValue::from(ice_server_addresses));
|
||||
let ice_servers = vec![ice_server].into_iter().collect::<Array>();
|
||||
let rtc_configuration = RtcConfiguration::new();
|
||||
rtc_configuration.set_ice_servers(&ice_servers);
|
||||
let peer_connection = RtcPeerConnection::new_with_configuration(&rtc_configuration).unwrap();
|
||||
let peer_connection_create_offer_promise = peer_connection.create_offer();
|
||||
let rtc_session_offer = JsFuture::from(peer_connection_create_offer_promise)
|
||||
.await
|
||||
.unwrap();
|
||||
log!("{:#?}", rtc_session_offer);
|
||||
let rtc_session_offer = rtc_session_offer
|
||||
.as_ref()
|
||||
.unchecked_ref::<RtcSessionDescriptionInit>();
|
||||
log!("{:#?}", rtc_session_offer);
|
||||
JsFuture::from(peer_connection.set_local_description(rtc_session_offer))
|
||||
.await
|
||||
.unwrap();
|
||||
let rtc_session_offer = Reflect::get(&rtc_session_offer, &JsValue::from_str("sdp"))
|
||||
.unwrap()
|
||||
.as_string()
|
||||
.unwrap();
|
||||
log!("{}", rtc_session_offer);
|
||||
}
|
||||
|
||||
pub async fn answer() {}
|
26
client/src/signal.rs
Normal file
26
client/src/signal.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use chrono::DateTime;
|
||||
use leptos::logging::log;
|
||||
use protocol::Signal;
|
||||
use serde_json::json;
|
||||
|
||||
pub async fn start_signalling(username: String, signal_address: String) {
|
||||
log!("Start Signalling");
|
||||
log!("{}\n{}", username, signal_address);
|
||||
let request_client = reqwest::Client::new();
|
||||
let signal = Signal {
|
||||
username,
|
||||
time: DateTime::default(),
|
||||
};
|
||||
let body = json!(signal);
|
||||
match request_client.post(signal_address).json(&body).send().await {
|
||||
Ok(signal_response) => log!("{:#?}", signal_response),
|
||||
Err(err_val) => {
|
||||
log!("Error: Signal Post | {}", err_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_offer() {}
|
||||
pub async fn receive_offer() {}
|
||||
pub async fn send_answer() {}
|
||||
pub async fn receive_answer() {}
|
Loading…
Add table
Add a link
Reference in a new issue