You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/Next.js项目使用wavesurfer.js出现self未定义及实例重复问题

我在使用 wavesurfer 时遇到了问题。我制作了一个基于 React 的演示示例,但实际项目使用的是 Next.js,由于 codesandbox 无法正常运行 Next.js 相关包,所以采用 React 环境做演示。我遇到两个问题:

  • 报错 ReferenceError: self is not defined,报错路径为 node_modules/wavesurfer.js/dist/wavesurfer.js (15:4)
  • 每次修改代码后,wavesurfer 实例都会重复生成,修改演示代码即可复现该问题。

代码如下:

/**
 * 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>
  );
}

针对第一个问题,我目前只能通过反复刷新页面消除错误,请问这是兼容性问题吗?另外该如何解决第二个实例重复的问题?

后续根据juliomalves的评论,我在导入组件时添加了ssr: false配置,已经解决了第一个问题。
我查阅了wavesurfer官方文档,尝试在useEffect清理函数中调用销毁方法,但没有生效,相关代码如下:

useEffect(() => {
  return () => waver.destroy()
}, [])

内容的提问来源于stack exchange,提问作者Sylar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 17:24:03