OpenCut's video preview and audio playback both rely on mediabunny, which in turn requires the WebCodecs API (VideoDecoder / AudioDecoder). On browsers where WebCodecs is not exposed (e.g. Linux Chromium builds without proprietary codec support), import and playback both throw "codec not supported" errors and the editor becomes unusable. This change makes the editor work on those browsers without sacrificing the WebCodecs fast-path elsewhere: - Add a server-side /api/convert-video route that transcodes incoming videos to H.264 baseline 3.1 yuv420p via the system ffmpeg binary. processMediaAssets uses it automatically when readVideoFile reports canDecode=false so the asset stored is always something the browser can play. - Add HTMLVideoElementSink, a CanvasSink-shaped sink backed by a hidden <video> element + canvas.drawImage. VideoCache.initializeSink selects it only when WebCodecs VideoDecoder is unavailable; otherwise it keeps using mediabunny's CanvasSink unchanged. - Add FallbackAudioBufferSink, an AudioBufferSink-shaped sink backed by AudioContext.decodeAudioData (which uses the platform's native audio decoders, not WebCodecs). AudioManager and the import-time decode path swap to it on canDecode=false. runClipIterator is wrapped in a try/catch so a sink failure no longer leaves an unhandled rejection. Tests cover frame timing, dispose semantics, FPS clamping, the WebCodecs/AudioDecoder availability probes, AudioBuffer slicing, and the fallback iterator contract. |
||
|---|---|---|
| .github | ||
| .vscode | ||
| apps | ||
| docs | ||
| eslint/rules | ||
| notes | ||
| rust | ||
| script | ||
| .dockerignore | ||
| .gitignore | ||
| .npmrc | ||
| .prettierignore | ||
| .prettierrc.json | ||
| .tokeignore | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| LICENSE | ||
| README.md | ||
| biome.json | ||
| bun.lock | ||
| docker-compose.yml | ||
| eslint.config.mjs | ||
| package.json | ||
| tsconfig.json | ||
| turbo.json | ||
| wrangler.jsonc | ||
README.md
|
|
OpenCutA free, open-source video editor for web, desktop, and mobile. |
Sponsors
Thanks to Vercel and fal.ai for their support of open-source software.
Why?
- Privacy: Your videos stay on your device
- Free features: Most basic CapCut features are now paywalled
- Simple: People want editors that are easy to use - CapCut proved that
Project Structure
apps/web/: Next.js web applicationapps/desktop/: Native desktop app built with GPUI (in progress)rust/: Platform-agnostic core: GPU compositor, effects, masks, and WASM bindings. We're actively migrating business logic here from TypeScript.docs/: Architecture and subsystem documentation
Getting Started
Prerequisites
- Bun
- Docker and Docker Compose
Note: Docker is optional but recommended for running the local database and Redis. If you only want to work on frontend features, you can skip it.
Setup
-
Fork and clone the repository
-
Copy the environment file:
# Unix/Linux/Mac cp apps/web/.env.example apps/web/.env.local # Windows PowerShell Copy-Item apps/web/.env.example apps/web/.env.local -
Start the database and Redis:
docker compose up -d db redis serverless-redis-http -
Install dependencies and start the dev server:
bun install bun dev:web
The application will be available at http://localhost:3000.
The .env.example has sensible defaults that match the Docker Compose config — it should work out of the box.
Desktop setup
Desktop is opt-in. If you're only working on the web app, skip this entirely.
If you want to get ready for apps/desktop, see apps/desktop/README.md. It's a two-step setup: Rust toolchain first, then desktop native dependencies.
Local WASM development
Only needed if you're editing rust/wasm and want the web app to use your local build instead of the published package.
Prerequisites — install these once before anything else:
# Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# build the WASM package
cargo install wasm-pack
# reruns the build on file changes, used by bun dev:wasm
cargo install cargo-watch
-
Build the package once from the repo root:
bun run build:wasm -
Register the generated package for linking:
cd rust/wasm/pkg bun link -
Link
apps/webto the local package:cd apps/web bun link opencut-wasm -
Rebuild on changes while you work:
bun dev:wasm
To switch apps/web back to the published package, run:
cd apps/web
bun add opencut-wasm
Self-Hosting with Docker
To run everything (including a production build of the app) in Docker:
docker compose up -d
The app will be available at http://localhost:3100.
Contributing
We welcome contributions! While we're actively developing and refactoring certain areas, there are plenty of opportunities to contribute effectively.
🎯 Focus areas: Timeline functionality, project management, performance, bug fixes, and UI improvements outside the preview panel.
⚠️ Avoid for now: Preview panel enhancements (fonts, stickers, effects) and export functionality - we're refactoring these with a new binary rendering approach.
See our Contributing Guide for detailed setup instructions, development guidelines, and complete focus area guidance.
Quick start for contributors:
- Fork the repo and clone locally
- Follow the setup instructions in CONTRIBUTING.md
- Working on
apps/desktop? Seeapps/desktop/README.mdfor setup - Create a feature branch and submit a PR