|
@@ -1,13 +1,39 @@ |
|
|
import * as React from 'react'; |
|
|
import * as React from 'react'; |
|
|
|
|
|
import {WaveSurferOptions} from 'wavesurfer.js'; |
|
|
|
|
|
import clsx from 'clsx'; |
|
|
|
|
|
|
|
|
type WaveSurferCanvasDerivedComponent = HTMLAudioElement; |
|
|
type WaveSurferCanvasDerivedComponent = HTMLAudioElement; |
|
|
|
|
|
|
|
|
export interface WaveSurferCanvasProps extends React.HTMLProps<WaveSurferCanvasDerivedComponent> {} |
|
|
|
|
|
|
|
|
export interface WaveSurferCanvasProps |
|
|
|
|
|
extends React.HTMLProps<WaveSurferCanvasDerivedComponent>, |
|
|
|
|
|
Omit<WaveSurferOptions, 'height' | 'media' | 'container' | 'fillParent' | 'url' | 'autoplay' | 'renderFunction'> {} |
|
|
|
|
|
|
|
|
export const WaveSurferCanvas = React.forwardRef<WaveSurferCanvasDerivedComponent, WaveSurferCanvasProps>(({ |
|
|
export const WaveSurferCanvas = React.forwardRef<WaveSurferCanvasDerivedComponent, WaveSurferCanvasProps>(({ |
|
|
className, |
|
|
className, |
|
|
children, |
|
|
children, |
|
|
controls, |
|
|
controls, |
|
|
|
|
|
waveColor, |
|
|
|
|
|
progressColor, |
|
|
|
|
|
cursorColor, |
|
|
|
|
|
cursorWidth, |
|
|
|
|
|
barWidth, |
|
|
|
|
|
barGap, |
|
|
|
|
|
barRadius, |
|
|
|
|
|
barHeight, |
|
|
|
|
|
barAlign, |
|
|
|
|
|
minPxPerSec, |
|
|
|
|
|
peaks, |
|
|
|
|
|
duration, |
|
|
|
|
|
autoPlay, |
|
|
|
|
|
interact, |
|
|
|
|
|
hideScrollbar, |
|
|
|
|
|
audioRate, |
|
|
|
|
|
autoScroll, |
|
|
|
|
|
autoCenter, |
|
|
|
|
|
sampleRate, |
|
|
|
|
|
splitChannels, |
|
|
|
|
|
normalize, |
|
|
|
|
|
plugins, |
|
|
...etcProps |
|
|
...etcProps |
|
|
}, forwardedRef) => { |
|
|
}, forwardedRef) => { |
|
|
const [isPlaying, setIsPlaying] = React.useState(false); |
|
|
const [isPlaying, setIsPlaying] = React.useState(false); |
|
@@ -45,13 +71,34 @@ export const WaveSurferCanvas = React.forwardRef<WaveSurferCanvasDerivedComponen |
|
|
const { default: WaveSurfer } = await import('wavesurfer.js'); |
|
|
const { default: WaveSurfer } = await import('wavesurfer.js'); |
|
|
const waveSurferInstance = WaveSurfer.create({ |
|
|
const waveSurferInstance = WaveSurfer.create({ |
|
|
container: containerRef.current, |
|
|
container: containerRef.current, |
|
|
barWidth: 2, |
|
|
|
|
|
barGap: 2, |
|
|
|
|
|
height: containerRef.current.clientHeight, |
|
|
height: containerRef.current.clientHeight, |
|
|
fillParent: true, |
|
|
fillParent: true, |
|
|
media, |
|
|
|
|
|
} as any); |
|
|
|
|
|
waveSurferInstance.load(ref.current.currentSrc); |
|
|
|
|
|
|
|
|
autoplay: autoPlay, |
|
|
|
|
|
waveColor, |
|
|
|
|
|
progressColor, |
|
|
|
|
|
cursorColor, |
|
|
|
|
|
barWidth, |
|
|
|
|
|
barGap, |
|
|
|
|
|
barRadius, |
|
|
|
|
|
barHeight, |
|
|
|
|
|
barAlign, |
|
|
|
|
|
minPxPerSec, |
|
|
|
|
|
peaks, |
|
|
|
|
|
duration, |
|
|
|
|
|
interact, |
|
|
|
|
|
hideScrollbar, |
|
|
|
|
|
audioRate, |
|
|
|
|
|
autoScroll, |
|
|
|
|
|
autoCenter, |
|
|
|
|
|
sampleRate, |
|
|
|
|
|
splitChannels, |
|
|
|
|
|
normalize, |
|
|
|
|
|
plugins, |
|
|
|
|
|
cursorWidth, |
|
|
|
|
|
media: media ?? undefined, |
|
|
|
|
|
}); |
|
|
|
|
|
await waveSurferInstance.load(ref.current.currentSrc); |
|
|
|
|
|
waveSurferInstance.setTime(ref.current.currentTime); |
|
|
waveSurferInstance.on('ready', () => { |
|
|
waveSurferInstance.on('ready', () => { |
|
|
if (!container) { |
|
|
if (!container) { |
|
|
return; |
|
|
return; |
|
@@ -67,18 +114,49 @@ export const WaveSurferCanvas = React.forwardRef<WaveSurferCanvasDerivedComponen |
|
|
if (waveSurferCurrent) { |
|
|
if (waveSurferCurrent) { |
|
|
(waveSurferCurrent as unknown as Record<string, Function>).destroy(); |
|
|
(waveSurferCurrent as unknown as Record<string, Function>).destroy(); |
|
|
} |
|
|
} |
|
|
|
|
|
if (container) { |
|
|
|
|
|
container.innerHTML = ''; |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
}, [ref]); |
|
|
|
|
|
|
|
|
}, [ |
|
|
|
|
|
ref, |
|
|
|
|
|
autoPlay, |
|
|
|
|
|
waveColor, |
|
|
|
|
|
progressColor, |
|
|
|
|
|
cursorColor, |
|
|
|
|
|
barWidth, |
|
|
|
|
|
barGap, |
|
|
|
|
|
barRadius, |
|
|
|
|
|
barHeight, |
|
|
|
|
|
barAlign, |
|
|
|
|
|
minPxPerSec, |
|
|
|
|
|
peaks, |
|
|
|
|
|
duration, |
|
|
|
|
|
interact, |
|
|
|
|
|
hideScrollbar, |
|
|
|
|
|
audioRate, |
|
|
|
|
|
autoScroll, |
|
|
|
|
|
autoCenter, |
|
|
|
|
|
sampleRate, |
|
|
|
|
|
splitChannels, |
|
|
|
|
|
normalize, |
|
|
|
|
|
plugins, |
|
|
|
|
|
cursorWidth, |
|
|
|
|
|
]); |
|
|
|
|
|
|
|
|
return ( |
|
|
return ( |
|
|
<div |
|
|
<div |
|
|
className="relative h-full w-full flex flex-col" |
|
|
|
|
|
|
|
|
className={clsx( |
|
|
|
|
|
'relative h-full w-full flex flex-col', |
|
|
|
|
|
className, |
|
|
|
|
|
)} |
|
|
> |
|
|
> |
|
|
<audio |
|
|
<audio |
|
|
{...etcProps} |
|
|
{...etcProps} |
|
|
controls={controls} |
|
|
controls={controls} |
|
|
className={className} |
|
|
className={className} |
|
|
ref={ref} |
|
|
ref={ref} |
|
|
|
|
|
autoPlay={autoPlay} |
|
|
> |
|
|
> |
|
|
{children} |
|
|
{children} |
|
|
</audio> |
|
|
</audio> |
|
|