What is the astats Filter?
astats measures an audio stream and prints the results to the console. One pass gives you the RMS level, peak level, DC offset and dynamic range, plus values that help you spot clipping.
Basic Usage
Print audio statistics for a video file
ffmpeg -i input.mp4 -af "astats" -f null /dev/null
The results go to stderr with the rest of FFmpeg’s log, after the whole file has been read.
Audio file statistics
ffmpeg -i input.mp3 -af "astats" -f null /dev/null
Reading the Output
The output looks like this:
[Parsed_astats_0 @ ...] Channel: 1
[Parsed_astats_0 @ ...] DC offset: 0.000016
[Parsed_astats_0 @ ...] Min level: -0.339507
[Parsed_astats_0 @ ...] Max level: 0.347663
[Parsed_astats_0 @ ...] Min difference: 0.000000
[Parsed_astats_0 @ ...] Max difference: 0.244717
[Parsed_astats_0 @ ...] Mean difference: 0.031762
[Parsed_astats_0 @ ...] RMS difference: 0.042086
[Parsed_astats_0 @ ...] Peak level dB: -9.176838
[Parsed_astats_0 @ ...] RMS level dB: -23.311905
[Parsed_astats_0 @ ...] RMS peak dB: -19.956980
[Parsed_astats_0 @ ...] RMS through dB: -42.057184
[Parsed_astats_0 @ ...] Crest factor: 5.090417
[Parsed_astats_0 @ ...] Flat factor: 0.000000
[Parsed_astats_0 @ ...] Peak count: 2
[Parsed_astats_0 @ ...] Abs Peak count: 1
[Parsed_astats_0 @ ...] Noise floor dB: -32.266999
[Parsed_astats_0 @ ...] Noise floor count: 422
[Parsed_astats_0 @ ...] Entropy: 0.779411
[Parsed_astats_0 @ ...] Bit depth: 30/32/32/32
[Parsed_astats_0 @ ...] Dynamic range: 136.555299
...
[Parsed_astats_0 @ ...] Overall
...
Values whose names end in dB are in dBFS (decibels relative to full scale): 0 dBFS is full scale, and quieter levels are negative. RMS is a kind of average level.
| Field | Meaning |
|---|---|
DC offset |
How far the waveform is shifted away from zero (closer to 0 is better) |
Peak level dB |
Highest sample level (dBFS) |
RMS level dB |
Average (RMS) level over the whole file (dBFS) |
RMS peak dB |
Highest RMS level |
RMS through dB |
Lowest RMS level (printed as RMS trough dB up to FFmpeg 7.1) |
Crest factor |
Ratio of the peak level to the RMS level |
Flat factor |
How flat the signal stays at Min level or Max level (runs of identical samples); helps detect clipping |
Peak count |
How many times the signal reached Min level or Max level; above zero even when nothing clips |
Dynamic range |
Dynamic range (dB) |
Filtering Which Measurements Are Reported
measure_perchannel and measure_overall choose which fields are printed.
Show RMS and peak level only
ffmpeg -i input.mp4 -af "astats=measure_perchannel=RMS_level+Peak_level:measure_overall=RMS_level+Peak_level" -f null /dev/null
Overall statistics only (skip per-channel)
ffmpeg -i input.mp4 -af "astats=measure_perchannel=0" -f null /dev/null
Emitting Results as Metadata
With metadata=1, astats attaches its statistics to every audio frame as metadata. Each value covers the audio from the start up to that frame; use reset to get values for shorter intervals. The ametadata filter prints the values:
ffmpeg -i input.mp4 -af "astats=metadata=1,ametadata=print:file=-" -f null /dev/null 2>&1 | head -50
Segment-by-Segment Statistics (reset Parameter)
reset=N clears the statistics every N frames, not every N samples. (A decoded AAC frame holds 1024 samples.) The summary at the end of the log then covers only the audio since the last reset. To see one value per interval, combine metadata=1 with ametadata:
ffmpeg -i input.mp4 -af "asetnsamples=n=44100,astats=metadata=1:reset=1,ametadata=print:key=lavfi.astats.Overall.RMS_level:file=-" -f null /dev/null
asetnsamples regroups the audio into frames of 44,100 samples, and reset=1 starts over on every frame. At 44.1 kHz that prints one RMS value per second, so you can see how the level changes over time.
astats vs. volumedetect
| Filter | Primary use | Output |
|---|---|---|
astats |
Detailed audio quality diagnosis | RMS, peak, DC offset, dynamic range, and more |
volumedetect |
Quick volume sanity check | mean_volume, max_volume, histogram |
Use astats for a detailed check. For a quick look at the volume, volumedetect is enough:
ffmpeg -i input.mp4 -af "volumedetect" -f null /dev/null
Detecting Clipping
If Peak level dB is 0 dB (full scale) or higher, the audio may be clipping. In uncompressed audio such as WAV, a peak clipped flat over several samples in a row gives a Flat factor above 0. Light clipping that cuts only one sample per peak leaves it at 0, so a Flat factor of 0 does not rule out clipping. Peak count does not show clipping: it is above zero for any signal, clipped or not.
ffmpeg -i input.mp4 -af "astats=measure_perchannel=Peak_level+Flat_factor:measure_overall=Peak_level+Flat_factor" -f null /dev/null
In volumedetect, max_volume: 0.0 dB also means the audio reaches full scale. -0.0 dB can also appear when the peak is just below full scale. If the audio clips, fix the level at the source or in the step that raised it. Turning it down afterwards with the volume filter does not repair clipping that is already in the file.
Checking and Fixing DC Offset
Check the DC offset value with astats first. If it is large, remove it with the highpass filter:
ffmpeg -i input.mp4 -c:v copy -af "highpass=f=10" output.mp4
Audio Quality Check Workflow
- Run
astatsand check the RMS level, peak level, DC offset and signs of clipping. - If the audio clips, fix the recording level or the step that raised the level.
- If the DC offset is large, remove it with the
highpassfilter. - If the RMS level is uneven across the material, normalize it with the
loudnormfilter.
Frequently Asked Questions
What is the difference between astats and ebur128?
astats reports peak level, RMS level, DC offset and crest factor for the whole stream in its log. It gives per-frame values only with metadata=1, and each of those covers the audio from the start unless you set reset. ebur128 measures loudness in LUFS, the unit broadcast standards use. Use astats to diagnose the waveform and ebur128 to hit a loudness target for delivery.
How do I get only the peak level?
Print only that metadata key with ffprobe: ffprobe -f lavfi -i "amovie=in.wav,astats=metadata=1:reset=0" -show_entries frame_tags=lavfi.astats.Overall.Peak_level -of csv=p=0. It prints one line per frame, and the last line is the peak of the whole file.
Can astats detect silence?
Only indirectly: where the RMS level drops below your threshold (for example -60 dB), that part is silent. For real silence detection, use the silencedetect filter.
Why does astats report different numbers per channel?
It measures each channel separately. A stereo file with sound only in the left channel shows a peak of -inf dB on the right. The combined values are printed under Overall.
Can I run astats on a video file?
Yes. FFmpeg picks the audio stream automatically. If the video has several audio tracks, choose one with -map 0:a:0 (the first audio track).
Related Articles
- Volume Detection and Adjustment (volumedetect / volume)
- Loudness Normalization (loudnorm / LUFS)
- Reading Video and Audio Metadata with ffprobe
Primary source: ffmpeg.org/ffmpeg-filters.html#astats