How to make realtime SoundCloud Waveforms in React Native
SoundCloud is a music and podcast streaming platform for listening to millions of authentic tracks. They have a really interactive interface for playing / listening to the tracks. The most important feature in their interface is showing the progress of the track based on its frequency waveform. This helps the users to identify the nature of it. They also have a blog post which describes how to use the waveform based on its image. It is hard to use the same techniques to generate the waveform in a React Native app. Their Waveform.js SDK translates a waveform into floating points to render on an HTML5 canvas and is currently no longer operational. In this article we’ll discuss how to use the same waveform for our React Native apps.
Why Should I use SoundCloud’s Waveforms?
- The SoundCloud’s waveform looks more impressive than the old boring way of showing the progress bar.
- The pre-loaded waveform will give the user an idea of the different frequencies present in the song.
- It is also much easier to show the buffered track percentage on a waveform rather than showing it on a blank progress bar.
Let’s learn more about SoundCloud’s Waveforms
The SoundCloud provides a
waveform_url in its tracks API.
- Each track has its own unique
waveform_urlcontains a link to the image hoisted over the cloud.
Example — https://w1.sndcdn.com/PP3Eb34ToNki_m.png
As of now, every argument is static hence it is unusable in this current state. Therefore we need to re-create the waveform based on it using React Native’s *containers* in order to have access to the touch events, styles etc.
Here is a list of stuff that you will need:
First, we need the sampling of the waveform. The trick is to replace
.json for the
waveform_url . A
GET call to it would give us a response
object that contains
- width (Width of the waveform)
- height (Height of the waveform)
- samples (Array)
For more info, you can try out the following link https://w1.sndcdn.com/PP3Eb34ToNki_m.json.
Dive into the code
Add a Custom SoundCloudWave Component
It would be better to create a custom SoundCloudWave component that can be
used in multiple places as required. Here are the required
- waveformUrl — The URL object to the waveform (accessible through the Tracks API)
- height — Height of the waveform
- width — Width of the waveform component
- percentPlayable — The duration of the track buffered in seconds
- percentPlayed — The duration of the track played in seconds
- **setTime — **The callback handler to change the current track time.
Get the samples
Get the samples by using a simple
GET API call and store the result in the
Create a Waveform Component
The Waveform Component works as follows:
- The Chunks split the
samplesobject based on the
widththat the user wants to render on the screen.
- The Chunks are then mapped into a
Touchableevent. The styles as
height: scaleLinearHeight(mean(chunk)). This generates the
backgroundColoris being passed as a method with different parameters to the
getColormethod. This will then determine the color to return based on the conditions set.
Touchable onPressevent will call the custom handler passed into it, to set the new seek time of the track.
Now this stateless component can be rendered to your child component as:
Here one of the waveform component is original and one inverted as in the SoundCloud’s player.
Here are the links to the react-native-soundcloud-waveform
I’ve also made an app in react-native — MetalCloud for Metal Music fans where you can see the above component at work.
Here are the links:
Thanks for reading. If you liked this article, show your support by clapping to share with other people on Medium.