Skip to content

Commit 2468bd1

Browse files
committed
Refactor segment start time handling in recording
1 parent a83740c commit 2468bd1

2 files changed

Lines changed: 29 additions & 11 deletions

File tree

crates/recording/src/studio_recording.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,12 @@ impl Message<Resume> for Actor {
212212
.create_next(cursors, next_cursor_id)
213213
.await?;
214214

215+
let new_segment_start_time = current_time_f64();
216+
215217
Some(ActorState::Recording {
216218
pipeline,
217-
// pipeline_done_rx,
218219
index: next_index,
219-
segment_start_time: current_time_f64(),
220+
segment_start_time: new_segment_start_time,
220221
segment_start_instant: Instant::now(),
221222
})
222223
}
@@ -575,8 +576,6 @@ async fn spawn_studio_recording_actor(
575576
let segments_dir = ensure_dir(&content_dir.join("segments"))?;
576577
let cursors_dir = ensure_dir(&content_dir.join("cursors"))?;
577578

578-
let start_time = Timestamps::now();
579-
580579
let (completion_tx, completion_rx) =
581580
watch::channel::<Option<Result<(), PipelineDoneError>>>(None);
582581

@@ -596,7 +595,6 @@ async fn spawn_studio_recording_actor(
596595
custom_cursor_capture,
597596
fragmented,
598597
max_fps,
599-
start_time,
600598
completion_tx.clone(),
601599
);
602600

@@ -689,6 +687,26 @@ async fn stop_recording(
689687
let to_start_time =
690688
|timestamp: Timestamp| timestamp.signed_duration_since_secs(s.pipeline.start_time);
691689

690+
let mic_start_time = s
691+
.pipeline
692+
.microphone
693+
.as_ref()
694+
.map(|mic| to_start_time(mic.first_timestamp));
695+
696+
let camera_start_time = s.pipeline.camera.as_ref().map(|camera| {
697+
let raw_camera_start = to_start_time(camera.first_timestamp);
698+
if let Some(mic_start) = mic_start_time {
699+
let sync_offset = raw_camera_start - mic_start;
700+
if sync_offset.abs() > 0.030 {
701+
mic_start
702+
} else {
703+
raw_camera_start
704+
}
705+
} else {
706+
raw_camera_start
707+
}
708+
});
709+
692710
MultipleSegment {
693711
display: VideoMeta {
694712
path: make_relative(&s.pipeline.screen.path),
@@ -716,12 +734,12 @@ async fn stop_recording(
716734
);
717735
DEFAULT_FPS
718736
}),
719-
start_time: Some(to_start_time(camera.first_timestamp)),
737+
start_time: camera_start_time,
720738
device_id: s.camera_device_id.clone(),
721739
}),
722740
mic: s.pipeline.microphone.map(|mic| AudioMeta {
723741
path: make_relative(&mic.path),
724-
start_time: Some(to_start_time(mic.first_timestamp)),
742+
start_time: mic_start_time,
725743
device_id: s.mic_device_id.clone(),
726744
}),
727745
system_audio: s.pipeline.system_audio.map(|audio| AudioMeta {
@@ -798,7 +816,6 @@ struct SegmentPipelineFactory {
798816
custom_cursor_capture: bool,
799817
fragmented: bool,
800818
max_fps: u32,
801-
start_time: Timestamps,
802819
index: u32,
803820
completion_tx: watch::Sender<Option<Result<(), PipelineDoneError>>>,
804821
#[cfg(windows)]
@@ -814,7 +831,6 @@ impl SegmentPipelineFactory {
814831
custom_cursor_capture: bool,
815832
fragmented: bool,
816833
max_fps: u32,
817-
start_time: Timestamps,
818834
completion_tx: watch::Sender<Option<Result<(), PipelineDoneError>>>,
819835
) -> Self {
820836
Self {
@@ -824,7 +840,6 @@ impl SegmentPipelineFactory {
824840
custom_cursor_capture,
825841
fragmented,
826842
max_fps,
827-
start_time,
828843
index: 0,
829844
completion_tx,
830845
#[cfg(windows)]
@@ -837,7 +852,7 @@ impl SegmentPipelineFactory {
837852
cursors: Cursors,
838853
next_cursors_id: u32,
839854
) -> anyhow::Result<Pipeline> {
840-
let segment_start_time = self.start_time;
855+
let segment_start_time = Timestamps::now();
841856
let pipeline = create_segment_pipeline(
842857
&self.segments_dir,
843858
&self.cursors_dir,

packages/ui-solid/src/auto-imports.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ declare global {
6262
const IconCapZoomIn: typeof import('~icons/cap/zoom-in.jsx')['default']
6363
const IconCapZoomOut: typeof import('~icons/cap/zoom-out.jsx')['default']
6464
const IconHugeiconsEaseCurveControlPoints: typeof import('~icons/hugeicons/ease-curve-control-points.jsx')['default']
65+
const IconLucideAlertCircle: typeof import('~icons/lucide/alert-circle.jsx')['default']
6566
const IconLucideAlertTriangle: typeof import('~icons/lucide/alert-triangle.jsx')['default']
6667
const IconLucideArrowLeft: typeof import('~icons/lucide/arrow-left.jsx')['default']
6768
const IconLucideBell: typeof import('~icons/lucide/bell.jsx')['default']
@@ -79,6 +80,7 @@ declare global {
7980
const IconLucideImage: typeof import('~icons/lucide/image.jsx')['default']
8081
const IconLucideInfo: typeof import('~icons/lucide/info.jsx')['default']
8182
const IconLucideLayout: typeof import('~icons/lucide/layout.jsx')['default']
83+
const IconLucideLoader2: typeof import('~icons/lucide/loader2.jsx')['default']
8284
const IconLucideLoaderCircle: typeof import('~icons/lucide/loader-circle.jsx')['default']
8385
const IconLucideMaximize: typeof import('~icons/lucide/maximize.jsx')['default']
8486
const IconLucideMaximize2: typeof import('~icons/lucide/maximize2.jsx')['default']
@@ -88,6 +90,7 @@ declare global {
8890
const IconLucidePlus: typeof import('~icons/lucide/plus.jsx')['default']
8991
const IconLucideRatio: typeof import('~icons/lucide/ratio.jsx')['default']
9092
const IconLucideRectangleHorizontal: typeof import('~icons/lucide/rectangle-horizontal.jsx')['default']
93+
const IconLucideRefreshCw: typeof import('~icons/lucide/refresh-cw.jsx')['default']
9194
const IconLucideRotateCcw: typeof import('~icons/lucide/rotate-ccw.jsx')['default']
9295
const IconLucideRotateCw: typeof import('~icons/lucide/rotate-cw.jsx')['default']
9396
const IconLucideSearch: typeof import('~icons/lucide/search.jsx')['default']

0 commit comments

Comments
 (0)