Cloudinary Blog

How to generate waveform images from audio files

How to generate waveform images from audio files

Many social networks, websites and messaging applications allow users to upload a wide variety of media files, and although the majority of files are in the form of images and video clips, a significant minority are audio files. When the website or application subsequently needs to display a thumbnail that describes the uploaded content, images can be cropped and resized down to scale, and a single frame from a video clip can be converted to an image and then also cropped and resized down to scale.

So what do you display when you need something to uniquely and visually represent an audio file? A useful solution is to display a waveform image, which is a visual representation of the audio file and is presented as a graph of the sound amplitude against time.

Creating waveform images

Cloudinary's media management service has support for uploading, manipulating and managing all kinds of media files, including images, videos and audio files. You can create waveform thumbnails of audio files just as easily as you can create thumbnails for images and videos, with fine control over the look & feel of the generated waveform image to match your graphic design and the responsive layouts of all devices and browsers. All the audio processing, image generation and manipulation takes place on-the-fly and in the cloud using dynamic URLs, and with no need to install any complex software.

Creating an image waveform from an audio file uploaded to your Cloudinary account is as simple as changing the file extension (format) of the Cloudinary audio delivery URL to an image format like PNG, and enabling the waveform flag (fl_waveform in URLs). By default, the resulting waveform image is delivered with a high resolution, so you will also want to scale down the resulting image.

For example, to generate a PNG waveform image of the bumblebee.mp3 audio file uploaded to Cloudinary's demo account, scaled to a height of 200 pixels and a width of 500 pixels:

Ruby:
Copy to clipboard
cl_image_tag("bumblebee.png", :height=>200, :width=>500, :flags=>"waveform", :resource_type=>"video")
PHP v1:
Copy to clipboard
cl_image_tag("bumblebee.png", array("height"=>200, "width"=>500, "flags"=>"waveform", "resource_type"=>"video"))
PHP v2:
Copy to clipboard
(new ImageTag('bumblebee.png'))
  ->resize(Resize::scale()->width(500)->height(200))
  ->addFlag(Flag::waveform())
  ->assetType(AssetType::VIDEO);
Python:
Copy to clipboard
CloudinaryVideo("bumblebee.png").image(height=200, width=500, flags="waveform")
Node.js:
Copy to clipboard
cloudinary.image("bumblebee.png", {height: 200, width: 500, flags: "waveform", resource_type: "video"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().height(200).width(500).flags("waveform")).resourceType("video").imageTag("bumblebee.png");
JS:
Copy to clipboard
cloudinary.videoTag('bumblebee.png', {height: 200, width: 500, flags: "waveform"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("bumblebee.png", {height: 200, width: 500, flags: "waveform", resource_type: "video"})
React:
Copy to clipboard
<Video publicId="bumblebee.png" resourceType="video">
  <Transformation height="200" width="500" flags="waveform" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="bumblebee.png" resourceType="video">
  <cld-transformation height="200" width="500" flags="waveform" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="bumblebee.png" resource-type="video">
  <cl-transformation height="200" width="500" flags="waveform">
  </cl-transformation>
</cl-video>
.NET:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Height(200).Width(500).Flags("waveform")).BuildImageTag("bumblebee.png")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().height(200).width(500).flags("waveform")).resourceType("video").generate("bumblebee.png");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setHeight(200).setWidth(500).setFlags("waveform")).generate("bumblebee.png")
Audio waveform image of 500x200

Note that as well as generating waveform images from audio files, you can also generate waveform images from the audio track of a video file in the same way as described above: simply change the file extension of a Cloudinary video URL to an image format like PNG, and enable the waveform flag (fl_waveform in URLs).

Customizing the waveform image

You can also control the colors used in the waveform image with the color parameter (co in URLs) to set the color for the waveform (default white) and the background parameter (b in URLs) to set the background color of the image (default black).

For example, to generate the same PNG waveform image of the bumblebee.mp3 audio file in the example above in inverted colors - with the waveform rendered in black on a white background:

Ruby:
Copy to clipboard
cl_image_tag("bumblebee.png", :height=>200, :width=>500, :flags=>"waveform", :color=>"black", :background=>"white", :resource_type=>"video")
PHP v1:
Copy to clipboard
cl_image_tag("bumblebee.png", array("height"=>200, "width"=>500, "flags"=>"waveform", "color"=>"black", "background"=>"white", "resource_type"=>"video"))
PHP v2:
Copy to clipboard
(new ImageTag('bumblebee.png'))
  ->resize(Resize::scale()->width(500)->height(200))
  ->backgroundColor(Color::WHITE)->color(Color::BLACK)
  ->addFlag(Flag::waveform())
  ->assetType(AssetType::VIDEO);
