Most FFmpeg users treat filters as static: you set crop=w:h:x:y once, press Enter, and live with the result. But many filters support runtime commands—you can change parameters while the video is being encoded. Need a watermark to fade in, move across the screen, or change opacity halfway through? You don't need multiple encodes or complex scripting. You need sendcmd, zmq, and a solid grasp of timeline expressions.
Key takeaways
sendcmdreads a command file and applies changes at specific timestamps—perfect for scripted animations.zmqlets you push commands interactively over ZeroMQ for live tweaking during a stream or recording.- Filters that support the
enableoption can be turned on/off based on time, but for gradual changes you need runtime commands. - Dynamic expressions like
t(current time in seconds) andn(frame number) let you animate parameters frame by frame without external input. - Not all filters support commands—always look for the 'T' flag in the official FFmpeg documentation.
The Gap: Timeline enable vs. True Dynamic Control
FFmpeg's timeline editing feature (the generic enable option) is widely known. You can write:
# apply a blur only between 5 and 10 seconds ffmpeg -i in.mp4 -vf "smartblur=5:0.8:0:enable='between(t,5,10)'" -c:a copy out.mp4
That works—but enable is a simple on/off switch. It doesn't let you change a filter's parameters continuously over time. You can't make a watermark gradually fade in, or move an overlay smoothly across the frame, or adjust a volume knob live while streaming. For that, you need runtime commands.
The Symptom: Hours of Trial and Error
Building a script that changes a watermark's opacity or moves an overlay dynamically usually turns into a frustrating marathon. Why?
- Documentation examples are minimal. The FFmpeg docs list which filters support commands, but real‑world examples are scarce.
- Syntax varies per filter. Some filters accept
widthandheightcommands; others expectxandy; some useopacity, othersalpha. - Timing is tricky. You need to know whether your expression uses
t(seconds) orn(frame number), and whether the filter evaluates per‑frame or only at configuration.
The good news: once you understand the two main mechanisms—sendcmd and zmq—you can stop guessing and start building reliable, dynamic encoding pipelines.
Method 1: sendcmd – Scheduled Commands from a File
sendcmd reads a text file containing commands and applies them at specific timestamps. It's ideal for predictable, scripted changes—like a fade‑in that lasts two seconds, or a logo that moves from left to right over five seconds.
Create a command file (e.g., commands.txt) with this format:
# change overlay opacity between 1 and 3 seconds
1.0 overlay x 100 y 100 opacity 0.0
2.0 overlay x 100 y 100 opacity 0.5
3.0 overlay x 100 y 100 opacity 1.0
# move the overlay from left to right between 5 and 10 seconds
5.0 overlay x 0 y 200
10.0 overlay x 500 y 200
Then run:
# apply commands from a file using sendcmd ffmpeg -i background.mp4 -i logo.png \ -filter_complex "[1:v]sendcmd=f=commands.txt[ov];[0:v][ov]overlay" \ -c:a copy out.mp4
Important: The sendcmd filter must be placed before the filter it's controlling in the filtergraph. In the example above, sendcmd is applied to the overlay stream ([1:v]) before it's passed to overlay.
Method 2: zmq – Interactive Real‑Time Commands
If you need to tweak parameters live—while encoding a stream, or during a recording session—zmq (ZeroMQ) is your friend. It sets up a socket that listens for commands you send from another terminal (or from a script).
First, enable zmq in your filtergraph:
# start FFmpeg with a zmq filter listening on port 5555 ffmpeg -i in.mp4 -vf "zmq,volume=volume=1.0" -c:a copy out.mp4
Then, in another terminal, send a command:
# send a command to change volume to 0.5
echo "volume volume 0.5" | zmqsend
The zmq filter passes the command to the volume filter, which adjusts the gain instantly—no restart, no re‑encode.
Note: You need to build FFmpeg with --enable-libzmq to use the zmq filter. Most pre‑built binaries don't include it, so you may need to compile from source.
Which Filters Support Runtime Commands?
Not every filter does. Look for the 'T' flag in the filter's documentation—it indicates the filter supports commands. Common filters that support runtime commands include:
crop– changew,h,x,yon the flyoverlay– changex,y,opacityvolume– change gain/volumescale/zscale– changewidth,heightdrawtext– change text, position, font size, etc.smartblur– change blur intensity
For filters that don't support commands, you can sometimes work around it by using the enable option with a timeline expression—but that only gives you on/off control, not gradual change.
Dynamic Expressions: t, n, and Per‑Frame Evaluation
Some filters evaluate expressions per frame, which lets you animate parameters without sending explicit commands. For example, the overlay filter can evaluate x and y expressions dynamically.
This makes a logo bounce or slide:
# slide a logo from left to right over 10 seconds
ffmpeg -i bg.mp4 -i logo.png \
-filter_complex "[1:v]format=rgba,colorchannelmixer=aa=0.8[logo]; \
[0:v][logo]overlay=x='100*t':y='200'" \
-c:a copy out.mp4
Here, x='100*t' moves the logo 100 pixels per second. You can also use n (frame number) for frame‑accurate animation, or combine expressions with if(), between(), and sin() for oscillating effects.
Pro tip: not all filters evaluate expressions per frame. Some evaluate only once at configuration time. Check the documentation for your filter—if it says "This expression is evaluated only once during the filter configuration," you'll need sendcmd or zmq instead.
Practical Example: Fading a Watermark In and Out
Let's put it all together. Suppose you want a watermark that:
- Appears at 2 seconds with 0% opacity
- Fades to 100% opacity by 4 seconds
- Stays at 100% until 8 seconds
- Fades out to 0% by 10 seconds
Using sendcmd, create watermark.txt:
2.0 overlay opacity 0.0
3.0 overlay opacity 0.5
4.0 overlay opacity 1.0
8.0 overlay opacity 1.0
9.0 overlay opacity 0.5
10.0 overlay opacity 0.0
Then run:
ffmpeg -i video.mp4 -i watermark.png \
-filter_complex "[1:v]sendcmd=f=watermark.txt,format=rgba,colorchannelmixer=aa=1[wm]; \
[0:v][wm]overlay=x=W-w-10:y=10" \
-c:a copy output.mp4
That's it—no multiple encodes, no fragile shell scripts, no guesswork.
Test Dynamically in the FFmpegLab IDE
The FFmpegLab editor lets you drag, drop, and preview dynamic effects before you commit to a full encode. You can adjust opacity sliders, move overlays, and see the result in real time—then export the exact sendcmd or zmq command you need.
Try it below. Load a video, add an overlay, set keyframes for opacity and position, and watch the preview update instantly. When you're happy, copy the generated FFmpeg command and run it locally—fully offline, nothing uploaded.
# dynamic overlay with keyframed opacity and position
ffmpeg -i background.mp4 -i overlay.png \
-filter_complex "[1:v]sendcmd=f=keyframes.txt,format=rgba,colorchannelmixer=aa=1[ov]; \
[0:v][ov]overlay=x='W-w-10':y='10+50*sin(t*0.5)'" \
-c:a copy dynamic.mp4
Frequently Asked Questions (FAQ)
What is the difference between sendcmd and zmq in FFmpeg?
sendcmd reads a predefined text file and applies commands at fixed timestamps—perfect for offline, scripted animations. zmq opens a live socket that listens for commands over ZeroMQ, allowing you to adjust parameters interactively during an ongoing encode or stream.
Which FFmpeg filters support dynamic runtime commands?
Filters marked with a 'T' (timeline + commands) in the official FFmpeg documentation support runtime commands. Common ones include crop, overlay, volume, scale, drawtext, and smartblur.
Can I change overlay opacity dynamically without restarting FFmpeg?
Yes. Use sendcmd with an opacity command file or zmq to send opacity values live. Both methods update the overlay's alpha channel in real time.
Does FFmpeg support per‑frame expression evaluation for animations?
Yes. Many filters, including overlay, evaluate expressions per frame using t (time in seconds) and n (frame number). This allows smooth sliding, bouncing, or scaling without external command files.
Final Word
Dynamic runtime commands turn FFmpeg from a batch processor into a live, interactive editing tool. Whether you're fading watermarks, moving logos, adjusting audio on the fly, or creating complex motion graphics, sendcmd and zmq give you the control you need—without the trial and error.
Next time you're wrestling with a script that changes opacity or position over time, remember: you don't have to guess. Use runtime commands, test interactively, and let FFmpeg do the heavy lifting.