Generate audio waveform videos using FFmpeg

Audio waveforms, or audiograms, are a visual representation of sound displayed as a video. It is very common to see a podcast video or podcast ad on social media that includes an animated waveform to make the video more visually appealing and add animation to an otherwise static scene.

In this tutorial, you will learn how to create the kind of waveform videos you might see in a podcast video using a tool called FFmpeg.

About FFmpeg

FFmpeg is a free and open-source command line tool for manipulating video, audio, and other forms of multimedia. You can use it for tasks such as file conversion, editing, transcoding, and more. Its versatile nature makes it a popular choice among developers and audio-visual engineers.

Install FFmpeg

To follow along with this guide and generate waveforms, you'll need to have FFmpeg installed on your computer. First, run the command below to check if it is already installed.

ffmpeg --version

You should see a version number and build information if it's installed.

If not, visit the official FFmpeg download page, select the appropriate version for your operating system, and follow the installation instructions.

Usually, it will include downloading the FFmpeg package, extracting its contents, and adding the FFmpeg executable's folder to your system's PATH.

The FFmpeg waveform command

For this demo we will use the following audio which you should download and save on your hard drive as input.mp3.

Once downloaded, open your terminal and navigate to the directory with the audio file and run the following FFmpeg command:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

You should see output from the command as FFmpeg processes the audio file and generates a video file called output.mp4. Here is the resulting waveform video:

How filter-complex and showwaves filter work

The command has several parameters that work together to generate the waveform. The most important part is the -filter_complex parameter and the showwaves=size=854x480:colors=white value. The FFmpeg -filter_complex parameter allows you to apply multiple filters to the media file.

In this case we use the showwaves filter to generate the waveform. The showwaves filter has several options that allow you to customize the waveform, such as size, colours, and style. In this example we set the size to 854x480 pixels and the color to white.

The compand filter is used to compress and expand the waveform to fill the video frame. The format=yuv420p parameter is used to set the pixel format to yuv420p which is compatible with most video players.

[0:a] is the input audio stream input and [vout] is the output video stream.

Breakdown of the remaining parameters

The command has several other parameters that are worth mentioning:

  • -i input.mp3 tells FFmpeg the audio file we want to use to generate the waveform.
  • -r 25 sets the frame rate to 25 frames per second (fps) for the output video.
  • -map "[vout]" maps the output video stream to the output file.
  • -map 0:a maps the input audio stream to the output file.
  • -c:v libx264 specifies the video codec to use for the output file. In this case, we use the H.264 (mp4) codec.
  • -c:a copy copies the audio stream from the input file to the output file without re-encoding it.
  • output.mp4 specifies the name of the output video file.

How to style the waveform appearance

In the previous example we generated a basic waveform. You can customize the waveform's appearance by changing the parameters of the showwaves filter. Here are some common parameters you can adjust:

Draw parameter

The draw option can be set to full or scale and controls how samples are drawn in the waveform. The default value is scale which scales pixels for each drawn sample. The full option draws every sample directly. When using full the waveform appears more bold and easier to see.

Here is the same command but using the draw parameter set to full:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white:draw=full,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Mode parameter

The mode parameter controls the style of the waveform. The default value is point which draws individual sample points without connecting them with lines. Other available modes include line, cline, and p2p.

Building on our previous command, here is an example using the line mode:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white:draw=full:mode=line,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Using cline mode:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white:draw=full:mode=cline,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

And finally, using p2p mode:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white:draw=full:mode=p2p,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Scale parameter

The scale parameter adjusts the waveform amplitudes which affects the peaks and troughs of the waveform. The default value is lin for linear. Other available values include log (logarithmic), sqrt (square root) and cbrt (cubic root).

Continuing from the last command, here is an example using the log scale:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white:draw=full:mode=p2p:scale=log,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Using the sqrt scale:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white:draw=full:mode=p2p:scale=sqrt,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

And using the cbrt scale:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=white:draw=full:mode=p2p:scale=cbrt,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Colours parameter

So far all our waveforms have been white. You can set the waveform colour to any colour you like. You can use built-in FFmpeg colour names like white, red or blue. The available colour names are listed in the FFmpeg colour guide.

