Skip to content

Instantly share code, notes, and snippets.

@cadrev
Forked from mixxorz/waveform.py
Created October 30, 2015 16:07
Show Gist options
  • Save cadrev/65ee8d1e35cc443e77d4 to your computer and use it in GitHub Desktop.
Save cadrev/65ee8d1e35cc443e77d4 to your computer and use it in GitHub Desktop.
Generate waveform images from audio files
# Requires pydub (with ffmpeg) and Pillow
#
# Usage: python waveform.py <audio_file>
import sys
from pydub import AudioSegment
from PIL import Image, ImageDraw
class Waveform(object):
bar_count = 107
db_ceiling = 60
def __init__(self, filename):
self.filename = filename
audio_file = AudioSegment.from_file(filename, filename.split('.')[-1])
self.peaks = self._calculate_peaks(audio_file)
def _calculate_peaks(self, audio_file):
""" Returns a list of audio level peaks """
chunk_length = len(audio_file) / self.bar_count
loudness_of_chunks = [
audio_file[i * chunk_length: (i + 1) * chunk_length].rms
for i in range(self.bar_count)]
max_rms = max(loudness_of_chunks) * 1.00
return [int((loudness / max_rms) * self.db_ceiling)
for loudness in loudness_of_chunks]
def _get_bar_image(self, size, fill):
""" Returns an image of a bar. """
width, height = size
bar = Image.new('RGBA', size, fill)
end = Image.new('RGBA', (width, 2), fill)
draw = ImageDraw.Draw(end)
draw.point([(0, 0), (3, 0)], fill='#c1c1c1')
draw.point([(0, 1), (3, 1), (1, 0), (2, 0)], fill='#555555')
bar.paste(end, (0, 0))
bar.paste(end.rotate(180), (0, height - 2))
return bar
def _generate_waveform_image(self):
""" Returns the full waveform image """
im = Image.new('RGB', (840, 128), '#f5f5f5')
for index, value in enumerate(self.peaks, start=0):
column = index * 8 + 2
upper_endpoint = 64 - value
im.paste(self._get_bar_image((4, value * 2), '#424242'),
(column, upper_endpoint))
return im
def save(self):
""" Save the waveform as an image """
png_filename = filename.replace(filename.split('.')[-1], 'png')
with open(png_filename, 'w') as imfile:
self._generate_waveform_image().save(imfile, 'PNG')
if __name__ == '__main__':
filename = sys.argv[1]
waveform = Waveform(filename)
waveform.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment