diff --git a/apps/desktop/src-tauri/src/recording.rs b/apps/desktop/src-tauri/src/recording.rs index bff295fd21..8db9417449 100644 --- a/apps/desktop/src-tauri/src/recording.rs +++ b/apps/desktop/src-tauri/src/recording.rs @@ -8,6 +8,8 @@ use cap_project::{ cursor::CursorEvents, }; use cap_recording::PipelineDoneError; +use cap_recording::feeds::camera::CameraFeedLock; +use cap_recording::feeds::microphone::MicrophoneFeedLock; use cap_recording::{ RecordingError, RecordingMode, feeds::{camera, microphone}, @@ -53,20 +55,24 @@ use crate::{ windows::{CapWindowId, ShowCapWindow}, }; +pub struct InProgressRecordingCommon { + pub target_name: String, + pub inputs: StartRecordingInputs, + pub recording_dir: PathBuf, +} + pub enum InProgressRecording { Instant { - target_name: String, handle: instant_recording::ActorHandle, progressive_upload: InstantMultipartUpload, video_upload_info: VideoUploadInfo, - inputs: StartRecordingInputs, - recording_dir: PathBuf, + common: InProgressRecordingCommon, + // camera isn't used as part of recording pipeline so we hold lock here + camera_feed: Option>, }, Studio { - target_name: String, handle: studio_recording::ActorHandle, - inputs: StartRecordingInputs, - recording_dir: PathBuf, + common: InProgressRecordingCommon, }, } @@ -80,8 +86,8 @@ impl InProgressRecording { pub fn inputs(&self) -> &StartRecordingInputs { match self { - Self::Instant { inputs, .. } => inputs, - Self::Studio { inputs, .. } => inputs, + Self::Instant { common, .. } => &common.inputs, + Self::Studio { common, .. } => &common.inputs, } } @@ -101,8 +107,8 @@ impl InProgressRecording { pub fn recording_dir(&self) -> &PathBuf { match self { - Self::Instant { recording_dir, .. } => recording_dir, - Self::Studio { recording_dir, .. } => recording_dir, + Self::Instant { common, .. } => &common.recording_dir, + Self::Studio { common, .. } => &common.recording_dir, } } @@ -112,21 +118,17 @@ impl InProgressRecording { handle, progressive_upload, video_upload_info, - target_name, + common, .. } => CompletedRecording::Instant { recording: handle.stop().await?, progressive_upload, video_upload_info, - target_name, + target_name: common.target_name, }, - Self::Studio { - handle, - target_name, - .. - } => CompletedRecording::Studio { + Self::Studio { handle, common, .. } => CompletedRecording::Studio { recording: handle.stop().await?, - target_name, + target_name: common.target_name, }, }) } @@ -449,6 +451,12 @@ pub async fn start_recording( .map_err(|e| format!("GetShareableContent: {e}"))? .ok_or_else(|| format!("GetShareableContent/NotAvailable"))?; + let common = InProgressRecordingCommon { + target_name, + inputs: inputs.clone(), + recording_dir: recording_dir.clone(), + }; + let actor = match inputs.mode { RecordingMode::Studio => { let mut builder = studio_recording::Actor::builder( @@ -481,12 +489,7 @@ pub async fn start_recording( e.to_string() })?; - InProgressRecording::Studio { - handle, - target_name, - inputs, - recording_dir: recording_dir.clone(), - } + InProgressRecording::Studio { handle, common } } RecordingMode::Instant => { let Some(video_upload_info) = video_upload_info.clone() else { @@ -526,9 +529,8 @@ pub async fn start_recording( handle, progressive_upload, video_upload_info, - target_name, - inputs, - recording_dir: recording_dir.clone(), + common, + camera_feed, } } }; diff --git a/crates/recording/src/instant_recording.rs b/crates/recording/src/instant_recording.rs index 0a1ddc57cc..400dd6a27d 100644 --- a/crates/recording/src/instant_recording.rs +++ b/crates/recording/src/instant_recording.rs @@ -1,7 +1,7 @@ use crate::{ RecordingBaseInputs, capture_pipeline::{MakeCapturePipeline, ScreenCaptureMethod, Stop, create_screen_capture}, - feeds::microphone::MicrophoneFeedLock, + feeds::{camera::CameraFeedLock, microphone::MicrophoneFeedLock}, output_pipeline::{self, OutputPipeline}, sources::screen_capture::{ScreenCaptureConfig, ScreenCaptureTarget}, }; diff --git a/crates/recording/src/sources/camera.rs b/crates/recording/src/sources/camera.rs index 3ef911f63b..48daae8e37 100644 --- a/crates/recording/src/sources/camera.rs +++ b/crates/recording/src/sources/camera.rs @@ -15,7 +15,7 @@ impl VideoSource for Camera { type Frame = FFmpegVideoFrame; async fn setup( - config: Self::Config, + feed_lock: Self::Config, mut video_tx: mpsc::Sender, _: &mut SetupCtx, ) -> anyhow::Result @@ -24,7 +24,7 @@ impl VideoSource for Camera { { let (tx, rx) = flume::bounded(8); - config + feed_lock .ask(camera::AddSender(tx)) .await .map_err(|e| anyhow!("Failed to add camera sender: {e}"))?; @@ -35,7 +35,7 @@ impl VideoSource for Camera { } }); - Ok(Self(config)) + Ok(Self(feed_lock)) } fn video_info(&self) -> VideoInfo { diff --git a/crates/recording/src/sources/microphone.rs b/crates/recording/src/sources/microphone.rs index 36a6fad636..752476661b 100644 --- a/crates/recording/src/sources/microphone.rs +++ b/crates/recording/src/sources/microphone.rs @@ -7,13 +7,13 @@ use cap_media_info::AudioInfo; use futures::{SinkExt, channel::mpsc}; use std::sync::Arc; -pub struct Microphone(AudioInfo); +pub struct Microphone(AudioInfo, Arc); impl AudioSource for Microphone { type Config = Arc; fn setup( - config: Self::Config, + feed_lock: Self::Config, mut audio_tx: mpsc::Sender, _: &mut crate::SetupCtx, ) -> impl Future> + 'static @@ -21,10 +21,10 @@ impl AudioSource for Microphone { Self: Sized, { async move { - let audio_info = config.audio_info(); + let audio_info = feed_lock.audio_info(); let (tx, rx) = flume::bounded(8); - config + feed_lock .ask(microphone::AddSender(tx)) .await .map_err(|e| anyhow!("Failed to add camera sender: {e}"))?; @@ -40,7 +40,7 @@ impl AudioSource for Microphone { } }); - Ok(Self(audio_info)) + Ok(Self(audio_info, feed_lock)) } }