pryty_rustbrowser/
camera.rs1use dioxus::prelude::*;
2use wasm_bindgen::JsCast;
3use wasm_bindgen_futures::JsFuture;
4use web_sys::{MediaStream, MediaStreamConstraints};
5
6pub struct Camera {
7 pub start: Callback<()>,
8 pub stop: Callback<()>,
9 pub stream: Signal<Option<MediaStream>>,
10 pub active: Signal<bool>,
11}
12
13pub fn use_camera() -> Camera {
14 let mut stream = use_signal(|| None::<MediaStream>);
15 let mut active = use_signal(|| false);
16
17 let start = use_callback(move |_| {
18 let mut stream = stream.clone();
19 let mut active = active.clone();
20
21 spawn(async move {
22 let window = web_sys::window().unwrap();
23 let devices = window.navigator().media_devices().unwrap();
24 let constraints = MediaStreamConstraints::new();
25 constraints.set_video(&true.into());
26
27 let promise = devices.get_user_media_with_constraints(&constraints).unwrap();
28 let js_val = JsFuture::from(promise).await.unwrap();
29 let s: MediaStream = js_val.dyn_into().unwrap();
30
31 stream.set(Some(s));
32 active.set(true);
33 });
34 });
35
36 let stop = use_callback(move |_| {
37 if let Some(s) = stream.read().as_ref() {
38 let tracks = s.get_tracks();
39 for i in 0..tracks.length() {
40 let track = tracks.get(i);
41 let _ = js_sys::Reflect::get(&track, &"stop".into())
42 .ok()
43 .and_then(|f| f.dyn_into::<js_sys::Function>().ok())
44 .map(|f| f.call0(&track));
45 }
46 }
47 stream.set(None);
48 active.set(false);
49 });
50
51 Camera {
52 start,
53 stop,
54 stream,
55 active,
56 }
57}