# FFmpeg WebAssembly build record av-tools ships the published ESM assets from `@ffmpeg/core` and `@ffmpeg/core-mt` **0.12.10**. The browser wrapper is `@ffmpeg/ffmpeg` **0.12.15** and helpers are `@ffmpeg/util` **0.12.2**. All versions are exact, not ranges. ## Underlying build The matching ffmpeg.wasm upstream release is `v12.15` at `71aa99d37c02a7b4c435275ca9ef50e612f6efa1`. Its Dockerfile selects: - FFmpeg **n5.1.4** (libavcodec 59.37.100); - Emscripten SDK **3.1.40**; - production `-O3 -msimd128`; - pthread flags for the MT build and explicit thread disabling for ST. The build configuration embedded in both copied WASM files is: ```text --target-os=none --arch=x86_32 --enable-cross-compile --disable-asm --disable-stripping --disable-programs --disable-doc --disable-debug --disable-runtime-cpudetect --disable-autodetect --nm=emnm --ar=emar --ranlib=emranlib --cc=emcc --cxx=em++ --objcc=emcc --dep-cc=emcc --extra-cflags='-I/opt/include -O3 -msimd128' --extra-cxxflags='-I/opt/include -O3 -msimd128' --enable-gpl --enable-libx264 --enable-libx265 --enable-libvpx --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libopus --enable-zlib --enable-libwebp --enable-libfreetype --enable-libfribidi --enable-libass --enable-libzimg ``` The ST string also has `--disable-pthreads --disable-w32threads --disable-os2threads`; the MT build supplies Emscripten pthread flags instead. At runtime the application executes `-version`, `-buildconf`, `-formats`, `-codecs`, `-encoders` and `-filters` sequentially. Presets are enabled only when the active core reports every required muxer, encoder and filter. Build flags alone are not treated as a capability guarantee. ## External libraries The upstream build references x264 `4-cores`, x265 3.4, libvpx v1.13.1, LAME `master`, Ogg v1.3.4, Theora v1.1.1, Opus v1.3.1, Vorbis v1.3.3, zlib v1.2.11, libwebp v1.3.2, FreeType VER-2-10-4, FriBidi v1.0.9, HarfBuzz 5.2.0, libass 0.15.0 and zimg release-3.0.5. These resolve to x264 `33cac6b77d5b9259c552156013a817ab23119612`, x265 `2bb5520e9596f361bf0ed81b3b8da0d7fd999069` and LAME `2badea1974ae36cb8312afe99cff1e6b3b5decee`. All three commits predate the ffmpeg.wasm v12.15 release; the branch-based x264/LAME commits remain the respective branch tips. `SOURCE.md` records retrieval commands. ## Shipped files | Mode | File | Bytes | SHA-256 | | ---- | -------------------------- | -------: | ------------------------------------------------------------------ | | ST | `st/ffmpeg-core.js` | 111804 | `67a48f11645f85439f3fde4f2119042c16b374b910206b7a7a24f342e28dcae3` | | ST | `st/ffmpeg-core.wasm` | 32232419 | `9f57947a5bd530d8f00c5b3f2cb2a3492faa7e5d823315342d6a8656d0a6b7b7` | | MT | `mt/ffmpeg-core.js` | 128947 | `270a2e6ff945e173238610669a3f7132df5f9c52698a9bf708cf5c2ab6bda0de` | | MT | `mt/ffmpeg-core.wasm` | 32718323 | `be2c97605366b78f3f13e21b52e81a55a79e1f29c133b03a68ec187b1a2ec41a` | | MT | `mt/ffmpeg-core.worker.js` | 2115 | `f77898d631dc010b45c29c23cb4379c611a7d7b131bf591d08a656bb729a4ca3` | `npm run vendor:ffmpeg` copies these files from `node_modules` to `public/vendor/ffmpeg/0.12.10/`; `npm run vendor:verify` checks versions, sizes, paths and digests. Vite then copies them unchanged into `dist`. A normal production build performs no network download. ## Multithread Chromium guardrail The pinned multithread core can stall in Chromium when FFmpeg lets codecs use the browser's full reported logical-core count. This is tracked upstream in [ffmpeg.wasm issue 654](https://github.com/ffmpegwasm/ffmpeg.wasm/issues/654). av-tools keeps the pthread core but adds `-threads 2` as an input and output codec option for MT jobs. ST arguments remain unchanged. A regular browser test performs an actual MT H.264/AAC conversion; loading the core alone is not accepted as functional evidence. Every execution also has a watchdog: an explicit shorter plan timeout wins; otherwise the timeout is at least two minutes, scales to thirty times the expected media duration, and is capped at the displayed four-hour product limit. Timeout is still a failure, not a successful partial export. ## Long-session heap guardrail The pinned Emscripten core was observed to end a later heterogeneous browser workflow with a bare `Aborted()` even though the same command passed in a fresh core and all per-job virtual files had been removed. Its `tile` filter also aborted deterministically on a fourth consecutive contact sheet in local stress runs. av-tools therefore refreshes an idle core before its seventeenth media execution and before a fourth contact-sheet execution. Application queue state, sources and completed results remain outside the worker and are not discarded. A bare core abort also triggers recreation after cleanup so a manual or queued retry starts on a fresh instance. This is a conservative browser-memory guardrail, not a guarantee that sixteen large jobs or three large contact sheets fit in memory. Cancellation and failed filesystem-cleanup recovery continue to recreate the core immediately. ## Opus regression risk Pinned core 0.12.10 predates upstream ffmpeg.wasm fixes associated with stack size and Opus zero-byte/out-of-bounds failures (including upstream issues `#591` and `#775`). Therefore: - decoder/encoder listing is not enough to certify Opus; - real ST and MT fixture encodes must produce a non-empty, re-probeable output; - the Opus audio and VP9/Opus presets must remain disabled with a diagnostic if that smoke fails; - a core upgrade requires new checksums, capability snapshots, legal review and regression tests. This is a known pinned-core risk, not a claim that every Opus job fails. ## Licence consequence The core packages declare GPL-2.0-or-later and the actual build enables GPL and links external codecs. The wrapper/util are MIT. av-tools is GPL-3.0-or-later, and the distributed application must not be described as MIT-only. Publish the reviewed Corresponding Source and external notices with the binary release. See `LICENSE`, `LICENSES/`, `THIRD_PARTY_NOTICES.md` and `SOURCE.md`.