These instructions are for AI assistants working in this project.
Always open @/openspec/AGENTS.md when the request:
- Mentions planning or proposals (words like proposal, spec, change, plan)
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
- Sounds ambiguous and you need the authoritative spec before coding
Use @/openspec/AGENTS.md to learn:
- How to create and apply change proposals
- Spec format and conventions
- Project structure and guidelines
Keep this managed block so 'openspec update' can refresh the instructions.
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
FFmpeg prebuilds - a modular build system for creating statically-linked FFmpeg binaries with codec dependencies. Supports macOS (ARM64, x64) and Linux (ARM64, x64).
# Full build for any platform
cd platforms/<os>-<arch>
./build.sh all # Or: make -j$(nproc) all
# Targets
make codecs # Build all codec libraries
make ffmpeg # Build FFmpeg (requires codecs)
make package # Create distribution package
make verify # Verify build (architecture check)
make preflight # Pre-build environment validation
make x264.stamp # Build specific codec
# Clean
make clean # Remove build directory
make distclean # Remove build + artifacts
# Lint & CI
mise run lint # All linters (actionlint, shellcheck, hadolint)
mise run act:validate # Dry-run workflows locallyPush to master → ci.yml → _build.yml (8 jobs) → Artifacts (30-day)
↓
bump-version.sh → push tag → release.yml → Download artifacts → Release + npm
| Workflow | Trigger | Purpose |
|---|---|---|
lint.yml |
PR to master | Land-blocking validation |
_build.yml |
workflow_call | Reusable build (4 platforms × 2 licenses) |
ci.yml |
Push to master | Continuous builds, stores artifacts |
release.yml |
Manual dispatch | Release existing tag, publish to npm |
Release flow:
- Run
./scripts/bump-version.sh patch(or minor/major) - Push:
git push origin master v0.7.0 - Actions → Release → Run workflow → Enter tag
v0.7.0
Version source of truth: npm/webcodecs-ffmpeg/package.json
Artifact naming: ffmpeg-{platform}-{license}.tar.gz (e.g., ffmpeg-darwin-arm64-free.tar.gz)
platforms/<os>-<arch>/ # Platform-specific builds
├── Makefile # Build orchestrator
├── build.sh # CI entry point
├── config.mk # Compiler/SDK configuration
shared/ # Cross-platform
├── common.mk # Reusable Make functions
├── versions.mk # Centralized versions/URLs/SHA256
├── verify.mk # Build verification guardrails
└── codecs/ # Shared codec recipes by license tier
├── bsd/ # libvpx, aom, dav1d, svt-av1, opus, ogg, vorbis
├── lgpl/ # lame
└── gpl/ # x264, x265
Stamp files: Each codec creates .stamp on success for incremental builds.
Build systems: Autoconf (autoconf_build), CMake (cmake_build), Meson (meson_build)
Common functions (from shared/common.mk):
download_and_extract/git_clone- Dependency fetchingverify_static_lib/verify_pkgconfig- Post-build verification
| Tier | Codecs | FFmpeg Flag | Use Case |
|---|---|---|---|
free |
libvpx, aom, dav1d, svt-av1, opus, ogg, vorbis, lame | (default) | Commercial/proprietary apps (LGPL-safe) |
non-free |
All above + x264, x265 | --enable-gpl |
Open source projects (GPL-licensed) |
Default is free - safe for commercial use with LGPL compliance.
Use LICENSE=non-free to include GPL x264/x265 codecs.
New codec:
- Add version/URL/SHA256 to
shared/versions.mk - Create
shared/codecs/<license>/<codec>.mk - Add to
CODEC_STAMPSin platform Makefile - Add
--enable-lib<codec>to FFmpeg configure
New platform:
- Create
platforms/<os>-<arch>/with Makefile, config.mk, build.sh - Set platform variables in config.mk (see existing platforms)
Internal tooling uses pnpm for workspace management and publishing. Consumers install packages via npm/yarn/pnpm from the npm registry.
# Workspace operations (from npm/ directory)
pnpm install # Install dependencies
pnpm list -r # List all workspace packages
pnpm publish -r --dry-run # Preview publishing
# Local development
./scripts/local-publish.sh --latest --version v0.1.0 --dry-runWorkspace configuration is in npm/pnpm-workspace.yaml.
Use /dev-ffmpeg skill for guidance on FFmpeg compilation, license compliance, and platform-specific configuration. Reference docs in .claude/skills/dev-ffmpeg/references/.
Primary sources:
https://ffmpeg.org/pipermail/ffmpeg-devel/- Developer mailing listhttps://trac.ffmpeg.org/- Bug trackerhttps://ffmpeg.org/general.html- External library requirements
FFmpeg 7+ gotchas:
- x265 static linking requires
--extra-libs=-lc++(broken .pc file) - Use
--pkg-config-flags="--static"for static builds - NASM required for x86 assembly (YASM deprecated)
Wrong:
cd $(SRC) && export PKG_CONFIG_LIBDIR="$(PREFIX)/lib/pkgconfig" && ./configureRight: Use inline prefix (propagates to child processes):
cd $(SRC) && PKG_CONFIG_LIBDIR="$(PREFIX)/lib/pkgconfig" ./configureDocker-specific: Environment isolation is stricter. Always use inline prefixes.
Cross-compilation flags can silently produce wrong-arch binaries. Every build must verify:
file "$BINARY" | grep -q "$EXPECTED_ARCH" || exit 1Native > cross-compile: darwin-x64 required 8+ fixes for cross-compilation. Switched to native Intel runner (macos-13).
./configure --prefix=$(PREFIX) $(if $(HOST_TRIPLET),--host=$(HOST_TRIPLET))Affected: opus, ogg, vorbis, lame, x264
FFmpeg prepends --cross-prefix to pkg-config binary. Force native:
./configure --cross-prefix=aarch64-linux-gnu- --pkg-config=pkg-configaom, x265, svt-av1 require CMake 3.x:
pip3 install 'cmake>=3.20,<4'npm registry E409 conflicts need retry with backoff:
for attempt in 1 2 3; do pnpm publish && break; sleep $((attempt * 5)); doneLayered verification defined in shared/verify.mk:
| Layer | When | Catches |
|---|---|---|
| 0. Parse-Time | Makefile parse | Mutable git refs |
| 1. Preflight | make preflight |
Wrong arch toolchain, env issues |
| 2. Post-Codec | After each codec | Silent build failures |
| 3. Pre-Configure | Before FFmpeg | Missing codecs |
| 4. Post-Build | make verify |
Wrong arch, dynamic deps |
Common errors:
Wrong architecture:
ERROR: Toolchain produces wrong architecture
Fix: Check CC and CFLAGS in config.mk
Missing codec:
ERROR: Some codecs not available for FFmpeg
Fix: Build missing codecs first with 'make codecs'
Mutable ref:
*** x264 uses mutable ref 'stable'. Pin to commit hash.
| Variable | Purpose | Example |
|---|---|---|
ARCH_VERIFY_PATTERN |
Architecture verification | arm64, aarch64, x86-64 |
FFMPEG_EXTRA_LIBS |
Link libraries | -lpthread -lm -lc++ |
Linux requires -ldl for x265's dlopen():
FFMPEG_EXTRA_LIBS := -lpthread -lm -lstdc++ -ldl