use crate::{Error, ScreenInfo, frame::ScreenFrame, sys};
use std::sync::Arc;
use wgpu::{Device, Queue};
#[derive(Debug, Clone)]
pub struct StreamConfig {
pub target_fps: u32,
pub show_cursor: bool,
}
impl Default for StreamConfig {
fn default() -> Self {
Self {
target_fps: 60,
show_cursor: true,
}
}
}
pub struct ScreenStream {
inner: sys::ScreenStreamInner,
}
impl std::fmt::Debug for ScreenStream {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ScreenStream").finish_non_exhaustive()
}
}
impl ScreenStream {
#[cfg_attr(
target_os = "macos",
expect(
clippy::future_not_send,
reason = "the capturer's Objective-C objects are not Send; the caller drives this future"
)
)]
#[cfg_attr(
target_arch = "wasm32",
expect(
clippy::future_not_send,
reason = "wgpu's WebGPU device is not Send on wasm"
)
)]
pub async fn start(
display: &ScreenInfo,
device: Arc<Device>,
queue: Arc<Queue>,
config: &StreamConfig,
) -> Result<Self, Error> {
let inner = sys::ScreenStreamInner::new(display, device, queue, config).await?;
Ok(Self { inner })
}
#[allow(
clippy::future_not_send,
reason = "the Windows capture session is a thread-affine `*mut c_void`, so `ScreenStream` is deliberately not `Sync` and these futures cannot be `Send`."
)]
pub async fn next_frame(&self) -> Option<ScreenFrame> {
self.inner.next_frame().await
}
#[must_use]
#[allow(clippy::missing_const_for_fn)] pub fn try_next_frame(&self) -> Option<ScreenFrame> {
self.inner.try_next_frame()
}
#[must_use]
pub const fn dimensions(&self) -> (u32, u32) {
self.inner.dimensions()
}
}