Mark Duppenthaler
Add audio examples, wip
eb27538
raw
history blame
2.21 kB
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