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.
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.
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.
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:
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.
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.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:
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
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
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
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
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
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
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.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:
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.
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
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.
curl --request POST 'https://api.shotstack.io/v1/render' \
--header 'x-api-key: YOUR_API_KEY' \
--data-raw '{
"timeline": {
"tracks": [
{
"clips": [
{
"asset": {
"type": "video",
"src": "https://shotstack-assets.s3.amazonaws.com/footage/beach-overhead.mp4"
},
"start": 0,
"length": "auto"
}
]
}
]
},
"output": {
"format": "mp4",
"size": {
"width": 1280,
"height": 720
}
}
}'