Spaces:
Running
Running
import { useEffect, useRef, useState } from 'react' | |
import WaveSurfer from 'wavesurfer.js' | |
// @ts-ignore: No types for timeline.esm.js | |
import TimelinePlugin from 'wavesurfer.js/dist/plugins/timeline.esm.js' | |
import API from '../API' | |
const AudioPlayer = ({ src }: { src: string }) => { | |
const containerRef = useRef<HTMLDivElement>(null) | |
const wavesurferRef = useRef<WaveSurfer | null>(null) | |
const [isPlaying, setIsPlaying] = useState(false) | |
useEffect(() => { | |
if (!containerRef.current) return | |
// Destroy previous instance if exists | |
if (wavesurferRef.current) { | |
wavesurferRef.current.destroy() | |
wavesurferRef.current = null | |
} | |
// Get proxied URL to bypass CORS | |
const proxiedUrl = API.getProxiedUrl(src) | |
// Create plugin instance inside effect | |
const bottomTimeline = TimelinePlugin.create({ | |
height: 16, | |
timeInterval: 0.1, | |
primaryLabelInterval: 1, | |
style: { fontSize: '10px' }, | |
}) | |
// Create an instance of WaveSurfer | |
wavesurferRef.current = WaveSurfer.create({ | |
container: containerRef.current, | |
waveColor: 'rgb(200, 0, 200)', | |
progressColor: 'rgb(100, 0, 100)', | |
url: proxiedUrl, | |
minPxPerSec: 100, | |
// barWidth: 10, | |
// barRadius: 10, | |
// barGap: 2, | |
mediaControls: true, | |
plugins: [bottomTimeline], | |
}) | |
// Play on click | |
wavesurferRef.current.on('interaction', () => { | |
wavesurferRef.current?.play() | |
setIsPlaying(true) | |
}) | |
wavesurferRef.current.on('finish', () => { | |
wavesurferRef.current?.setTime(0) | |
setIsPlaying(false) | |
}) | |
wavesurferRef.current.on('play', () => setIsPlaying(true)) | |
wavesurferRef.current.on('pause', () => setIsPlaying(false)) | |
// Cleanup on unmount | |
return () => { | |
wavesurferRef.current?.destroy() | |
wavesurferRef.current = null | |
} | |
}, [src]) | |
// Optionally, add a play/pause button | |
// const handlePlayPause = () => { | |
// wavesurferRef.current?.playPause() | |
// } | |
return ( | |
<div className="w-full"> | |
<div ref={containerRef} /> | |
{/* <button onClick={handlePlayPause}>{isPlaying ? 'Pause' : 'Play'}</button> */} | |
</div> | |
) | |
} | |
export default AudioPlayer | |