Audio Player with Wavesurfer.js & React ππ½ββοΈ
andy_801 π«πΊπ¦
Posted on July 26, 2020
Recently I was in need to set a simple view that can show audio file waveform and play its audio using React.JS. After some googling, I found this Wavesurfer.js package. It has pretty exciting use examples, except it lucks of React.JS example, which as we know lives in its own virtual world, what force you write code in its specific way. So, I share my example here with some main points.
Here is the final result (with some soundcloud-like style)
Code In Details
π Reference to DOM
We can import package and use the module as usual.
import WaveSurfer from "wavesurfer.js";
WaveSurfer.create({ container: someDiv });
Most tricky things happen when React rerenders component replacing DOM elements and old ones lost. WaveSurfer.js
doesn't expect these changes, so we need to provide an alias to a needed HTML element within React.
We can do it setting ref
to some element and passing this ref
to WaveSurfer object on creating.
const waveformRef = useRef(null);
useEffect(() => {
WaveSurfer.create({
container: waveformRef.current
});
}, []);
return <div ref={waveformRef} />;
π Reference to Audio Player
A similar thing we need to do to access Wavesurfer instance from our React component. Again, because of React nature, on each rerender React component born in a new body (function) and it doesn't have access to variables from previous live. So we need to save it between rerenders with similar ref
technique.
const wavesurfer = useRef(null);
useEffect(() => {
wavesurfer.current = WaveSurfer.create(options);
// Removes events, elements and disconnects Web Audio nodes.
// when component unmount
return () => wavesurfer.current.destroy();
}, [url]);
And, when component life is over or when we want to create a new instance we need to destroy the previous one manually, otherwise, you will have multiply copies displayed on the screen and you won't have access to them.
Lastly, at this stage, we need to destroy the old instance and create a new one each time we will have url
property changed. Based on docs, looks like you can use the same instance over-and-over, but for me, it wasn't updated properly so I did it this way.
useEffect(() => {
...
}, [url]);
𦦠That's all.
That is actually all you need to do specific to React - Wavesurfer.js communication. Next, you can follow Wavesurfer.js docs on how to use it. For example:
wavesurfer.current.load(url);
wavesurfer.current.on("ready", function() {
// https://wavesurfer-js.org/docs/methods.html
wavesurfer.current.setVolume(0.5);
wavesurfer.current.play();
});
Posted on July 26, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.