Spaces:
Running
Running
File size: 2,563 Bytes
08dfd47 ed37070 eb27538 ed37070 08dfd47 ed37070 f76d503 08dfd47 ed37070 08dfd47 ed37070 08dfd47 eb27538 ed37070 eb27538 ed37070 eb27538 ed37070 f76d503 eb27538 ed37070 08dfd47 ed37070 08dfd47 ed37070 eb27538 ed37070 eb27538 ed37070 08dfd47 ed37070 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
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
|