FFmpeg fade in fade out: video and audio, from and to black
Fade a video in and out with FFmpeg: fade=t=in and fade=t=out on the picture, afade on the sound, with the fade-out starting at the length minus its duration.

To fade a video in and out with FFmpeg, chain two fade filters on the picture and two afade filters on the sound. For a 10-second clip with 1-second fades: ffmpeg -i input.mp4 -vf "fade=t=in:st=0:d=1,fade=t=out:st=9:d=1" -af "afade=t=in:st=0:d=1,afade=t=out:st=9:d=1" output.mp4. The fade-out starts at the clip's length minus the fade's duration, so you need the length first.
The FFmpeg behavior below is quoted from the FFmpeg filters documentation and the ffprobe documentation, and the Sume facts come from the Timeline 1.0 and Video filter docs, all read on 2026-09-29. Anything called current behavior is read from Sume's code. The commands were run on a 10-second test clip.
How do I fade out at the end without knowing the length?
Read the length with ffprobe, subtract the fade, and pass the result as st. -show_entries format=duration prints only the container's duration, and the default writer's nw=1:nk=1 drops the section wrapper and the key, leaving a bare number.
FADE=1
LEN=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 input.mp4)
OUT=$(echo "$LEN - $FADE" | bc)
ffmpeg -i input.mp4 \
-vf "fade=t=in:st=0:d=$FADE,fade=t=out:st=$OUT:d=$FADE" \
-af "afade=t=in:st=0:d=$FADE,afade=t=out:st=$OUT:d=$FADE" \
output.mp4What do the fade options mean?
fade works on frames and afade on samples, but both take a start time and a duration in seconds, which is the easiest way to keep them in step. At the end of a fade-in the picture and sound are back to full; at the end of a fade-out the picture is the fade colour and the sound is silent.
- Fade to white instead of black with
fade=t=out:st=9:d=1:color=white. fade=t=in:st=5.5:d=0.5keeps the first 5.5 seconds black, then fades in over half a second.- The picture is re-encoded, because filters work on decoded frames.
| Option | fade (video) | afade (audio) |
|---|---|---|
t | in (default) or out | in (default) or out |
st | Start time in seconds; default 0 | Start time; default 0 |
d | Duration in seconds; used over n when both are set | Duration; used over ns when set |
| Length in units | n: frames, default 25 | ns: samples, default 44100 |
color / curve | color: fade colour, default black | curve: fade shape, default tri (linear) |
Can I fade a video in and out with Sume instead?
Yes, for files already on media.sume.com, such as earlier Sume job outputs. A Timeline 1.0 render (POST /v1/timeline-1.0/render) takes output.fade_in_seconds and output.fade_out_seconds, 0 to 5 seconds each, and the API reference says each fades the picture from or to black and the sound from or to silence, so you don't need a second setting; video transitions API covers the rules.
- Timeline takes sound only from
audioand the optionalsoundtrack; each clip's own audio is dropped in current code. To keep a clip's sound, pass its track from audio detach asaudio.url. - A render is $0.10 per output minute, reserved in whole minutes.
- For one clip, Sume's video filter also allows
fadein afiltergraph, but that graph is video-only (the server wraps[0:v]…[vout]), so the sound is not faded. Each encode job reserves $0.02. - A fade between two clips is a different job: see dip to black.
curl -X POST https://api.sume.com/v1/timeline-1.0/render \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: fade-edges-001" \
-d '{
"audio": { "url": "https://media.sume.com/artifacts/artf_demo/voice.wav", "duration_seconds": 10 },
"video": [{ "source_url": "https://media.sume.com/artifacts/artf_demo/talk.mp4", "start": 0, "duration": 10 }],
"output": { "fade_in_seconds": 1, "fade_out_seconds": 1 }
}'Sources
Related posts
More in Developers
- FFmpeg increase volume: the volume filter, in dB or ×
Increase volume in FFmpeg with -af volume: volume=2 or volume=6dB, with -c:v copy so the video isn't re-encoded. Check headroom with volumedetect first.
- Golang HTTP client retry: what net/http retries on POST
Go's http.Transport retries only network errors on reused connections, and a POST only with an Idempotency-Key header. Write the 429 and 5xx loop yourself.
- HeyGen API avatar ID and voice ID: where to find them
In HeyGen's v3 API, avatar_id is a look id from GET /v3/avatars/looks, and voice_id comes from GET /v3/voices or the look's default voice.
- HeyGen API key: get one and make your first video
Generate a HeyGen API key in its API dashboard, send it as X-Api-Key to api.heygen.com, check it with GET /v3/users/me, then create a video.
Written by Sume