Skip to content

fix(ffmpeg): backport upstream load, proxy, writeFile and Node path fixes - #72

Merged
Project516 merged 2 commits into
masterfrom
fix/upstream-batch-1
Oct 5, 2026
Merged

Project516 merged 2 commits into
masterfrom
fix/upstream-batch-1

Conversation

@Project516

Copy link
Copy Markdown
Owner

Backports from upstream ffmpegwasm/ffmpeg.wasm, fitted to this fork's code.

Changed

  • A second load() on a loaded instance no longer creates a second core and leaks the first. It waits for any load in flight, keeps the loaded core, and resolves false (the existing "first" meaning of IsFirst, so the return type is unchanged). A failed load clears the state so a retry works. Both worker.ts and worker-node-entry.mts. From #972.
  • When the wasm response is not WebAssembly (V8's "magic word" error), load() throws an error naming the wasmURL. Also from Fix double load(), name a non-wasm wasmURL, TS < 4.4 types, internal setTimeout ffmpegwasm/ffmpeg.wasm#972. The TS<4.4 typing change is skipped.
  • mount() checks Object.hasOwn on FS.filesystems, so __proto__ and constructor return false. From #958, that part only.
  • on and off are arrow-function class fields, so they work through a Proxy such as Vue's reactive() (upstream issue Using vite + vue: TypeError: Cannot read from private field ffmpegwasm/ffmpeg.wasm#687). writeFile(path, data, { transfer: false }) copies the array instead of transferring it; the default is unchanged. Docs and the load() doc comment updated. From #979, without its unload-after-trap part (PR fix(core): end the argv array with NULL #70 covers that area).
  • /* turbopackIgnore: true */ next to @vite-ignore on the dynamic core import. From #994. classWorkerURL resolution is untouched.
  • Node worker accepts filesystem paths (including Windows paths) and file: URLs for coreURL and wasmURL, converting paths with pathToFileURL. fetchFile(Blob) uses blob.arrayBuffer(), so it works where FileReader is undefined. Remainder of #956.

CHANGELOG has an Unreleased section for these.

Tests

Added to tests/ffmpeg-node.test.mjs: Blob read without FileReader, on/off through a Proxy, second load() keeps the core, mount("__proto__") and mount("constructor") return false, writeFile transfer vs transfer: false, path coreURL/wasmURL, and a non-wasm wasmURL error.

Verified locally

pnpm install --frozen-lockfile, pnpm build, pnpm lint, pnpm run test:node:helpers:args, and the Blob, Proxy and fetchFile cases of ffmpeg-node.test.mjs (they need no core).

Not run locally

  • The core-dependent cases in ffmpeg-node.test.mjs (second load, mount names, transfer, path URLs, non-wasm error), in st and mt. No built core on the Pi.
  • Browser suites.
  • The non-wasm error relies on matching V8's "magic word" message from the core's wasm instantiate; CI is the first real check of that.

Noticed, not fixed

  • Concurrent load() calls where the first fails: the waiting calls reject with the same error rather than retrying.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 58 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: eb3b4db2-71d2-4c57-817b-90bb071f6ea0
📥 Commits

Reviewing files that changed from the base of the PR and between 36bf577 and a768a9d.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • apps/website/docs/getting-started/usage.md
  • packages/ffmpeg/src/classes.ts
  • packages/ffmpeg/src/errors.ts
  • packages/ffmpeg/src/worker-node-entry.mts
  • packages/ffmpeg/src/worker.ts
  • packages/util/src/index.ts
  • tests/ffmpeg-node.test.mjs
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@project516-review-bot project516-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR backports several upstream fixes: (1) second load() waits for in-flight load and returns false without creating a duplicate core; failed loads clear state for retry. (2) load() errors name the wasmURL when the response isn't WebAssembly. (3) mount() uses Object.hasOwn to reject proto/constructor. (4) on/off are arrow functions so they work through Proxies. (5) writeFile adds {transfer:false} to copy instead of transfer. (6) Node worker accepts filesystem paths and file: URLs for coreURL/wasmURL via pathToFileURL. (7) fetchFile(Blob) uses blob.arrayBuffer() instead of FileReader. (8) Dynamic import carries turbopackIgnore. Tests cover all new behavior.


review-bot, model nvidia/nemotron-3-ultra-550b-a55b:free, verdict approve

@Project516
Project516 merged commit 87ec901 into master Oct 5, 2026
21 checks passed
@Project516
Project516 deleted the fix/upstream-batch-1 branch October 5, 2026 23:55
@Project516 Project516 mentioned this pull request Oct 6, 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