Skip to content

Commit 9e7a067

Browse files
Merge pull request #1475 from CapSoftware/cursor/audio-video-sync-perfection-2fc4
2 parents 4de3050 + 7231d88 commit 9e7a067

File tree

25 files changed

+1087
-87
lines changed

25 files changed

+1087
-87
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ pub async fn generate_export_preview(
225225
RenderVideoConstants::new(
226226
&recordings.segments,
227227
recording_meta.clone(),
228-
studio_meta.clone(),
228+
(**studio_meta).clone(),
229229
)
230230
.await
231231
.map_err(|e| format!("Failed to create render constants: {e}"))?,

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,7 +1456,7 @@ async fn get_video_metadata(path: PathBuf) -> Result<VideoRecordingMetadata, Str
14561456
return Err("Unable to get metadata on in-progress recording".to_string());
14571457
}
14581458

1459-
match meta {
1459+
match &**meta {
14601460
StudioRecordingMeta::SingleSegment { segment } => {
14611461
vec![recording_meta.path(&segment.display.path)]
14621462
}
@@ -1888,15 +1888,13 @@ impl RecordingMetaWithMetadata {
18881888
RecordingMetaInner::Instant(_) => RecordingMode::Instant,
18891889
},
18901890
status: match &inner.inner {
1891-
RecordingMetaInner::Studio(StudioRecordingMeta::MultipleSegments { inner }) => {
1892-
inner
1891+
RecordingMetaInner::Studio(meta) => match &**meta {
1892+
StudioRecordingMeta::MultipleSegments { inner } => inner
18931893
.status
18941894
.clone()
1895-
.unwrap_or(StudioRecordingStatus::Complete)
1896-
}
1897-
RecordingMetaInner::Studio(StudioRecordingMeta::SingleSegment { .. }) => {
1898-
StudioRecordingStatus::Complete
1899-
}
1895+
.unwrap_or(StudioRecordingStatus::Complete),
1896+
StudioRecordingMeta::SingleSegment { .. } => StudioRecordingStatus::Complete,
1897+
},
19001898
RecordingMetaInner::Instant(InstantRecordingMeta::InProgress { .. }) => {
19011899
StudioRecordingStatus::InProgress
19021900
}
@@ -3072,8 +3070,10 @@ async fn resume_uploads(app: AppHandle) -> Result<(), String> {
30723070
// Check if recording is still marked as in-progress and if so mark as failed
30733071
// This should only happen if the application crashes while recording
30743072
match &mut meta.inner {
3075-
RecordingMetaInner::Studio(StudioRecordingMeta::MultipleSegments { inner }) => {
3076-
if let Some(StudioRecordingStatus::InProgress) = &inner.status {
3073+
RecordingMetaInner::Studio(meta_box) => {
3074+
if let StudioRecordingMeta::MultipleSegments { inner } = &mut **meta_box
3075+
&& let Some(StudioRecordingStatus::InProgress) = &inner.status
3076+
{
30773077
inner.status = Some(StudioRecordingStatus::Failed {
30783078
error: "Recording crashed".to_string(),
30793079
});

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -543,13 +543,13 @@ pub async fn start_recording(
543543
pretty_name: project_name.clone(),
544544
inner: match inputs.mode {
545545
RecordingMode::Studio => {
546-
RecordingMetaInner::Studio(StudioRecordingMeta::MultipleSegments {
546+
RecordingMetaInner::Studio(Box::new(StudioRecordingMeta::MultipleSegments {
547547
inner: MultipleSegments {
548548
segments: Default::default(),
549549
cursors: Default::default(),
550550
status: Some(StudioRecordingStatus::InProgress),
551551
},
552-
})
552+
}))
553553
}
554554
RecordingMode::Instant => {
555555
RecordingMetaInner::Instant(InstantRecordingMeta::InProgress { recording: true })
@@ -1213,6 +1213,7 @@ pub async fn take_screenshot(
12131213
path: relative_path,
12141214
fps: 0,
12151215
start_time: Some(0.0),
1216+
device_id: None,
12161217
};
12171218

12181219
let segment = cap_project::SingleSegment {
@@ -1227,9 +1228,9 @@ pub async fn take_screenshot(
12271228
project_path: project_file_path.clone(),
12281229
pretty_name: project_name,
12291230
sharing: None,
1230-
inner: cap_project::RecordingMetaInner::Studio(
1231+
inner: cap_project::RecordingMetaInner::Studio(Box::new(
12311232
cap_project::StudioRecordingMeta::SingleSegment { segment },
1232-
),
1233+
)),
12331234
upload: None,
12341235
};
12351236

@@ -1331,7 +1332,7 @@ async fn handle_recording_end(
13311332
{
13321333
match &mut project_meta.inner {
13331334
RecordingMetaInner::Studio(meta) => {
1334-
if let StudioRecordingMeta::MultipleSegments { inner } = meta {
1335+
if let StudioRecordingMeta::MultipleSegments { inner } = &mut **meta {
13351336
inner.status = Some(StudioRecordingStatus::Failed { error });
13361337
}
13371338
}
@@ -1396,7 +1397,7 @@ async fn handle_recording_finish(
13961397

13971398
let (meta_inner, sharing) = match completed_recording {
13981399
CompletedRecording::Studio { recording, .. } => {
1399-
let meta_inner = RecordingMetaInner::Studio(recording.meta.clone());
1400+
let meta_inner = RecordingMetaInner::Studio(Box::new(recording.meta.clone()));
14001401

14011402
if let Ok(mut meta) = RecordingMeta::load_for_project(&recording_dir).map_err(|err| {
14021403
error!("Failed to load recording meta while saving finished recording: {err}")
@@ -1508,7 +1509,10 @@ async fn handle_recording_finish(
15081509

15091510
config.write(&recording_dir).map_err(|e| e.to_string())?;
15101511

1511-
(RecordingMetaInner::Studio(updated_studio_meta), None)
1512+
(
1513+
RecordingMetaInner::Studio(Box::new(updated_studio_meta)),
1514+
None,
1515+
)
15121516
}
15131517
CompletedRecording::Instant {
15141518
recording,
@@ -1910,7 +1914,7 @@ pub fn generate_zoom_segments_from_clicks(
19101914
project_path: recording.project_path.clone(),
19111915
pretty_name: String::new(),
19121916
sharing: None,
1913-
inner: RecordingMetaInner::Studio(recording.meta.clone()),
1917+
inner: RecordingMetaInner::Studio(Box::new(recording.meta.clone())),
19141918
upload: None,
19151919
};
19161920

@@ -1930,7 +1934,7 @@ pub fn generate_zoom_segments_for_project(
19301934
let mut all_clicks = Vec::new();
19311935
let mut all_moves = Vec::new();
19321936

1933-
match studio_meta {
1937+
match &**studio_meta {
19341938
StudioRecordingMeta::SingleSegment { segment } => {
19351939
if let Some(cursor_path) = &segment.cursor {
19361940
let mut events = CursorEvents::load_from_file(&recording_meta.path(cursor_path))

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ impl ScreenshotEditorInstances {
214214
path: relative_path.clone(),
215215
fps: 30,
216216
start_time: Some(0.0),
217+
device_id: None,
217218
};
218219
let segment = SingleSegment {
219220
display: video_meta.clone(),
@@ -227,7 +228,7 @@ impl ScreenshotEditorInstances {
227228
project_path: path.parent().unwrap().to_path_buf(),
228229
pretty_name: "Screenshot".to_string(),
229230
sharing: None,
230-
inner: RecordingMetaInner::Studio(studio_meta.clone()),
231+
inner: RecordingMetaInner::Studio(Box::new(studio_meta.clone())),
231232
upload: None,
232233
}
233234
};
@@ -283,7 +284,7 @@ impl ScreenshotEditorInstances {
283284
queue: (*queue).clone(),
284285
device: (*device).clone(),
285286
options,
286-
meta: studio_meta,
287+
meta: *studio_meta,
287288
recording_meta: recording_meta.clone(),
288289
background_textures: Arc::new(tokio::sync::RwLock::new(HashMap::new())),
289290
is_software_adapter,

apps/desktop/src/utils/tauri.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ export type AspectRatio = "wide" | "vertical" | "square" | "classic" | "tall"
374374
export type Audio = { duration: number; sample_rate: number; channels: number; start_time: number }
375375
export type AudioConfiguration = { mute: boolean; improve: boolean; micVolumeDb?: number; micStereoMode?: StereoMode; systemVolumeDb?: number }
376376
export type AudioInputLevelChange = number
377-
export type AudioMeta = { path: string; start_time?: number | null }
377+
export type AudioMeta = { path: string; start_time?: number | null; device_id?: string | null }
378378
export type AuthSecret = { api_key: string } | { token: string; expires: number }
379379
export type AuthStore = { secret: AuthSecret; user_id: string | null; plan: Plan | null; intercom_hash: string | null; organizations?: Organization[] }
380380
export type BackgroundConfiguration = { source: BackgroundSource; blur: number; padding: number; rounding: number; roundingType?: CornerStyle; inset: number; crop: Crop | null; shadow?: number; advancedShadow?: ShadowConfiguration | null; border?: BorderConfiguration | null }
@@ -520,7 +520,7 @@ export type UploadProgress = { progress: number }
520520
export type UploadProgressEvent = { video_id: string; uploaded: string; total: string }
521521
export type UploadResult = { Success: string } | "NotAuthenticated" | "PlanCheckFailed" | "UpgradeRequired"
522522
export type Video = { duration: number; width: number; height: number; fps: number; start_time: number }
523-
export type VideoMeta = { path: string; fps?: number; start_time?: number | null }
523+
export type VideoMeta = { path: string; fps?: number; start_time?: number | null; device_id?: string | null }
524524
export type VideoRecordingMetadata = { duration: number; size: number }
525525
export type VideoUploadInfo = { id: string; link: string; config: S3UploadMeta }
526526
export type WindowExclusion = { bundleIdentifier?: string | null; ownerName?: string | null; windowTitle?: string | null }

crates/audio/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,15 @@ ffmpeg = { workspace = true }
99
cpal = { workspace = true }
1010
tokio.workspace = true
1111
tracing = { workspace = true }
12+
serde = { workspace = true, features = ["derive"] }
13+
serde_json = { workspace = true }
1214
workspace-hack = { version = "0.1", path = "../workspace-hack" }
1315

1416
[target.'cfg(target_os = "macos")'.dependencies]
1517
cidre = { workspace = true }
1618

19+
[dev-dependencies]
20+
tempfile = "3"
21+
1722
[lints]
1823
workspace = true

0 commit comments

Comments
 (0)