Python:
Copy to clipboard
CloudinaryVideo("bumblebee.png").image(height=200, width=500, flags="waveform", color="black", background="white")
Node.js:
Copy to clipboard
cloudinary.image("bumblebee.png", {height: 200, width: 500, flags: "waveform", color: "black", background: "white", resource_type: "video"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().height(200).width(500).flags("waveform").color("black").background("white")).resourceType("video").imageTag("bumblebee.png");
JS:
Copy to clipboard
cloudinary.videoTag('bumblebee.png', {height: 200, width: 500, flags: "waveform", color: "black", background: "white"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("bumblebee.png", {height: 200, width: 500, flags: "waveform", color: "black", background: "white", resource_type: "video"})
React:
Copy to clipboard
<Video publicId="bumblebee.png" resourceType="video">
  <Transformation height="200" width="500" flags="waveform" color="black" background="white" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="bumblebee.png" resourceType="video">
  <cld-transformation height="200" width="500" flags="waveform" color="black" background="white" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="bumblebee.png" resource-type="video">
  <cl-transformation height="200" width="500" flags="waveform" color="black" background="white">
  </cl-transformation>
</cl-video>
.NET:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Height(200).Width(500).Flags("waveform").Color("black").Background("white")).BuildImageTag("bumblebee.png")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().height(200).width(500).flags("waveform").color("black").background("white")).resourceType("video").generate("bumblebee.png");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setHeight(200).setWidth(500).setFlags("waveform").setColor("black").setBackground("white")).generate("bumblebee.png")
Black on white waveform image

If you only want to capture the waveform of a specific segment of the audio file, you can use a combination of the following 3 parameters to specify the section of the audio file to sample for the waveform:

  • start_offset (so in URLs) specifies the start of the sample.
  • end_offset (eo in URLs) specifies the end of the sample.
  • duration (du in URLs) specifies the duration of the sample.

For example, to display a PNG waveform image of a sample from the 2 second mark until the 4 second mark of the bumblebee.mp3 audio file uploaded to Cloudinary's demo account, scaled to a height of 250 pixels and a width of 400 pixels, with the waveform rendered in blue on a green background:

Ruby:
Copy to clipboard
cl_image_tag("bumblebee.png", :height=>250, :width=>400, :flags=>"waveform", :start_offset=>"2", :end_offset=>"4", :color=>"blue", :background=>"#02b30a", :resource_type=>"video")
PHP v1:
Copy to clipboard
cl_image_tag("bumblebee.png", array("height"=>250, "width"=>400, "flags"=>"waveform", "start_offset"=>"2", "end_offset"=>"4", "color"=>"blue", "background"=>"#02b30a", "resource_type"=>"video"))
PHP v2:
Copy to clipboard
(new ImageTag('bumblebee.png'))
  ->videoEdit(VideoEdit::trim()->startOffset(2)->endOffset(4))
  ->resize(Resize::scale()->width(400)->height(250))
  ->backgroundColor(Color::rgb('02b30a'))
  ->color(Color::BLUE)->addFlag(Flag::waveform())
  ->assetType(AssetType::VIDEO);
Python:
Copy to clipboard
CloudinaryVideo("bumblebee.png").image(height=250, width=400, flags="waveform", start_offset="2", end_offset="4", color="blue", background="#02b30a")
Node.js:
Copy to clipboard
cloudinary.image("bumblebee.png", {height: 250, width: 400, flags: "waveform", start_offset: "2", end_offset: "4", color: "blue", background: "#02b30a", resource_type: "video"})
Java:
Copy to clipboard
cloudinary.url().transformation(new Transformation().height(250).width(400).flags("waveform").startOffset("2").endOffset("4").color("blue").background("#02b30a")).resourceType("video").imageTag("bumblebee.png");
JS:
Copy to clipboard
cloudinary.videoTag('bumblebee.png', {height: 250, width: 400, flags: "waveform", startOffset: "2", endOffset: "4", color: "blue", background: "#02b30a"}).toHtml();
jQuery:
Copy to clipboard
$.cloudinary.image("bumblebee.png", {height: 250, width: 400, flags: "waveform", start_offset: "2", end_offset: "4", color: "blue", background: "#02b30a", resource_type: "video"})
React:
Copy to clipboard
<Video publicId="bumblebee.png" resourceType="video">
  <Transformation height="250" width="400" flags="waveform" startOffset="2" endOffset="4" color="blue" background="#02b30a" />
