Skip to content

Commit 7d21996

Browse files
committed
Refactor mic selection, retry, and Windows pause
1 parent ed0a52b commit 7d21996

3 files changed

Lines changed: 87 additions & 53 deletions

File tree

apps/desktop/src-tauri/src/lib.rs

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -442,73 +442,90 @@ impl App {
442442
#[specta::specta]
443443
#[instrument(skip(state))]
444444
async fn set_mic_input(state: MutableState<'_, App>, label: Option<String>) -> Result<(), String> {
445-
let (mic_feed, studio_handle, current_label) = {
446-
let app = state.read().await;
445+
let desired_label = label;
446+
447+
let (mic_feed, studio_handle, previous_label) = {
448+
let mut app = state.write().await;
449+
if desired_label == app.selected_mic_label {
450+
return Ok(());
451+
}
452+
447453
let handle = match app.current_recording() {
448454
Some(InProgressRecording::Studio { handle, .. }) => Some(handle.clone()),
449455
_ => None,
450456
};
451-
(app.mic_feed.clone(), handle, app.selected_mic_label.clone())
452-
};
453457

454-
if label == current_label {
455-
return Ok(());
456-
}
458+
let previous_label = app.selected_mic_label.clone();
459+
app.selected_mic_label = desired_label.clone();
457460

458-
if let Some(handle) = &studio_handle {
459-
handle.set_mic_feed(None).await.map_err(|e| e.to_string())?;
460-
}
461+
(app.mic_feed.clone(), handle, previous_label)
462+
};
461463

462-
let desired_label = label.clone();
464+
let apply_result = async {
465+
if let Some(handle) = &studio_handle {
466+
handle.set_mic_feed(None).await.map_err(|e| e.to_string())?;
467+
}
463468

464-
match desired_label.as_ref() {
465-
None => {
466-
mic_feed
467-
.ask(microphone::RemoveInput)
468-
.await
469-
.map_err(|e| e.to_string())?;
469+
match desired_label.as_ref() {
470+
None => {
471+
mic_feed
472+
.ask(microphone::RemoveInput)
473+
.await
474+
.map_err(|e| e.to_string())?;
475+
}
476+
Some(label) => {
477+
mic_feed
478+
.ask(feeds::microphone::SetInput {
479+
label: label.clone(),
480+
})
481+
.await
482+
.map_err(|e| e.to_string())?
483+
.await
484+
.map_err(|e| e.to_string())?;
485+
}
470486
}
471-
Some(label) => {
472-
mic_feed
473-
.ask(feeds::microphone::SetInput {
474-
label: label.clone(),
475-
})
487+
488+
if let Some(handle) = studio_handle
489+
&& desired_label.is_some()
490+
{
491+
let mic_lock = mic_feed
492+
.ask(microphone::Lock)
476493
.await
477-
.map_err(|e| e.to_string())?
494+
.map_err(|e| e.to_string())?;
495+
handle
496+
.set_mic_feed(Some(Arc::new(mic_lock)))
478497
.await
479498
.map_err(|e| e.to_string())?;
480499
}
481-
}
482500

483-
if let Some(handle) = studio_handle
484-
&& desired_label.is_some()
485-
{
486-
let mic_lock = mic_feed
487-
.ask(microphone::Lock)
488-
.await
489-
.map_err(|e| e.to_string())?;
490-
handle
491-
.set_mic_feed(Some(Arc::new(mic_lock)))
492-
.await
493-
.map_err(|e| e.to_string())?;
501+
Ok::<(), String>(())
494502
}
503+
.await;
495504

496-
{
497-
let mut app = state.write().await;
498-
app.selected_mic_label = desired_label;
499-
let cleared = app
500-
.disconnected_inputs
501-
.remove(&RecordingInputKind::Microphone);
505+
match apply_result {
506+
Ok(()) => {
507+
let mut app = state.write().await;
508+
let cleared = app
509+
.disconnected_inputs
510+
.remove(&RecordingInputKind::Microphone);
502511

503-
if cleared {
504-
let _ = RecordingEvent::InputRestored {
505-
input: RecordingInputKind::Microphone,
512+
if cleared {
513+
let _ = RecordingEvent::InputRestored {
514+
input: RecordingInputKind::Microphone,
515+
}
516+
.emit(&app.handle);
506517
}
507-
.emit(&app.handle);
518+
519+
Ok(())
520+
}
521+
Err(err) => {
522+
let mut app = state.write().await;
523+
if app.selected_mic_label == desired_label {
524+
app.selected_mic_label = previous_label;
525+
}
526+
Err(err)
508527
}
509528
}
510-
511-
Ok(())
512529
}
513530

514531
#[tauri::command]

apps/desktop/src-tauri/src/recording.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,12 +986,13 @@ pub async fn start_recording(
986986
);
987987
continue;
988988
}
989-
Err(err) if mic_restart_attempts == 0 && mic_actor_not_running(&err) => {
989+
Err(err) if mic_restart_attempts < 3 && mic_actor_not_running(&err) => {
990990
mic_restart_attempts += 1;
991991
state
992992
.restart_mic_feed()
993993
.await
994994
.map_err(|restart_err| anyhow!(restart_err))?;
995+
tokio::time::sleep(Duration::from_millis(250)).await;
995996
}
996997
Err(err) => return Err(err),
997998
}

crates/recording/src/output_pipeline/win.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88
path::PathBuf,
99
sync::{
1010
Arc, Mutex,
11-
atomic::AtomicBool,
11+
atomic::{AtomicBool, Ordering},
1212
mpsc::{RecvTimeoutError, SyncSender, TrySendError, sync_channel},
1313
},
1414
time::Duration,
@@ -122,7 +122,7 @@ impl Muxer for WindowsMuxer {
122122
output_path: PathBuf,
123123
video_config: Option<VideoInfo>,
124124
audio_config: Option<AudioInfo>,
125-
_pause_flag: Arc<AtomicBool>,
125+
pause_flag: Arc<AtomicBool>,
126126
tasks: &mut TaskPool,
127127
) -> anyhow::Result<Self>
128128
where
@@ -159,6 +159,7 @@ impl Muxer for WindowsMuxer {
159159

160160
{
161161
let output = output.clone();
162+
let pause_flag = pause_flag.clone();
162163

163164
tasks.spawn_thread("windows-encoder", move || {
164165
cap_mediafoundation_utils::thread_init();
@@ -323,7 +324,10 @@ impl Muxer for WindowsMuxer {
323324
return Ok(None);
324325
}
325326
Err(RecvTimeoutError::Timeout) => {
326-
if let Some(last_ts) = last_timestamp {
327+
if pause_flag.load(Ordering::Acquire) {
328+
last_timestamp = None;
329+
continue;
330+
} else if let Some(last_ts) = last_timestamp {
327331
let new_ts = last_ts.saturating_add(frame_interval);
328332
last_timestamp = Some(new_ts);
329333
frames_reused += 1;
@@ -422,6 +426,10 @@ impl Muxer for WindowsMuxer {
422426
}
423427
Ok(None) => break,
424428
Err(RecvTimeoutError::Timeout) => {
429+
if pause_flag.load(Ordering::Acquire) {
430+
last_timestamp = None;
431+
continue;
432+
}
425433
if let Some(last_ts) = last_timestamp {
426434
let new_ts = last_ts.saturating_add(frame_interval);
427435
last_timestamp = Some(new_ts);
@@ -629,7 +637,7 @@ impl Muxer for WindowsCameraMuxer {
629637
output_path: PathBuf,
630638
video_config: Option<VideoInfo>,
631639
audio_config: Option<AudioInfo>,
632-
_pause_flag: Arc<AtomicBool>,
640+
pause_flag: Arc<AtomicBool>,
633641
tasks: &mut TaskPool,
634642
) -> anyhow::Result<Self>
635643
where
@@ -686,6 +694,7 @@ impl Muxer for WindowsCameraMuxer {
686694

687695
{
688696
let output = output.clone();
697+
let pause_flag = pause_flag.clone();
689698
let encoder_preferences = config.encoder_preferences;
690699

691700
tasks.spawn_thread("windows-camera-encoder", move || {
@@ -837,7 +846,10 @@ impl Muxer for WindowsCameraMuxer {
837846
return Ok(None);
838847
}
839848
Err(RecvTimeoutError::Timeout) => {
840-
if let Some(last_ts) = last_timestamp {
849+
if pause_flag.load(Ordering::Acquire) {
850+
last_timestamp = None;
851+
continue;
852+
} else if let Some(last_ts) = last_timestamp {
841853
let new_ts = last_ts.saturating_add(frame_interval);
842854
last_timestamp = Some(new_ts);
843855
}
@@ -929,6 +941,10 @@ impl Muxer for WindowsCameraMuxer {
929941
}
930942
Ok(None) => break,
931943
Err(RecvTimeoutError::Timeout) => {
944+
if pause_flag.load(Ordering::Acquire) {
945+
last_timestamp = None;
946+
continue;
947+
}
932948
if let Some(last_ts) = last_timestamp {
933949
let new_ts = last_ts.saturating_add(frame_interval);
934950
last_timestamp = Some(new_ts);

0 commit comments

Comments
 (0)