stem-separator / frontend /src /components /WaveformPlayer.tsx
sourav-das's picture
Upload folder using huggingface_hub
7dfae77 verified
import { useWaveSurfer } from "../hooks/useWaveSurfer";
interface WaveformPlayerProps {
url: string;
color: string;
height?: number;
instanceId: string;
onDownload?: () => void;
}
function formatTime(seconds: number): string {
const m = Math.floor(seconds / 60);
const s = Math.floor(seconds % 60);
return `${m}:${s.toString().padStart(2, "0")}`;
}
export function WaveformPlayer({
url,
color,
height = 64,
instanceId,
onDownload,
}: WaveformPlayerProps) {
const { containerRef, isPlaying, isReady, currentTime, duration, togglePlay } =
useWaveSurfer({ url, color, height, instanceId });
return (
<div className="flex items-center gap-3 w-full min-w-0">
{/* Play/Pause button */}
<button
onClick={togglePlay}
disabled={!isReady}
className="flex-shrink-0 w-10 h-10 rounded-full flex items-center justify-center transition-colors disabled:opacity-30"
style={{ backgroundColor: color + "20", color }}
>
{isPlaying ? (
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<rect x="6" y="4" width="4" height="16" rx="1" />
<rect x="14" y="4" width="4" height="16" rx="1" />
</svg>
) : (
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M8 5.14v14l11-7-11-7z" />
</svg>
)}
</button>
{/* Waveform */}
<div ref={containerRef} className="flex-grow min-w-0" />
{/* Time */}
<span className="flex-shrink-0 text-xs text-text-secondary font-mono w-[85px] text-right">
{isReady ? `${formatTime(currentTime)} / ${formatTime(duration)}` : "--:--"}
</span>
{/* Download button */}
{onDownload && (
<button
onClick={(e) => {
e.stopPropagation();
onDownload();
}}
className="flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center text-text-secondary hover:text-text-primary hover:bg-bg-hover transition-colors"
title="Download"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
</svg>
</button>
)}
</div>
);
}