Skip to content

fix: patch WebM Duration header on streamed recordings (stacks on #617)#1

Closed
neurot1cal wants to merge 1 commit into
Amanuel2x:fix/streaming-chunks-to-diskfrom
neurot1cal:fix/streaming-duration-patch
Closed

fix: patch WebM Duration header on streamed recordings (stacks on #617)#1
neurot1cal wants to merge 1 commit into
Amanuel2x:fix/streaming-chunks-to-diskfrom
neurot1cal:fix/streaming-duration-patch

Conversation

@neurot1cal

Copy link
Copy Markdown

Stacks on siddharthvaddem#617. Resolves the duration-metadata regression I flagged in my review (finding siddharthvaddem#2).

Problem

After siddharthvaddem#617, streamed .webm files save successfully but with no Duration EBML element. ffprobe reports duration=N/A and bit_rate=N/A. The editor opens the file but every control that needs a timeline breaks: seek bar reads 0:03 / 0:00, the timeline panel says "No Video Loaded", scrub/trim/zoom blocks have no time basis.

This was the user-felt failure mode for the long recordings siddharthvaddem#617 set out to save: pre-PR they got nothing; post-PR they get an uneditable file.

Fix

Patch the Duration header on disk in the main process after WriteStream.end() resolves. The renderer can no longer run fixWebmDuration(blob, durationMs) because the blob no longer exists, but the same library exposes a parser-level API (fixParsedWebmDuration(WebmFile, durationMs)) that operates on a Uint8Array — which works fine in Node.

Reads the whole file into a main-process Buffer, patches, writes back. Same memory footprint as the pre-PR renderer path, just on the side without V8's heap cap. Adds ~1–5 s to stop time depending on file size.

Verified locally

Best-effort by design

If fixParsedWebmDuration returns false (no Info section, or already valid) or any I/O fails, we log and return without throwing. The file is still playable — decoders walk frames sequentially regardless of the Duration field — so a patch failure is a degraded UX, not a broken recording. Surfacing the failure to the user is a follow-up.

Possible alternatives if size becomes an issue

I went with the simplest variant for the first cut. Happy to pivot if the wall-time on stop matters in practice.

The streaming-chunks-to-disk change in siddharthvaddem#617 skipped fixWebmDuration
because the renderer no longer holds the blob. As a result, streamed
recordings save with no Duration EBML element — the editor's seek bar,
timeline, and any scrub/trim that needs a known duration all break.
ffprobe reports duration=N/A for files saved by the previous behaviour.

Patch on disk in the main process after WriteStream.end() resolves,
using the existing @fix-webm-duration parser API to rewrite the
Info segment's Duration element. Reuses the existing dependency.

Best-effort: a failure logs and returns rather than blocking the
editor from opening — the file is still playable, just with broken
controls if patching fails.

Verified locally on a 90-second streamed recording:
  before: duration=N/A, bit_rate=N/A, editor reads 0:03/0:00
  after:  duration=90.862, bit_rate=10201352, editor reads 0:00/1:30,
          timeline populated, zoom blocks land on real timestamps

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@neurot1cal

Copy link
Copy Markdown
Author

Closing — folding this into a diff on the upstream PR (siddharthvaddem#617) instead of a separate PR, so everything stays on the original thread. Branch stays on my fork if it's easier to pull from.

@neurot1cal neurot1cal closed this May 24, 2026
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