servo_media_gstreamer/
device_monitor.rs

1use gst::prelude::*;
2use gst::DeviceMonitor as GstDeviceMonitor;
3use std::cell::RefCell;
4
5use servo_media_streams::device_monitor::{MediaDeviceInfo, MediaDeviceKind, MediaDeviceMonitor};
6
7pub struct GStreamerDeviceMonitor {
8    devices: RefCell<Option<Vec<MediaDeviceInfo>>>,
9}
10
11impl GStreamerDeviceMonitor {
12    pub fn new() -> Self {
13        Self {
14            devices: RefCell::new(None),
15        }
16    }
17
18    fn get_devices(&self) -> Result<Vec<MediaDeviceInfo>, ()> {
19        const AUDIO_SOURCE: &str = "Audio/Source";
20        const AUDIO_SINK: &str = "Audio/Sink";
21        const VIDEO_SOURCE: &str = "Video/Source";
22        let device_monitor = GstDeviceMonitor::new();
23        let audio_caps = gst_audio::AudioCapsBuilder::new().build();
24        device_monitor.add_filter(Some(AUDIO_SOURCE), Some(&audio_caps));
25        device_monitor.add_filter(Some(AUDIO_SINK), Some(&audio_caps));
26        let video_caps = gst_video::VideoCapsBuilder::new().build();
27        device_monitor.add_filter(Some(VIDEO_SOURCE), Some(&video_caps));
28        let devices = device_monitor
29            .devices()
30            .iter()
31            .filter_map(|device| {
32                let display_name = device.display_name().as_str().to_owned();
33                Some(MediaDeviceInfo {
34                    device_id: display_name.clone(),
35                    kind: match device.device_class().as_str() {
36                        AUDIO_SOURCE => MediaDeviceKind::AudioInput,
37                        AUDIO_SINK => MediaDeviceKind::AudioOutput,
38                        VIDEO_SOURCE => MediaDeviceKind::VideoInput,
39                        _ => return None,
40                    },
41                    label: display_name,
42                })
43            })
44            .collect();
45        Ok(devices)
46    }
47}
48
49impl MediaDeviceMonitor for GStreamerDeviceMonitor {
50    fn enumerate_devices(&self) -> Result<Vec<MediaDeviceInfo>, ()> {
51        {
52            if let Some(ref devices) = *self.devices.borrow() {
53                return Ok(devices.clone());
54            }
55        }
56        let devices = self.get_devices()?;
57        *self.devices.borrow_mut() = Some(devices.clone());
58        Ok(devices)
59    }
60}