2025-04-02 03:27:59 +03:00
|
|
|
use leptos::{
|
2025-04-26 03:34:07 +03:00
|
|
|
IntoView,
|
|
|
|
html::{ElementChild, button, label},
|
|
|
|
logging::log,
|
2025-04-23 17:35:47 +03:00
|
|
|
prelude::{OnAttribute, Read, Show, ShowProps, ToChildren},
|
2025-04-02 03:27:59 +03:00
|
|
|
server::LocalResource,
|
|
|
|
};
|
2025-05-02 19:29:47 +03:00
|
|
|
use wasm_bindgen_futures::{JsFuture, spawn_local};
|
|
|
|
use web_sys::{HtmlAudioElement, MediaStreamTrack};
|
2025-04-11 04:58:16 +03:00
|
|
|
|
2025-04-30 18:22:37 +03:00
|
|
|
use crate::{
|
2025-05-02 19:29:47 +03:00
|
|
|
media,
|
2025-04-30 18:22:37 +03:00
|
|
|
signal::{send_auth, wait_until_communication_is_ready},
|
|
|
|
sleep,
|
|
|
|
webrtc::WebRTC,
|
|
|
|
};
|
2025-04-02 03:27:59 +03:00
|
|
|
|
|
|
|
pub fn app() -> impl IntoView {
|
2025-05-02 19:29:47 +03:00
|
|
|
let audio_stream = LocalResource::new(|| media::audio());
|
2025-04-28 05:18:36 +03:00
|
|
|
let wait_until_communication_is_ready =
|
|
|
|
LocalResource::new(|| wait_until_communication_is_ready());
|
2025-04-26 03:34:07 +03:00
|
|
|
|
|
|
|
let props = ShowProps::builder()
|
2025-04-28 05:18:36 +03:00
|
|
|
.when(move || {
|
|
|
|
audio_stream.read().is_some() && wait_until_communication_is_ready.read().is_some()
|
|
|
|
})
|
2025-04-02 03:27:59 +03:00
|
|
|
.children(ToChildren::to_children(move || {
|
2025-04-26 03:34:07 +03:00
|
|
|
let audio_stream = audio_stream.read();
|
2025-05-01 16:57:03 +03:00
|
|
|
let audio_stream = audio_stream.as_deref().unwrap().as_ref().unwrap().clone();
|
2025-04-26 03:34:07 +03:00
|
|
|
|
|
|
|
let webrtc = WebRTC::new(Some(audio_stream), None, None).unwrap();
|
2025-04-30 18:22:37 +03:00
|
|
|
let webrtc_state = webrtc.clone();
|
|
|
|
spawn_local(async move {
|
2025-05-02 19:29:47 +03:00
|
|
|
let mut webrtc_status = webrtc_state.get_status();
|
2025-04-30 18:22:37 +03:00
|
|
|
loop {
|
2025-05-02 19:29:47 +03:00
|
|
|
if webrtc_status != webrtc_state.get_status() {
|
|
|
|
webrtc_status = webrtc_state.get_status();
|
|
|
|
log!("{:#?}", webrtc_status);
|
|
|
|
}
|
2025-04-30 18:22:37 +03:00
|
|
|
sleep(1000).await;
|
|
|
|
}
|
|
|
|
});
|
2025-04-26 03:34:07 +03:00
|
|
|
|
|
|
|
let webrtc_offer = webrtc.clone();
|
|
|
|
let offer_button = button()
|
|
|
|
.on(leptos::ev::click, move |_| {
|
2025-05-02 19:29:47 +03:00
|
|
|
log!("Offer");
|
2025-04-30 18:22:37 +03:00
|
|
|
send_auth(&String::from("Offer")).unwrap();
|
2025-04-27 21:11:18 +03:00
|
|
|
let webrtc_offer = webrtc_offer.clone();
|
|
|
|
spawn_local(async move {
|
2025-04-30 18:22:37 +03:00
|
|
|
if let Err(err_val) = webrtc_offer.offer().await {
|
|
|
|
log!("Error: WebRTC Offer | {}", err_val);
|
2025-05-02 19:29:47 +03:00
|
|
|
return;
|
2025-04-30 18:22:37 +03:00
|
|
|
}
|
2025-04-27 21:11:18 +03:00
|
|
|
});
|
2025-04-02 03:27:59 +03:00
|
|
|
})
|
2025-04-26 03:34:07 +03:00
|
|
|
.child("Offer");
|
2025-04-25 04:54:41 +03:00
|
|
|
|
2025-04-26 03:34:07 +03:00
|
|
|
let webrtc_answer = webrtc.clone();
|
|
|
|
let answer_button = button()
|
|
|
|
.on(leptos::ev::click, move |_| {
|
2025-05-02 19:29:47 +03:00
|
|
|
log!("Answer");
|
2025-04-30 18:22:37 +03:00
|
|
|
send_auth(&String::from("Answer")).unwrap();
|
2025-04-29 22:58:24 +03:00
|
|
|
let webrtc_answer = webrtc_answer.clone();
|
|
|
|
spawn_local(async move {
|
2025-04-30 18:22:37 +03:00
|
|
|
if let Err(err_val) = webrtc_answer.answer().await {
|
|
|
|
log!("Error: WebRTC Answer | {}", err_val);
|
2025-05-02 19:29:47 +03:00
|
|
|
return;
|
2025-04-30 18:22:37 +03:00
|
|
|
}
|
2025-04-29 22:58:24 +03:00
|
|
|
});
|
2025-04-25 04:54:41 +03:00
|
|
|
})
|
2025-04-26 03:34:07 +03:00
|
|
|
.child("Answer");
|
|
|
|
|
2025-05-02 19:29:47 +03:00
|
|
|
let webrtc_audio = webrtc.clone();
|
|
|
|
let play_remote_audio_button = button()
|
|
|
|
.on(leptos::ev::click, move |_| {
|
|
|
|
let audio_element = HtmlAudioElement::new().unwrap();
|
|
|
|
|
|
|
|
let audio_streams = webrtc_audio.get_remote_streams().unwrap();
|
|
|
|
log!("Streams = {:#?}", audio_streams);
|
|
|
|
let audio_stream = audio_streams.get(0);
|
|
|
|
match audio_stream {
|
|
|
|
Some(audio_stream) => {
|
|
|
|
audio_element.set_src_object(Some(audio_stream));
|
|
|
|
let audio_tracks = audio_stream
|
|
|
|
.get_audio_tracks()
|
|
|
|
.iter()
|
|
|
|
.map(|audio_track| MediaStreamTrack::from(audio_track))
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
log!("How many tracks = {}", audio_tracks.len());
|
|
|
|
log!(
|
|
|
|
"Constraints = {:#?}",
|
|
|
|
audio_tracks.first().unwrap().get_constraints()
|
|
|
|
);
|
|
|
|
|
|
|
|
let audio_element_play_promise = audio_element.play().unwrap();
|
|
|
|
spawn_local(async move {
|
|
|
|
JsFuture::from(audio_element_play_promise).await.ok();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
None => todo!(),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.child("Play");
|
|
|
|
|
|
|
|
(offer_button, answer_button, play_remote_audio_button)
|
2025-04-25 04:54:41 +03:00
|
|
|
}))
|
2025-04-26 03:34:07 +03:00
|
|
|
.fallback(|| label().child("NOOOOOOOOOOOO"))
|
2025-04-25 04:54:41 +03:00
|
|
|
.build();
|
|
|
|
|
2025-04-26 03:34:07 +03:00
|
|
|
Show(props)
|
2025-04-02 03:27:59 +03:00
|
|
|
}
|