stem-separator / frontend /src /hooks /useWaveSurfer.ts
sourav-das's picture
Upload folder using huggingface_hub
7dfae77 verified
import { useRef, useEffect, useState, useCallback } from "react";
import WaveSurfer from "wavesurfer.js";
interface UseWaveSurferOptions {
url: string;
color: string;
height?: number;
instanceId: string;
}
export function useWaveSurfer({
url,
color,
height = 64,
instanceId,
}: UseWaveSurferOptions) {
const containerRef = useRef<HTMLDivElement>(null);
const wsRef = useRef<WaveSurfer | null>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [isReady, setIsReady] = useState(false);
useEffect(() => {
if (!containerRef.current || !url) return;
const ws = WaveSurfer.create({
container: containerRef.current,
url,
waveColor: color + "30",
progressColor: color + "ee",
height,
barWidth: 2,
barGap: 1,
barRadius: 2,
cursorWidth: 1,
cursorColor: "#ffffff40",
normalize: true,
interact: true,
});
wsRef.current = ws;
ws.on("ready", () => {
setDuration(ws.getDuration());
setIsReady(true);
});
ws.on("timeupdate", (time) => {
setCurrentTime(time);
});
ws.on("play", () => setIsPlaying(true));
ws.on("pause", () => setIsPlaying(false));
ws.on("finish", () => setIsPlaying(false));
// Exclusive playback: pause when another player starts
const handleStemPlay = (e: Event) => {
const detail = (e as CustomEvent).detail;
if (detail !== instanceId) {
ws.pause();
}
};
window.addEventListener("stem-play", handleStemPlay);
return () => {
window.removeEventListener("stem-play", handleStemPlay);
ws.destroy();
wsRef.current = null;
setIsReady(false);
setIsPlaying(false);
};
}, [url, color, height, instanceId]);
const togglePlay = useCallback(() => {
if (!wsRef.current) return;
if (wsRef.current.isPlaying()) {
wsRef.current.pause();
} else {
// Dispatch event to pause other players
window.dispatchEvent(
new CustomEvent("stem-play", { detail: instanceId })
);
wsRef.current.play();
}
}, [instanceId]);
return {
containerRef,
isPlaying,
isReady,
currentTime,
duration,
togglePlay,
};
}