Sandbox-first FFmpeg processing on Cloudflare Containers.
Sandcut packages a common high-frequency workload—video transcoding, clipping, resizing, and watermarking—into a clean open-source reference project. It is designed to show how to run user-supplied FFmpeg jobs inside an isolated container sandbox, while keeping the control plane on Cloudflare Workers and the output in R2.
- Sandboxed FFmpeg: untrusted transformation jobs run inside a container instead of the Worker runtime.
- Edge control plane: authentication, request validation, routing, and storage orchestration stay in the Worker.
- Production-shaped design: lease-based container scheduling, structured error codes, SSRF protection, and streamed R2 uploads are included.
- Useful default scenario: this is not a toy demo; FFmpeg is a real, high-frequency workload with clear business value.
Client -> Worker (`src/index.js`) -> Container (`container/server.js`) -> R2
| |
+-> KV auth DO scheduler
src/index.js: API entry, auth, input probing, lease scheduling, and streamed upload flowsrc/scheduler.js: Durable Object scheduler with expiring container leasessrc/utils.js: shared validation, seek normalization, size probing, and responsescontainer/server.js: isolated FFmpeg runtime with streamed file responsescontainer/ffmpeg.js: FFmpeg argument planning forfast,accurate, andhybridseek modes
The processing API supports either a single input_url or multiple remote inputs through an inputs array for workflows such as multi-file concat and composition.
npm install
cp .dev.vars.example .dev.vars
npm run devDeploy with:
npm run deployRun tests with:
npm testcurl -X POST https://your-worker.workers.dev/video/process \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-token" \
-d '{
"input_url": "https://example.com/video.mp4",
"ffmpeg_args": ["-vf", "scale=320:240", "-c:v", "libx264", "-c:a", "aac"],
"seek": {
"mode": "hybrid",
"start": 30,
"duration": 8
}
}'fast: puts-ssbefore-i, best for quick clipping on large inputs.accurate: puts-ssafter-i, best when frame accuracy matters most.hybrid: combines coarse pre-input seek with fine post-input seek for a balanced default.
The Worker also probes remote input size with HEAD and a ranged GET fallback before leasing a container.
See CONTRIBUTING.md, SECURITY.md, and ROADMAP.md for the public project workflow.
Documentation site source now lives in apps/docs/ as a separate Markdown-driven docs app and can be published to an independent Cloudflare Pages project with npm run docs:deploy.