servo_media_gstreamer/
device_monitor.rs1use 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}