</Video>
Vue.js:
Copy to clipboard
<cld-video publicId="bumblebee.png" resourceType="video">
  <cld-transformation height="250" width="400" flags="waveform" startOffset="2" endOffset="4" color="blue" background="#02b30a" />
</cld-video>
Angular:
Copy to clipboard
<cl-video public-id="bumblebee.png" resource-type="video">
  <cl-transformation height="250" width="400" flags="waveform" start-offset="2" end-offset="4" color="blue" background="#02b30a">
  </cl-transformation>
</cl-video>
.NET:
Copy to clipboard
cloudinary.Api.UrlVideoUp.Transform(new Transformation().Height(250).Width(400).Flags("waveform").StartOffset("2").EndOffset("4").Color("blue").Background("#02b30a")).BuildImageTag("bumblebee.png")
Android:
Copy to clipboard
MediaManager.get().url().transformation(new Transformation().height(250).width(400).flags("waveform").startOffset("2").endOffset("4").color("blue").background("#02b30a")).resourceType("video").generate("bumblebee.png");
iOS:
Copy to clipboard
cloudinary.createUrl().setResourceType("video").setTransformation(CLDTransformation().setHeight(250).setWidth(400).setFlags("waveform").setStartOffset("2").setEndOffset("4").setColor("blue").setBackground("#02b30a")).generate("bumblebee.png")
Waveform of a partial audio cut with color customization

Visualization of uploaded audio files made simple

Waveform images are a nice way to visualize audio files, and are useful for user generated content, social networks and social messaging apps. With Cloudinary you can easily generate images of the waveforms of audio files, with the images generated on-the-fly using dynamic delivery URLs and delivered optimized via a fast CDN. The generated image thumbnails for audio, as well as image and video files, can be further manipulated to match any graphic design and any responsive layout, just like any other image uploaded to Cloudinary.

Full audio support including upload, manipulation, streaming and waveform generation is available in all Cloudinary's plans, including the free tier. Try it yourself by opening a free account.

Recent Blog Posts

Generate Waveform Images from Audio with Cloudinary

This is a reposting of an article written by David Walsh. Check out his blog HERE!
I've been working a lot with visualizations lately, which is a far cry from your normal webpage element interaction coding; you need advanced geometry knowledge, render and performance knowledge, and much more. It's been a great learning experience but it can be challenging and isn't always an interest of all web developers. That's why we use apps and services specializing in complex tasks like Cloudinary: we need it done quickly and by a tool written by an expert.

Read more
Make All Images on Your Website Responsive in 3 Easy Steps

Images are crucial to website performance, but most still don't implement responsive images. It’s not just about fitting an image on the screen, but also making the the image size relatively rational to the device. The srcset and sizes options, which are your best hit are hard to implement. Cloudinary provides an easier way, which we will discuss in this article.

Read more

The Future of Audio and Video on the Web

By Prosper Otemuyiwa
The Future of Audio and Video on the Web

Web sites and platforms are becoming increasingly media-rich. Today, approximately 62 percent of internet traffic is made up of images, with audio and video constituting a growing percentage of the bytes.

Read more

Embed Images in Email Campaigns at Scale

By Sourav Kundu
Embed Images in Email Campaigns at Scale

tl;dr

Cloudinary is a powerful image hosting solution for email marketing campaigns of any size. With features such as advanced image optimization and on-the-fly image transformation, backed by a global CDN, Cloudinary provides the base for a seamless user experience in your email campaigns leading to increased conversion and performance.

Read more
Build the Back-End For Your Own Instagram-style App with Cloudinary

Github Repo

Managing media files (processing, storage and manipulation) is one of the biggest challenges we encounter as practical developers. These challenges include:

A great service called Cloudinary can help us overcome many of these challenges. Together with Cloudinary, let's work on solutions to these challenges and hopefully have a simpler mental model towards media management.

Read more

Build A Miniflix in 10 Minutes

By Prosper Otemuyiwa
Build A Miniflix in 10 Minutes

Developers are constantly faced with challenges of building complex products every single day. And there are constraints on the time needed to build out the features of these products.

Engineering and Product managers want to beat deadlines for projects daily. CEOs want to roll out new products as fast as possible. Entrepreneurs need their MVPs like yesterday. With this in mind, what should developers do?

Read more