Drawing good looking Waveforms on the web
A small exploration for creating waveform vizualization on the web, simple and raw
After starting a small project that had and audio component i wanted to show some representation of it. So how do you visualize audio ? Decided to look at products that have any sort of audio visualizations and found 2 distinct types of looks:
Well doesn’t seem like a complex task so what about libraries that help us achieve the task at hand. The Soundcloud is really stylized and also a web solution, but searching for what are they using i stumbled on Waveform.js (). Now at first hand its an easy to use solution and even supports streaming waveform data only one thing doesnt seem right
Well it seems like Soundcloud is not using it anymore so how do we really replicate the same type of audio visualization. One interesting note here is that they made an article about that some years age showing the aforementioned library. First thing thats important to be aware that our audio file contains alot of samples. For my specific purpose i had audio with length between 1 hours and a maximum of 24 hours so that is probably too big to use all the samples for the visualizations. So next thing we have to do is decide what samples are we gonna leave and what samples we want do discard, but keep the shape of the waveform almost intact. We can use some audio specific technique for downsampling, but if we are not really thinking about accuracy a simple selection of the maximum value is enough.
Getting Samples One of the best tools to get the audio samples from either video or some audio container format is ffmpeg. I know that there are more capable tools specific for audio format manipulation, but this will do the job for now. ffmpeg -i <audio/video_file> -ac 1 -ar 44100 -c:a pcm_s16le -f s16le pipe: ac allows us to choose how many channels we want ar is the sample rate of our output, should be the same as the input file the other options -c:a pcm_s16le -f s16le define how the output will be formatted We chose to use pcm format because its just raw samples no headers no extra metadata. Choosing a proper format of what you want to parse is essential, in this case I use signed 16-bit Little Endian. All the other formats you can see here https://trac.ffmpeg.org/wiki/audio%20types. After we have the proper format we just need to parse it in parts because there is no need to save the whole file.
https://gist.github.com/Bloodb0ne/706254db1f7b5baabf6cb86f0142f939#file-test_pcm-js
This is a sample snippet in Node.js to fetch and reduce the samples from a spawned ffmpeg process. First we estimate the amount of samples we get from a file with a certain size based on sample rate and duration of the audio. Using this size we can now fill a bucket with samples and get the maximum value for each bucket and that will be our final output sample. Now that we have our final result of 1800 samples of audio its time to display them. Using
Bonus( coloring a region of the waveform) In the example code below we have the function drawOverlay that just draws a rectangle over our waveform but we use a composition operation “source-atop” so we use the waveform as a mask. You can learn more on composition operation on the MDN ( https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation ).
https://gist.github.com/Bloodb0ne/419c5314b691816b20ecd74554b28c3b#file-waveform-html