Skip to content

feat(ffmpeg): add server-side FFmpeg media-processing block#4802

Open
waleedlatif1 wants to merge 3 commits into
stagingfrom
waleedlatif1/svg-icon-white-bg-docs
Open

feat(ffmpeg): add server-side FFmpeg media-processing block#4802
waleedlatif1 wants to merge 3 commits into
stagingfrom
waleedlatif1/svg-icon-white-bg-docs

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Add an FFmpeg block that processes video/audio files server-side — no external service, API key, or OAuth. Runs via an internal /api/tools/ffmpeg/process route using the already-bundled ffmpeg-static / fluent-ffmpeg.
  • Files flow in and out as standard UserFile objects (input via the STT pattern, output via the TTS pattern), so the block chains naturally with other blocks.
  • 9 operations: Convert Format, Extract Audio, Trim/Cut, Compress/Scale, Get Media Info (ffprobe), Extract Thumbnail, Concatenate, Adjust Volume, Change Speed.
  • Boundary contract in lib/api/contracts/tools/media/ffmpeg.ts; block + 9 tools registered; icon + docs (with a manual usage section) added.

Type of Change

  • New feature

Testing

Tested manually. biome clean, bun run check:api-validation passing. Note: tsc/vitest were not run locally (deps not installed in this workspace) — they run in CI.

Notes

  • Concatenate uses the concat demuxer with stream copy, so inputs must share the same codec/format.
  • Get Media Info requires ffprobe on the server PATH (ffmpeg-static bundles ffmpeg only) — same assumption as the existing audio extractor.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Add an FFmpeg block that processes video/audio files server-side (no
external service or auth) via an internal /api/tools/ffmpeg/process
route. Files flow in and out as standard UserFile objects.

Operations: convert, extract audio, trim, compress/scale, probe,
thumbnail, concatenate, adjust volume, change speed.
@vercel
Copy link
Copy Markdown

vercel Bot commented May 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped May 30, 2026 1:23am

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented May 29, 2026

PR Summary

Medium Risk
New server-side binary execution on user-uploaded media (CPU, long-running jobs, temp files) with operational dependency on ffmpeg/ffprobe; mitigated by internal auth and size/filter validation but still expands attack/resource surface.

Overview
Adds a built-in FFmpeg workflow block and nine tools for server-side video/audio processing—no external API or credentials. Media flows through standard UserFile inputs/outputs so blocks can chain (e.g. convert → trim → thumbnail).

A new authenticated POST /api/tools/ffmpeg/process route (Zod contract, 300s limit) runs operations via ffmpeg-static / fluent-ffmpeg: convert, extract audio, trim, compress, probe, thumbnail, concat (stream-copy), volume, and speed. Inputs/outputs are capped at 200 MB; compress scale and volume strings are validated before filter use. Probe and speed need ffprobe on the server PATH.

The block is registered with icons, docs (ffmpeg.mdx), integrations metadata, and media-processing tagging; API validation baseline increases by one route.

Reviewed by Cursor Bugbot for commit 52323f6. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 29, 2026

Greptile Summary

This PR adds a server-side FFmpeg block supporting 9 operations (convert, extract audio, trim, compress, probe, thumbnail, concat, volume, speed), routed through /api/tools/ffmpeg/process and integrated as UserFile I/O so it chains naturally with other blocks. Security fixes for filter injection (scale, volume) and the concat output-size bypass from an earlier review have been applied in the current HEAD.

  • New route + contract: apps/sim/app/api/tools/ffmpeg/process/route.ts implements all operations with auth, per-operation validation, a shared finalize() helper for the 200 MB output guard, and temp-dir cleanup.
  • 9 tool definitions (apps/sim/tools/ffmpeg/) and a block config (apps/sim/blocks/blocks/ffmpeg.ts) wire the operations into the existing tool/block registry with typed params and shared transform helpers.
  • One unresolved input-validation gap: the speed Zod schema only enforces positive() with no lower bound, letting arbitrarily tiny values (e.g. 0.0001) instruct FFmpeg to produce output thousands of times longer than the input; the 200 MB size guard fires only after the full file has been written to disk and read into RAM.

Confidence Score: 4/5

Safe to merge after adding a minimum bound to the speed contract field — without it a tiny speed value (e.g. 0.0001) lets FFmpeg write a file many orders of magnitude larger than the input before the output-size guard can fire.

The speed contract field has .positive() but no lower bound, allowing values like 0.0001 that direct FFmpeg to produce output thousands of times the input's duration. The 200 MB guard only runs after the full output has been written to disk and read into RAM, so disk and memory exhaustion happen first. All other previously reported issues (concat size bypass, scale/volume injection, ffprobe dependency) have been fixed in the current HEAD.

apps/sim/lib/api/contracts/tools/media/ffmpeg.ts — the speed field needs a minimum constraint; the codec/bitrate fields would benefit from the same pattern-validation approach already applied to scale and volume.

Important Files Changed

Filename Overview
apps/sim/app/api/tools/ffmpeg/process/route.ts Core API route — 574 lines handling all 9 operations. Scale/volume injection and concat size-guard issues fixed in HEAD. speed lacks a meaningful minimum, allowing near-zero values that make FFmpeg write files orders of magnitude larger than the input before the 200 MB guard fires.
apps/sim/lib/api/contracts/tools/media/ffmpeg.ts Zod contract for the route. speed is validated as .positive().max(100) — no lower bound beyond 0, so arbitrarily small speeds pass validation. videoCodec, audioCodec, videoBitrate, format, startTime, duration, time use length-only bounds.
apps/sim/blocks/blocks/ffmpeg.ts Block definition wiring 9 sub-operations with correct conditional UI, file-upload/ref inputs, and tools config. Clean.
apps/sim/tools/ffmpeg/shared.ts Shared transform helpers and output-property definitions for file and probe responses. Well-structured and consistent.
apps/sim/tools/ffmpeg/types.ts Type definitions for all 9 operation param/response shapes. Clean; consistent with the route contract.
apps/sim/tools/registry.ts Adds 9 ffmpeg tool registrations in alphabetical order alongside existing tools. No issues.

Reviews (2): Last reviewed commit: "fix(ffmpeg): guard concat output size, v..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/ffmpeg/process/route.ts Outdated
Comment thread apps/sim/app/api/tools/ffmpeg/process/route.ts Outdated
Comment thread apps/sim/app/api/tools/ffmpeg/process/route.ts
Comment thread apps/sim/app/api/tools/ffmpeg/process/route.ts
Comment thread apps/sim/app/api/tools/ffmpeg/process/route.ts Outdated
… ffprobe errors

- Route concat output through finalize() so it enforces the empty-file
  and 200 MB output-size checks like every other operation
- Validate scale (width:height) and volume (multiplier/dB) against strict
  patterns before interpolating into the filter graph (prevents filter
  injection)
- Default compress audio to -c:a copy so audio isn't silently re-encoded
- Surface a clear 'ffprobe not found' message and document that Change
  Speed also requires ffprobe
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/api/contracts/tools/media/ffmpeg.ts Outdated
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 52323f6. Configure here.

Comment thread apps/sim/app/api/tools/ffmpeg/process/route.ts
- Sanitize all temp-file extensions (input name/MIME and output format)
  to [a-z0-9] so a crafted format like ../../../t.jpg cannot escape the
  temp dir (path traversal)
- finalize() now checks output size via fs.stat before fs.readFile, so an
  oversized output is rejected without loading the whole file into memory
- Bound the speed multiplier to [0.1, 100] in the contract (and block) to
  prevent tiny values producing pathologically large outputs
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