Add an audio waveform visualizer to a video using FFmpeg and Editframe (Updated)
Published on July 5, 2023
Last updated on September 25, 2024
6 min read
If you, like many people, first encountered audio visualizers in the late aughts or early 2010s when Apple’s iTunes brought them to the world, there will always be a special place in your heart for this wonder of audio technology. Perhaps you spent hours transfixed by the undulating hues that Radiohead’s OK Computer produced on your laptop screen. Maybe you projected these hypnotic waves on your dorm room wall to set a mood for your Friday night pregame. Are these anecdotes are too specific to be relatable? Maybe, though given that you’re currently reading technical content on a video infrastructure platform’s docs site, we’re willing to go out on that limb.
Suffice it to say, audio visualizers ruled back in 2008, and in 2023… they’re still total rad. And what’s even cooler, you ask? Adding audio visualizers a video, that’s what. Embedding a visual element that responds to the audio in a video file will help your viewers follow your music or audio easier, and bring another interesting dimension to your content.
Many online videos (think slideshows, product videos, or podcast recordings) are static and repetitive, and fail to deliver any visual stimulation to the viewer. Adding a waveform that responds to the audio track is an easy way to bring this much-needed dimension to your video content, and quickly up the ante with your video game.
In this tutorial, we will show you how to quickly add a waveform to your videos using two methods, FFmpeg and Editframe.
Let’s get started!
Part 1: Using FFmpeg
First, we’ll walk through the process of adjusting saturation, brightness, and contrast with FFmpeg.
Required Tools
- Sample video files: provided by pexels.com(opens in a new tab)
- FFmpeg(opens in a new tab): (You’ll need to install FFmpeg and set up the appropriate environment variables before beginning this tutorial)
Download the required assets
Here is a sample video file provided by pexels.com(opens in a new tab) and music by pixabay.com(opens in a new tab) to use in this tutorial:
video.mp4
Using FFmpeg’s filter complex
Here’s the FFmpeg command to add an audio waveform to a video file:
ffmpeg -i video.mp4 \
-filter_complex "[0:a]showwaves=s=1080x200:colors=White\
:mode=line,format=yuv420p[v];\
[0:v][v]overlay=(W-w)/2:H-h[outv]" \
-map "[outv]" -pix_fmt yuv420p -map 0:a \
-c:v libx264 -c:a copy waveform.mp4
Let’s break down what this code is doing.
- In this line, we will import the video.mp4 video file:
ffmpeg -i video.mp4 \
- Here, we set the audio waveform mode to line, set the video format to
yuv420p
, and set the audio waveform part to[v]
variable:
:mode=line,format=yuv420p[v];\
- In this line, we add the audio waveform
[v]
to the video[0:v]
, set the position of x to center(W-w)/2
, and y to the bottom(H-h)
of the video. Additionally, we set this composition to[outv]
variable:
[0:v][v]overlay=(W-w)/2:H-h[outv]" \
- In this line, we map over the
[outv]
composition and first video input audio stream:
-map "[outv]" -pix_fmt yuv420p -map 0:a \
- Here, we copy the audio and video streams into waveform.mp4 video output.
-c:v libx264 -c:a copy waveform.mp4
Here’s the output video using this FFmpeg command:
waveform.mp4
Part 2: Using Editframe
Now we’ll perform the same color grading operations again, only this time we will use Editframe instead of FFmpeg.
Required tools:
- Node.js installed on your machine
- No need to have FFmpeg installed on your machine
- Editframe API Token (you can create an account from this link(opens in a new tab))
Let’s get started:
- Setup a new Node.js project using the Editframe CLI:
npx @editframe/create@beta
- Install the required dependencies:
cd add-waveform && npm install
- Add assets to the project:
Add video.mp4
to the src/assets
folder.
- Update the
index.html
file with the following code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script type="module" src="./src/index.js"></script>
<link rel="stylesheet" href="./src/styles.css" />
</head>
<body>
<ef-timegroup mode="sequence" class="w-[1080px] h-[1920px] relative">
<ef-timegroup mode="contain">
<ef-video id="video" class="w-full h-full object-cover" src="/assets/audio.mp4"></ef-video>
<ef-waveform mode="bars" class="h-[200px] w-full bg-black fill-white absolute bottom-0 z-10" target="video"></ef-waveform>
</ef-timegroup>
</ef-timegroup>
</body>
</html>
Let’s walk through what the code in this file is doing.
- In these lines, we import the
index.js
file and thestyles.css
file which contains the styles for the video and@editframe/elements
:
<head>
<meta charset="UTF-8" />
<script type="module" src="./src/index.js"></script>
<link rel="stylesheet" href="./src/styles.css" />
</head>
- In this line, we create a new video composition using the
ef-timegroup
element. A vertical video (9:16) with a height of 1920px and a width of 1080px:
<ef-timegroup
mode="sequence"
class="w-[1080px] h-[1920px] relative"
>
{ /* Add elements here */ }
</ef-timegroup>
- In these lines, we set a new time group with a mode of
contain
to add the video and waveform elements:
<ef-timegroup mode="contain">
{ /* Add elements here */ }
</ef-timegroup>
- In these lines, we import the video and waveform elements:
<ef-video id="video" class="w-full h-full object-cover" src="/assets/audio.mp4"></ef-video>
<ef-waveform mode="bars" class="h-[200px] w-full bg-black fill-white absolute bottom-0 z-10" target="video"></ef-waveform>
-
ef-video
is an Editframe element that allows you to add videos to your video composition. -
ef-waveform
is an Editframe element that allows you to add audio to your video. -
Preview the project:
npx vite .
- Update the
.env
file with your Editframe API token:
EF_TOKEN="YOUR_API_TOKEN"
- Render the video:
npx @editframe/cli render .
Boom! Here’s the output video from the Editframe API:
ediframe-waveform.mp4
Here’s the video comparison between using Editframe and FFmpeg:
compare.mp4
Note: You can add transitions, filters, trim videos, and more. You can learn more here in the Editframe API docs.