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