FFmpeg AI Alternative
ffmpeg does exactly what you told it to. That is the whole problem. Every command on this page is correct and worth knowing. None of them can express "cut the bit where I fumble the pricing line" — not because the filtergraph language is weak, but because that sentence is about content, and ffmpeg has never claimed to know anything about content. It is a transcoder with an extremely good filter engine, and it is the best one there has ever been.
So this page does two things. First, the real commands for the seven jobs people actually run, with the gotcha attached to each — because half the ffmpeg answers on the internet are subtly wrong and it costs you an hour to find out. Then the honest version of the gap: what a model that emits ffmpeg commands fixes, what it does not, and what an agent with a transcript and eyes does differently. Valmera's renderer is ffmpeg. This is not an argument against the tool.
Describe the Edit. Keep the ffmpeg.
50 free credits, no card. Upload real footage, say what you want, and the agent produces the edit — then exports from your original file.
Try it free →What ffmpeg Is Genuinely Unbeatable At
Determinism. Given the same input and the same command, ffmpeg produces the same bytes on every machine, this year and in ten years, with no account, no upload and no network. That property is the reason it sits under essentially every video product on the internet, including this one.
It also owns the layers nothing else touches: container and codec surgery, pixel formats, colour primaries and transfer characteristics, 10-bit and HDR, ProRes and DNxHD, HLS and DASH packaging, RTMP and SRT ingest, hardware encoders, timestamps, and the several hundred filters in between. It handles files that are broken in ways a GUI will simply refuse. It scales to ten thousand files in a for-loop for the price of the CPU.
None of that is what the rest of this page is about. The rest of this page is about the one thing ffmpeg cannot do, which is know what is in your video.
The Seven Commands, Correct
Verified against the ffmpeg filter documentation. Each one is followed by the failure mode people hit, which is usually the part that was missing from wherever they copied it.
1 · Trim a range without re-encoding
# fast seek, stream copy — no quality loss, no CPU
ffmpeg -ss 00:01:30 -i talk.mp4 -t 75 -c copy \
-avoid_negative_ts make_zero cut.mp4
# frame-accurate, at the cost of a re-encode
ffmpeg -ss 00:01:30 -i talk.mp4 -t 75 \
-c:v libx264 -crf 18 -preset veryfast -c:a aac -b:a 192k cut.mp4The gotcha: with -c copy the cut snaps to the nearest keyframe at or before your -ss, so the output starts early and its first frames may reference frames that were never copied — the freeze or block-mess at the head. Since ffmpeg 2.1 input seeking is frame-accurate for re-encodes, so -ss belongs before -i either way; it is only stream copy that is keyframe-bound.
2 · Cut the middle out, then join the halves
ffmpeg -i talk.mp4 -t 92 -c copy part1.mp4
ffmpeg -ss 118 -i talk.mp4 -c copy part2.mp4
printf "file 'part1.mp4'\nfile 'part2.mp4'\n" > list.txt
ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp4
# when the parts differ in codec, resolution or frame rate:
ffmpeg -i a.mp4 -i b.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" out.mp4The gotcha: the concat demuxer stream-copies and therefore requires identical codecs, resolution, frame rate and pixel format across every part — mismatch it and you get a file that plays for one segment and then falls apart. -safe 0 is what permits absolute paths in the list. The concat filter handles mismatched inputs but re-encodes everything, including the parts you did not touch.
3 · Find the silences
ffmpeg -i talk.mp4 -af silencedetect=noise=-30dB:d=0.6 \
-f null - 2> silences.txt
# [silencedetect @ ...] silence_start: 3.204
# [silencedetect @ ...] silence_end: 5.118 | silence_duration: 1.914The gotcha: the measurements go to stderr, not stdout, so the redirect is 2>. Defaults are noise=-60dB and d=2, both far too conservative for speech — -30dB and 0.6 is a sane starting point for a decent microphone. And what you get is a list of silences; the spans you want to keep are the inverse, which you compute yourself.
4 · Actually remove those silences
ffmpeg -i talk.mp4 \
-vf "select='between(t,0,3.204)+between(t,5.118,9.4)',setpts=N/FRAME_RATE/TB" \
-af "aselect='between(t,0,3.204)+between(t,5.118,9.4)',asetpts=N/SR/TB" \
-c:v libx264 -crf 18 -c:a aac tight.mp4The gotcha: setpts and asetpts are not optional. Without them the surviving frames keep their original timestamps and the player stalls through the gaps you just removed. Note also that the expression grows by one between() term per kept span — a talking-head with three hundred pauses produces a filtergraph you cannot read, let alone edit. And amplitude is not speech: this will cut mid-word through a quiet consonant, because silencedetect hears a level, not a language.
5 · Reframe 16:9 to 9:16
# centre crop — loses the sides
ffmpeg -i talk.mp4 -vf "crop=ih*9/16:ih,scale=1080:1920:flags=lanczos" \
-c:a copy vertical.mp4
# blurred pad — keeps the whole frame, fills the rest
ffmpeg -i talk.mp4 -filter_complex \
"[0:v]scale=1080:1920:force_original_aspect_ratio=increase,\
crop=1080:1920,gblur=sigma=24[bg];\
[0:v]scale=1080:-2[fg];\
[bg][fg]overlay=(W-w)/2:(H-h)/2" -c:a copy vertical.mp4The gotcha: scale=1080:-2, never -1 — H.264 in 4:2:0 needs even dimensions and -2 is the flag that rounds to one. But the real gotcha is conceptual: a centre crop assumes the subject is in the centre. It is not. Whoever is speaking moves, and a fixed crop beheads them for the half of the video where they lean out of frame. The auto-reframe problem is a tracking problem, and there is no ffmpeg filter for "follow the person who is talking".
6 · Burn subtitles with libass
ffmpeg -i talk.mp4 -vf "subtitles=subs.srt:fontsdir=./fonts:\
force_style='FontName=Anton,FontSize=28,PrimaryColour=&H00FFFFFF,\
OutlineColour=&H00000000,BorderStyle=1,Outline=3,Shadow=0,\
Alignment=2,MarginV=90'" \
-c:a copy captioned.mp4The gotcha: three of them. Your build needs --enable-libass — ffmpeg -filters | grep subtitles tells you. ASS colours are &HAABBGGRR: bytes reversed from CSS, and the alpha byte is inverted, so 00 is fully opaque. And FontSize is in the subtitle script's own resolution, not pixels, so the same number renders at a different size on a 1080p and a 4K master unless PlayResY matches. Paths with colons need escaping. The file must be UTF-8. And subs.srt has to exist before any of this is relevant, which means an ASR pass that ffmpeg does not perform.
7 · Two-pass loudnorm, and frame extraction
# pass 1 — measure only
ffmpeg -i talk.mp4 -af loudnorm=I=-14:TP=-1.5:LRA=11:print_format=json \
-f null -
# -> input_i, input_tp, input_lra, input_thresh, target_offset
# pass 2 — feed the measurements back, apply one linear gain
ffmpeg -i talk.mp4 -c:v copy -af loudnorm=I=-14:TP=-1.5:LRA=11:\
measured_I=-21.7:measured_TP=-4.2:measured_LRA=8.4:\
measured_thresh=-32.5:offset=-0.3:linear=true \
-c:a aac -b:a 192k -ar 48000 mastered.mp4
# every 5th second as a JPEG
ffmpeg -i talk.mp4 -vf fps=1/5 -q:v 2 frames/%05d.jpg
# keyframes only, fast — decoder skips the rest
ffmpeg -skip_frame nokey -i talk.mp4 -fps_mode vfr -frame_pts true frames/%d.pngThe gotcha: single-pass loudnorm is a dynamic compressor and will squash a performance; the two-pass form with linear=true applies one constant gain and leaves the dynamics intact. loudnorm also resamples internally to 192 kHz, so pass -ar 48000 explicitly or you will ship a 192 kHz AAC track. On the frames: -fps_mode vfr replaced the deprecated -vsync vfr, and without it ffmpeg duplicates frames to hold a constant rate — which is exactly what you did not want when you asked for keyframes.
Every one of those is a real answer to a real job, and none of them is what makes editing slow.
The Part That Is Not in the Manual
Here is the honest shape of an edit. You already know that trimming is -ss and -t. You have known that for years. What takes the afternoon is scrubbing a fourteen-minute recording to find the four seconds where you fumbled the pricing line — and then the six other moments like it, and then re-finding them all after you changed your mind about the intro and every timestamp downstream moved.
Read the diagram bottom-up and the point lands harder. The bottom row — the actual command — is five seconds of typing. Everything above it is the work, and none of it is a flag. A filtergraph takes numbers; producing the numbers is a perception problem. That is not a gap in ffmpeg's design. It is a different job that ffmpeg was never in.
It compounds, too. Change one cut near the start and every timestamp after it shifts, so your carefully measured caption timings, your zoom in-points and your music cue are all wrong by 1.9 seconds. In a shell pipeline that means re-deriving the lot. In an edit decision list it means nothing at all: the decisions are stored against the source clock and the program is recomputed.
What an LLM Over ffmpeg Fixes — and What It Does Not
The obvious move is to put a model in front of the CLI: you type the sentence, it emits the command. Several good open-source tools do exactly this — llmpeg, wtffmpeg, MediaLLM — and there is serious research in the same shape. ELLMPEG (Azimi, Farahani, Prodan and Timmerer, MMSys 2026) pairs retrieval over the ffmpeg documentation with an iterative self-reflection step so the model can catch its own errors, and reports 78% average command-generation accuracy across 480 prompts on an edge-deployable model.
Take that number the way its authors do. It is a strong result for a hard problem, and it also says that roughly one command in five is wrong. Which is the first of three things this architecture cannot fix.
A wrong flag looks exactly like a right one
Models invent options. -preset ultrafast is real; a confidently produced -quality high is not. Worse are the ones that parse: -crf on an audio-only encode, -b:v silently ignored beside -crf, a filter placed after the output so it never applies. ffmpeg does not object. You get a file, it plays, and it is wrong in a way you find three days later.
There is no feedback loop
The model emits text, the shell runs it, and the model never sees the result. It cannot know that the centre crop cut off the speaker's head, that the captions landed over a face, that the trim started eight seconds early because the keyframe was there, or that the "silence" it removed contained a word. Self-reflection over the command is not inspection of the output — one checks syntax, the other checks reality.
It still does not know what is in the video
This is the one that matters. Give the best model in the world perfect ffmpeg syntax and ask it to cut the fumbled pricing line, and it has nothing to work with. It has not heard the audio, has not seen a frame and has no timestamps. The syntax was never the bottleneck. Everything on the top three rows of the diagram above is still missing.
The dashed arrow on the left is you. That is the entire difference, and it is why "put a model in front of ffmpeg" tops out where it does. The loop has to close inside the tool, and to close it the tool needs senses.
Three Different Things Called "ffmpeg AI"
| ffmpeg | LLM → ffmpeg | Valmera | |
|---|---|---|---|
| Performs the operation | Yes — it is the reference implementation | Yes, by shelling out to ffmpeg | Yes — the renderer is ffmpeg |
| Knows which seconds to operate on | You supply them | You supply them | Reads them off the transcript, silences and frames |
| Word-level transcript of the audio | No — pipe to a separate ASR first | No | Built once per upload, with speaker labels |
| Catches a wrong flag | Parse errors, yes. A valid flag doing the wrong thing, no | No — a plausible flag is indistinguishable from a real one | Typed tool schemas; an invalid call is refused, not attempted |
| Looks at what it produced | ✗ | ✗ | Renders a preview and reads the frames back |
| Reversible | Only if you kept the input file | Same | Edits a decision list; the upload is never written to |
| Multi-step dependent requests | You write the pipeline | One command per prompt | Sequenced by the agent |
| Runs headless, in CI | ✓ | ✓ | Over MCP, from an agent — not from a shell script |
| Codec, container and bitrate control | Total | Whatever the model emitted | H.264 MP4 out; no codec switches |
| Cost | Free | Model tokens | 50 free credits, then per-turn |
The two rows that decide it are the second and the fifth. Everything else is convenience.
What Valmera Does Instead
Upload a file — up to 14 GB or 3 hours, MP4, MOV, MKV or WebM. It is indexed once: a word-level transcript with speaker labels, every silence measured, shot boundaries detected, and labeled frame tiles the agent reads directly. That index is the thing a shell pipeline does not have, and it is paid for exactly once — every later request reads it, which is why a request against a three-hour recording is not three hours of work.
Then you describe the outcome and the agent works against an edit decision list. It has 108 tools — 97 editing, 11 session — and every one of them writes a decision, never a pixel. Your upload is never modified. Anything cut can be restored by asking. Cuts snap to word boundaries rather than amplitude thresholds, because the transcript knows where the word ended and silencedetect only knows where the level dropped.
It renders a preview from a fast proxy and then looks at the frames it produced — real tiles out of its own render, carrying a faint tenths grid, so an aim point is a measurement rather than an impression. That is what catches the caption sitting over a face without you reporting it. And every reply is verified server-side against the decisions actually recorded, so the agent cannot claim an edit it did not make; when nothing changed, it says nothing changed. If you have ever been told by a chat assistant that it ran a command it did not run, that guarantee is the one you want.
The export goes back to your original upload and renders at source quality — H.264 MP4. Previews use the proxy; the deliverable never does. Underneath all of it, the renderer is ffmpeg and the caption layer is libass. The same two pieces you would have reached for. The difference is upstream.
The Command and the Sentence
Same ten jobs, three ways to look at each. The middle column is not a criticism of ffmpeg — it is an accurate description of what you have to already know before ffmpeg can help.
| The job | What you have to write | What you say instead |
|---|---|---|
| Trim a range | -ss 00:01:30 -i in.mp4 -t 75 -c copy | “cut from 1:30 to 2:45” |
| Drop the dead air | silencedetect to a log, parse it, then one select= term per kept span | “cut the silences” |
| Drop the filler words | no primitive at all — needs word-level ASR before ffmpeg can help | “remove the ums” |
| Reframe for Reels | crop=ih*9/16:ih,scale=1080:1920 — or a blurred-pad filter_complex | “make it 9:16 for Reels” |
| Burn captions | subtitles=subs.srt:force_style='…' — and subs.srt has to exist already | “add karaoke captions” |
| Master the loudness | two-pass loudnorm, feeding the measured_* values back in | “master it to −14 LUFS” |
| Music under the voice | amix plus sidechaincompress keyed off the speech track | “put chill music under my voice” |
| Punch in on a word | zoompan, or a scale/crop ramp — timed by hand, per word | “punch in when he says ‘never’” |
| Blur a licence plate | crop the region, boxblur it, overlay it back with enable='between(t,…)' | “blur the plate” |
| Cut on the beat | no primitive — beat detection happens somewhere else first | “cut on the beat” |
Four of those ten have no ffmpeg primitive at all. Filler-word removal, beat-aligned cutting, repeated-take detection and subject-tracked reframing are not filters that exist — they are analysis steps that have to happen somewhere else and then be handed to ffmpeg as numbers. That "somewhere else" is the product.
How to Edit a Video Without Writing an ffmpeg Command
- 1Upload the source fileUp to 14 GB or 3 hours, in MP4, MOV, MKV or WebM. Valmera indexes it once — word-level transcript with speaker labels, measured silences, shot boundaries and labeled frame tiles — with visible progress. Every later request reads that index instead of the pixels.
- 2State the outcome, not the flags"Cut the dead air and the ums, add karaoke captions, put a calm track under my voice, master it to -14 LUFS and reframe it 9:16." Those are five operations with dependencies between them — the cuts move the timeline the captions are timed against, and the music has to fit a length nothing knows until the cuts are done. The agent sequences that itself.
- 3Judge the preview, correct by talkingThe agent renders a preview and inspects its own frames. Reply in plain English — "looser cuts", "captions higher", "different track" — and each correction is another full pass, not a manual fix. Export when it is right and the render comes from your original file at source quality.
Indexing a long upload takes a while and shows progress throughout; the analysis is done once and reused by every edit after it.
When to Stay in ffmpeg
Most of the time, honestly. These are the cases where opening a browser is the wrong move and the answer is a command.
- Anything at volume. Ten thousand files, one for-loop, no upload, no per-item cost. There is no argument here.
- Codec, container or bitrate work. Remuxing, changing pixel format, 10-bit, HDR metadata, ProRes or DNxHD masters, CBR for a broadcast spec. Valmera exports H.264 MP4 and offers no codec switches.
- Packaging and delivery. HLS or DASH ladders, segmenting, RTMP or SRT ingest, thumbnails for a CDN. Not remotely the same job.
- Determinism and privacy. Reproducible bytes, an air-gapped machine, footage that must not leave the building.
- Repair. Broken indexes, mismatched timestamps, files a GUI refuses to open.
ffmpeg -err_detectand a hex editor beat any agent. - Non-video. Audio-only transcodes, image sequences, GIFs, waveform renders.
And the other side of that, so this page does not do the thing every competitor page does. Valmera does not generate a video from a text prompt — it edits footage you upload. No SRT or VTT import or export, because captions are burned into the picture. No true crossfade or dissolve, and one transition style per video rather than per cut. No multi-cam sync, no motion-tracked overlays, no custom font uploads. No audio denoise or "studio sound", no per-speaker leveling, no separating music out of an already-baked track, no AI music generation. One deliverable per request, so ten Shorts is ten requests rather than a batch. No team seats, share links, direct publishing to YouTube or TikTok, or native mobile app. English is the best-tested transcription path.
If your job is on the first list, close this tab and write the command. If it is on the second, ffmpeg is still your answer and this was not the page.
If You Would Rather Stay in the Terminal
There is a middle path that is not a web app. Valmera publishes its complete tool registry as a remote Model Context Protocol server over streamable HTTP, with OAuth 2.1, dynamic client registration and PKCE. One line attaches it to Claude Code:
claude mcp add --transport http valmera \
https://entrepreneur-bot-backend.onrender.com/mcpThen /mcp to sign in — there is no token to copy — and the model in your terminal can upload, index, cut, caption, mix, render, export and hand you a download URL. It is the same registry the in-house agent uses, served verbatim rather than re-declared, so there is no second tool list that can drift out of sync. Slow operations return a job id and a wait_for_job call instead of a fabricated completion, which is the MCP equivalent of not lying about whether the encode finished.
If you were about to write a shell script around an LLM that emits ffmpeg, this is the thing you were building, with the index and the feedback loop already attached. Setup for the Claude Code, Claude app and Cursor paths, the full tool reference, and why the programmatic surface is an MCP server rather than a REST API.
Frequently Asked Questions
Keep the ffmpeg. Skip the Scrubbing.
50 free credits, no card. Upload real footage, describe the cut, and let the agent find the moment — then export from your original file at source quality.
Start free →