Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| 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 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: src, | |
| 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 | |