silenceremove cuts silence out of an audio file. Its options are easy to misread, which often ends in “it only trimmed the start” or “half my file disappeared”.

The test audio

Every output length shown was measured on one of these two files, in which each silence has a known position and length:

  • gaps.wav (8.0 s): tone 1 s → silence 2 s → tone 1 s → silence 3 s → tone 1 s
  • padded.wav (14.0 s): gaps.wav with 2 s of silence added in front and 4 s after

The tone is a 440 Hz sine wave. The silence is digital silence: every sample is exactly zero. Real recordings always contain some background noise, so for them you set the threshold to around -50dB (see “Choosing the threshold” below).

Trim leading silence only: start_periods=1

ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_threshold=-50dB" output.wav
Input Output What happened
padded.wav 14.0 s 12.0 s Only the 2 s of silence at the start is removed. The gaps in the middle and the 4 s at the end stay

start_periods=1 means “remove one stretch of silence before the sound starts”. It does not trim the end of the file. For the end, see the areverse method below.

start_duration and start_silence

  • start_duration=0.5 — sound counts as started only after 0.5 s of continuous sound. This keeps a short click from ending the trim, but those 0.5 s of sound are removed as well. Measured: 14.0 → 11.5 s (half a second of the tone is lost)
  • start_silence=0.3 — how much silence to keep before the sound, so that it doesn’t start abruptly. Measured: 14.0 → 12.3 s (0.3 s of silence remains at the start)

Both options together:

ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_duration=0.5:start_silence=0.3:start_threshold=-50dB" output.wav

Shorten mid-file gaps: stop_periods=-1

Use this to shorten long pauses in podcasts and lecture recordings.

ffmpeg -i input.wav -af "silenceremove=stop_periods=-1:stop_duration=1:stop_threshold=-50dB" output.wav
Input Output What happened
gaps.wav 8.0 s 5.04 s The 2 s and 3 s gaps each became 1 s. 1+1+1+1+1 = 5 s
padded.wav 14.0 s 8.06 s The gaps in the middle and the 4 s at the end each became 1 s. The 2 s at the start is still there

stop_periods=-1 means “act on every silence that comes after sound”. stop_duration=1 means “shorten any silence longer than 1 s to 1 s”. The silence at the very start is not affected, so add start_periods=1 to remove it as well:

ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_threshold=-50dB:stop_periods=-1:stop_duration=1:stop_threshold=-50dB" output.wav

How much silence to leave after shortening

stop_silence keeps extra silence on top of stop_duration. stop_duration=1:stop_silence=0.5 leaves 1.5 s in each gap (measured: gaps.wav 8.0 → 6.04 s). For shorter gaps, lower stop_duration instead: stop_duration=0.5 leaves 0.5 s in each gap (8.0 → 4.04 s).

For speech that still sounds natural, try stop_duration=1:stop_silence=0.3. For tight editing, try about stop_duration=0.3.

stop_periods=1 deletes everything after the first silence

ffmpeg -i input.wav -af "silenceremove=stop_periods=1:stop_duration=1:stop_threshold=-50dB" output.wav

This looks like “remove one silence at the end”. In fact, everything after the first silence is discarded. Measured: gaps.wav 8.0 s → 2.02 s: only the first second of tone and about 1 s of the silence after it (stop_duration=1) are left. A positive stop_periods means “end the output at the Nth silence”.

To shorten the gaps in the middle, use a negative value (stop_periods=-1). To trim only the silence at the end, use areverse as shown in the next section.

Trim trailing silence with areverse

The start_* options only work on the beginning. To trim the end, reverse the audio, trim its start, and reverse it back. The command below also trims the real start first, so it removes the silence at both ends:

ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_threshold=-50dB,areverse,silenceremove=start_periods=1:start_threshold=-50dB,areverse" output.wav

Measured: padded.wav 14.0 s → 8.0 s. The 2 s at the start and the 4 s at the end are gone; the gaps in the middle stay. To trim only the end, leave out the first silenceremove=start_periods=1:start_threshold=-50dB,.

areverse holds the whole recording in memory. About an hour of audio is fine; recordings several hours long need gigabytes of RAM.

Preview where the silence is: silencedetect

To see what counts as silence before you cut anything, run silencedetect. It writes no file and prints the positions to the log.

ffmpeg -i input.wav -af "silencedetect=noise=-50dB:d=0.5" -f null -
[silencedetect @ ...] silence_start: 1
[silencedetect @ ...] silence_end: 3.000023 | silence_duration: 2.000023
[silencedetect @ ...] silence_start: 4
[silencedetect @ ...] silence_end: 7.000023 | silence_duration: 3.000023

noise is the threshold, and d is the shortest stretch that counts as silence. With the same values in stop_threshold and stop_duration, silenceremove acts on roughly the same ranges. They can differ where quiet sound goes on for a while. silencedetect checks the level of each sample, while silenceremove by default uses the RMS level, an average over a short window (detection=rms). For more on reading the output, see Detect silence.

Choosing the threshold

Source start/stop_threshold
Digitally generated audio, DAW exports -60dB to -70dB
Microphone in a quiet room -45dB to -50dB
Noisy environment, old cassette -35dB to -40dB

If the threshold is too high (-30dB or above), quiet speech and the ends of words count as silence and get cut. Check with silencedetect and adjust in 5 dB steps.

Removing silence from a video

silenceremove is an audio filter, so it removes no picture from a video. Only the audio gets shorter, and it goes out of sync with the picture.

ffmpeg -i input.mp4 -af "silenceremove=start_periods=1:start_threshold=-50dB" -c:v copy output.mp4

This command runs without errors, but the result is the original video with audio that starts too early. To cut the silent parts out of the picture too, get the timestamps from silencedetect, cut out the parts with sound using trim / atrim or -ss/-to, and join them with concat. With many parts this needs a script, so a dedicated tool such as Auto-Editor, which uses FFmpeg underneath, is easier.

Combining with loudness normalisation

To normalise the loudness as well, put loudnorm after silenceremove. Normalising first also raises or lowers the background noise, which changes what counts as silence. Without -ar 48000, this command writes 192 kHz audio.

ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_threshold=-50dB:stop_periods=-1:stop_duration=1:stop_threshold=-50dB,loudnorm=I=-16:TP=-1.5:LRA=11" -ar 48000 output.wav

Output to MP3 / AAC

ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_threshold=-50dB" -c:a libmp3lame -q:a 2 output.mp3
ffmpeg -i input.wav -af "silenceremove=start_periods=1:start_threshold=-50dB" -c:a aac -b:a 160k output.m4a

FAQ

Nothing is trimmed from the start

Either the threshold is too low (for example -90dB), or the “silence” in your file contains noise. Check whether silencedetect=noise=-50dB reports that part as silence, and raise the threshold.

Words get chopped mid-sentence

The quiet ends of words are being cut as silence. This happens when the threshold is too high and stop_duration is short: even the short pauses between words are cut, together with the word endings before them. Lower stop_threshold (for example from -30dB to -50dB), raise stop_duration to 0.5–1 s, or keep some silence with stop_silence.

What is the window option?

It sets the length of the window over which the RMS level is measured for the threshold decision (default 0.02 s). You can normally leave it alone. Shorten it only to catch very short pulses.

The Silence cut tool runs silenceremove in your browser, so the file never leaves your device.