Mark Duppenthaler
Updated audio examples, leaderboard table initial metric
08dfd47
import { useEffect, useRef, useImperativeHandle, forwardRef } 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'
export interface AudioPlayerHandle {
getCurrentTime: () => number
setTime: (t: number) => void
play: () => void
pause: () => void
}
const AudioPlayer = forwardRef<
AudioPlayerHandle,
{
src: string
playing: boolean
// seekTo: number
onPlay: () => void
onPause: () => void
onAudioProcess?: (currentTime: number) => void
}
>(({ src, playing, onPlay, onPause, onAudioProcess }, ref) => {
const containerRef = useRef<HTMLDivElement>(null)
const wavesurferRef = useRef<WaveSurfer | null>(null)
useImperativeHandle(ref, () => ({
getCurrentTime: () => wavesurferRef.current?.getCurrentTime() || 0,
setTime: (t: number) => wavesurferRef.current?.setTime(t),
play: () => wavesurferRef.current?.play(),
pause: () => wavesurferRef.current?.pause(),
}))
// Sync play/pause and seek
useEffect(() => {
if (wavesurferRef.current) {
// wavesurferRef.current.setTime(seekTo)
if (playing) {
wavesurferRef.current.play()
} else {
wavesurferRef.current.pause()
}
}
}, [
playing,
// seekTo
])
useEffect(() => {
if (!containerRef.current) return
if (wavesurferRef.current) {
wavesurferRef.current.destroy()
wavesurferRef.current = null
}
const proxiedUrl = API.getProxiedUrl(src)
const bottomTimeline = TimelinePlugin.create({
height: 16,
timeInterval: 0.1,
primaryLabelInterval: 1,
style: { fontSize: '10px' },
})
wavesurferRef.current = WaveSurfer.create({
container: containerRef.current,
waveColor: 'rgb(200, 0, 200)',
progressColor: 'rgb(100, 0, 100)',
url: proxiedUrl,
minPxPerSec: 100,
mediaControls: true,
plugins: [bottomTimeline],
})
wavesurferRef.current.on('play', onPlay)
wavesurferRef.current.on('pause', onPause)
if (onAudioProcess) {
wavesurferRef.current.on('audioprocess', onAudioProcess)
}
return () => {
if (wavesurferRef.current && onAudioProcess) {
wavesurferRef.current.un('audioprocess', onAudioProcess)
}
wavesurferRef.current?.destroy()
wavesurferRef.current = null
}
}, [src])
return (
<div className="w-full">
<div ref={containerRef} />
</div>
)
})
export default AudioPlayer