You can also use HTML style, hex colours like 0x25d3d0 or #25d3d0. Depending on your version of FFmpeg you can also add transparency to the colour using @ followed by a value between 0 and 1. For example, 0x25d3d0@0.3 sets the colour to 30% opacity. Or by appending an alpha setting to the end of the hex code, like this 0x25d3d0CC.

Here is an example using the Shotstack accent colour #25d3d0:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=#25d3d0:draw=full:mode=line,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Multiple colours

You can also use multiple colours by separating them with the pipe | symbol. For example, colors=blue|yellow would create a waveform with the colours blue and yellow.

Multiple waveform colours works better with different types of audio, for example, music files. Here is an example using the Shotstack accent colour, a complimentary purple colour #7925d3 and a music file:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=#25d3d0|#7925d3:draw=full:mode=line,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Size parameter

You can adjust the size of the waveform using the size parameter. This will also determine the output size of the video unless you use on of the other FFmpeg parameters to crop and resize the video.

Our original video was 854x480 pixels. Here is an example to create a small square video that is 400px by 400px:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=400x400:colors=#25d3d0:draw=full:mode=line,format=yuv420p[vout]" -map "[vout]" -map 0:a -c:v libx264 -c:a copy output.mp4

Backgrounds colour

All the waveform videos so far have a black background. It is possible to change the background colour using the following command:

ffmpeg -i input.mp3 -f lavfi -i color=c=#7925d3:s=854x480 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=#25d3d0:draw=full:mode=line[vout];[1:v][vout]overlay=format=auto:shortest=1,format=yuv420p[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy output.mp4 

In this example we have added the following:

  • -f lavfi -i color=c=#7925d3:s=854x480 use a single filter and the creates a solid colour background. The c parameter is the colour in hex format and the s parameter is the size of the video. The size of the solid colour should match the size of the waveform video.
  • [1:v][vout]overlay=format=auto:shortest=1,format=yuv420p[v] overlays the waveform output on the background colour using the overlay filter. The [1:v][vout] and [v] notation controls how the filters are chained together.
  • The shortest=1 parameter ensures the output video is the same length as the shortest input stream, i.e. the waveform video (the background colour would play forever if not set to the shortest input stream).

Here is how the final video looks:

Transparent backgrounds

In a real world scenario, it is common to overlay the waveform on top of an image or anther video. To do this you would need to create a video with a transparent background. This is not possible with the H.264 codec we have been using.

Instead you need to use the QuickTime Animation codec -c:v qtrle, argb pixel format, and save the video as a .mov file. The QuickTime Animation codec supports alpha transparent backgrounds.

Here is an example command to create a waveform video with a transparent background:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=#25d3d0:draw=full:mode=line,format=argb[vout]" -map "[vout]" -map 0:a -c:v qtrle -c:a copy output.mov

The output video will be a .mov file with a transparent background. You can overlay this video on top of other videos or images in your video editing software.

Removing the audio

It is also possible that you will want to seperate the audio and not include it with the waveform video. To do that you can simply remove the -map 0:a -c:a copy parameters from the command. Here is an example:

ffmpeg -i input.mp3 -r 25 -filter_complex "[0:a]compand,showwaves=size=854x480:colors=#25d3d0:draw=full:mode=line,format=argb[vout]" -map "[vout]" -map 0:a -c:v qtrle output.mov

Conclusion

This guide covered the key features of the FFmpeg showwaves filter and how to create waveform videos from audio files. You learned how to customize the waveform appearance by adjusting parameters such as draw, mode, scale, colours, size, and backgrounds. You also learned how to create waveform videos with transparent backgrounds and how to remove the audio from the output video.

There are a few more options you can explore for the FFmpeg showwaves filter including n and split_channels. There are hundreds of different ways you could combine all these settings to create all sorts of waveform patterns to bring your videos to life.

Jeff Shillitto

BY JEFF SHILLITTO
22nd March, 2024

Become an Automated Video Editing Pro

Every month we share articles like this one to keep you up to speed with automated video editing.


You might also like

How to use FFmpeg (with examples)

How to use FFmpeg (with examples)

Andrew Bone
 Convert videos to MP3 using FFmpeg

Convert videos to MP3 using FFmpeg

Jeff Shillitto