Home > database >  Using wavesurfer.js in a react app cause issues
Using wavesurfer.js in a react app cause issues

Time:10-18

Got an issue using wavesurfer. I have a demo here using react but I'm using Nextjs. I could not get codesandbox to work with their nextjs package so I used react instead. I have two issues:

  1. I'm getting ReferenceError: self is not defined (node_modules/wavesurfer.js/dist/wavesurfer.js (15:4))
  2. Everytime I make changes, wavesurfer duplicates. Can be seen in demo should you make a change.

Code:

/**
 * This file is imported using next/dynamic in my Next.js app:
 * import dynamic from 'next/dynamic'
 * const Player = dynamic(() => import('components/Player'), { ssr: false })
 */
import { useEffect, useRef, useState } from "react";
import WaveSurfer from "wavesurfer.js";

export default function Player() {
  const [waver, setWaver] = useState(null);
  const [playing, setPlaying] = useState(false);

  const el = useRef();
  const audioEl = useRef();

  useEffect(() => {
    if (el.current) {
      let wavesurfer = WaveSurfer.create({
        barWidth: 3,
        barHeight: 1,
        cursorWidth: 1,
        container: el.current,
        backend: "WebAudio",
        height: 60,
        progressColor: "#fff",
        responsive: true,
        waveColor: "rgba(255,255,255,.38",
        cursorColor: "#fff"
      });

      wavesurfer.load(audioEl.current);

      setWaver(wavesurfer);
    }
  }, []);

  const handlePlay = () => {
    setPlaying(!playing);
    waver?.playPause();
  };

  return (
    <div className="max-w-lg w-full rounded-md bg-blue-600 p-3">
      <div className="flex items-center">
        <PlayButton onClick={handlePlay} />
        <div className="flex-1" ref={el} />
      </div>
      <audio
        ref={audioEl}
        src={
          "https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3"
        }
      />
    </div>
  );
}

function PlayButton({ onClick }) {
  return (
    <button
      onClick={onClick}
      className="h-10 w-10 rounded-full bg-white/[0.3] hover:bg-white/[0.4] flex items-center justify-center cursor-pointer"
    >
      <PlayIcon />
    </button>
  );
}

function PlayIcon() {
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      width="22"
      height="22"
      viewBox="0 0 35.713 39.635"
    >
      <path
        d="M14.577.874C11-1.176,8.107.5,8.107,4.621V35.01c0,4.122,2.9,5.8,6.47,3.751L41.139,23.529c3.575-2.05,3.575-5.372,0-7.422Z"
        transform="translate(-8.107 0)"
        fill="#f7f7f7"
      />
    </svg>
  );
}

For the first issue, to get rid of the error, I have to refresh the page until the error goes away. Compatibility issue? And lastly, how to prevent number 2?

As per juliomalves's comment, added ssr: false to my import solves number 1.

Been looking at their doc, but nothing works when I use them in the useEffect cleanup function:


useEffect(() => {

  return () => waver.destroy()

}, [])

CodePudding user response:

To make sure Wavesurfer does not duplicate, you need to destroy the wavesurfer instance when the component unmounts which can be done in the useEffect's cleanup phase.

useEffect(() => {
    // `wavesurfer` instance init code

    return () => wavesurfer.destroy()
}, []);

To fix the ReferenceError: self is not defined issue, you can dynamically import Wavesurfer as described in Why am I getting ReferenceError: self is not defined in Next.js when I try to import a client-side library?.

  • Related