Skip to content

Fix desktop recordings losing their last segment on a slow finalize, and measure clips at the Stop click - #6

Merged
Johannes5 merged 1 commit into
mainfrom
fix/uploading-problems
Aug 19, 2026
Merged

Fix desktop recordings losing their last segment on a slow finalize, and measure clips at the Stop click#6
Johannes5 merged 1 commit into
mainfrom
fix/uploading-problems

Conversation

@Johannes5

Copy link
Copy Markdown
Collaborator

Follow-up to #4's "Not fixed" section: the segment-rollover truncation. It turned out to be two defects, both in the native stop path, and both visible in tray-timings.log.

1. A slow final finalize dropped the last segment (real data loss)

Every multi-segment recording whose final ScreenCaptureKit finalize took longer than SCK_FINALIZE_TIMEOUT (10 s) lost its last segment. recover_from_unusable_current_segment ran an instant playability check right after the timeout, saw no moov, popped the segment, quarantined the file and subtracted its time from duration_ms — so the clip uploaded "complete" minus its last 2–4.5 minutes, wall-clock and media agreed, and nothing flagged it.

Evidence: all three quarantine events in the local log happen exactly ~10.2–10.5 s after stop-begin, and all three quarantined files in lost-segments/ are fully playable today (124 s / 271 s / 166 s per ffprobe — the writer finished the moov after the rename):

recording lost tail
bqhlKZC61Tz8 124 s
JJu2NjjKSGHC 271 s
Q5N0xi0KgLm7 166 s

Fix: segment recovery gives a still-flushing writer up to SEGMENT_MOOV_GRACE (20 s) to land its moov before judging it, matching the budget parked rotation writers already get in resolve_deferred_finalizes. The single-segment path already did this (wait_for_mp4_moov 8 s before "still being finalized, retry"); the multi-segment path was the sibling that didn't.

2. duration_ms included the stop latency (the "17 s / 12 s shorter" false alarms)

duration_ms was computed after the finalize wait, the deferred writers and the segment merge, so every slow stop ran 10–17 s long and the pre-upload duration gate reported complete clips as truncated:

  • zzBTjeZJF53G: 165.7 s wall-clock, session-finalized ms:10752, media 164.4 s → "12 s shorter"
  • It89xpTan1cr: 18 s + pause + 147 s + 241 s = 406 s, session-finalized ms:16626, media 405.5 s → "17 s shorter"

Both clips are complete; their "Clip may be incomplete" editor-notes are false alarms. The clip is now measured at the Stop request; pause likewise starts at the request rather than after its own finalize wait, and lost-segment accounting uses the same request-time measurement.

Also

  • multi_segment is read before consolidation collapses the list, so session-finalized stops reporting every multi-segment recording as multiSegment:false; the event also carries durationMs / lostSegments / lostMs.
  • The webview's lost-event guard for clips:native-recording-finalized (was 15 s) now outlasts the new Rust ceiling — firing early is the -5814 interruption that corrupts the moov.

Verification

  • 194 Rust unit tests pass, including two new ones: a moov landing 700 ms into the grace is kept; one that never lands is dropped after the grace with the request-time duration credited as lost.
  • Desktop typecheck clean, 160 desktop tests, vite build OK.
  • Not verified on a real slow-finalize stop yet — the grace is a poll on the file, the same signal the single-segment path already relies on.

Not done here

Lost segments are still only loud in tray-timings.log and stderr. When a tail is genuinely unrecoverable the user should see it on the clip (the same editor-note mechanism #4 added for short clips); that needs lost_ms threaded through NativeFullscreenUploadResult.

…g last segment, and measure the clip at the Stop click

Every multi-segment recording whose final ScreenCaptureKit finalize took
longer than SCK_FINALIZE_TIMEOUT lost its last segment: the instant
playability check saw no moov, quarantined the file, and subtracted the
time from duration_ms — so the clip uploaded "complete" minus its last
2–4.5 minutes and nothing flagged it. All three quarantined files on this
machine are fully playable today; the writer finished the moov after the
rename. Segment recovery now gives a still-flushing writer up to
SEGMENT_MOOV_GRACE (20s) before judging it, matching the budget rotated
writers already get.

Separately, duration_ms was computed after the finalize wait, deferred
writers and the segment merge, so every slow stop ran 10–17s long and the
pre-upload duration gate reported complete clips as truncated (the 17s and
12s "may be incomplete" cases). The clip is now measured at the Stop
request; pause likewise starts at the request, not after its finalize wait.

multi_segment is read before consolidation collapses the list so the
session-finalized diag stops reporting every multi-segment recording as
single; the event also carries lost segment totals. The webview's
lost-event guard for the finalized event outlasts the new ceiling, since
firing early is the -5814 interruption that corrupts the moov.
@github-actions

Copy link
Copy Markdown

Visual recap — skipped

The visual recap job did not run for this pull request. This is informational only and does not block the PR.

Recap skipped for ee54ba3: PLAN_RECAP_TOKEN not configured.

@Johannes5
Johannes5 merged commit bc8be27 into main Aug 19, 2026
26 of 36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant