Skip to main content

pryty_rustbrowser/
camera.rs

1use 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}