Skip to content

StreamTarget WritableStream.write() doesn’t fire during recording in fMP4; only fires on finalize() #175

@chemsabd

Description

@chemsabd

Summary

When using StreamTarget with MP4 fragmented fast start, WritableStream.write() never fires during recording. It only fires (in bursts at the configured chunkSize) when output.finalize() is called. This happens even though both video (CanvasSource) and audio (AudioSampleSource) are being fed continuously and output.start() resolves. This is running inside a Web Worker.

Reproduction

Repo: https://github.com/chemsabd/mediabunny-streamtarget-repro/

The repro generates its own deterministic A/V in a worker and logs every write/close call from the WritableStream sink.

Clone the repo and install dependencies.

Run the dev server.

Click Start (defaults shown below).

Let it run for enough time, then click Stop.

You’ll see the log lines for write/close (or lack thereof) in the page and console.

Actual behavior

During recording: no writable.write() calls (sometimes a single tiny initial write ~28 bytes when unchunked).

On Stop (after finalize()): a burst of write events appears at the configured chunkSize (e.g., 10 MiB), then close().

Image

Expected behavior

With fastStart: 'fragmented', StreamTarget should call writable.write() during recording—either when a fragment closes or (in chunked:true mode) when the internal buffer reaches chunkSize.

What I already tried

minimumFragmentDuration: 1, 0.5, 0.25, 0.1.

chunkSize: 10 MiB, 2 MiB.

Long runs (final files ~40–60 MB) → still no mid-session writes.

Unchunked StreamTarget (new StreamTarget(writable)) → only a tiny initial write; nothing more until finalize.

Verified both tracks are added before start, and packets flow:

Video frames added every 1/30 s via CanvasSource.add(...).

Audio packets are 20 ms (960 frames @ 48 kHz) with strictly increasing timestamps.

Environment

Context: Web Worker

Mediabunny version: pinned in repro’s package.json (same as my main app)

Browser/OS: can provide exact versions on request (tested on modern Chromium)

Questions

What exactly causes StreamTarget to invoke WritableStream.write() for fragmented MP4?
Does it strictly require a complete fragment across both tracks before emitting, and could anything defer emission until finalize()?

In chunked:true mode, should write() fire during recording once chunkSize is reached, or can StreamTarget buffer internally until finalize?

Any known Worker-specific caveats for StreamTarget/fMP4 that would cause this behavior?

Happy to adjust the repro or test a patch branch. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions