styling and building out trimmer component
This commit is contained in:
@ -5,8 +5,13 @@ import React, {
|
||||
useCallback,
|
||||
useRef,
|
||||
} from 'react';
|
||||
import Regions from 'wavesurfer.js/dist/plugins/regions.esm.js';
|
||||
import { useWavesurfer } from '@wavesurfer/react';
|
||||
import Regions from 'wavesurfer.js/dist/plugins/regions.esm.js';
|
||||
import ZoomPlugin from 'wavesurfer.js/dist/plugins/zoom.esm.js';
|
||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
import PauseIcon from '@mui/icons-material/Pause';
|
||||
import SaveIcon from '@mui/icons-material/Save';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
|
||||
export interface AudioTrimmerProps {
|
||||
filePath: string;
|
||||
@ -29,14 +34,25 @@ export default function AudioTrimmer({
|
||||
}: AudioTrimmerProps) {
|
||||
const [blobUrl, setBlobUrl] = useState<string | undefined>(undefined);
|
||||
const containerRef = useRef(null);
|
||||
const [clipStart, setClipStart] = useState<number>(0);
|
||||
const [clipEnd, setClipEnd] = useState<number>(0);
|
||||
|
||||
const plugins = useMemo(() => [Regions.create()], []);
|
||||
const plugins = useMemo(
|
||||
() => [
|
||||
Regions.create(),
|
||||
ZoomPlugin.create({
|
||||
scale: 0.25,
|
||||
}),
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const { wavesurfer, isReady, isPlaying } = useWavesurfer({
|
||||
container: containerRef,
|
||||
height: 100,
|
||||
waveColor: '#ccb1ff',
|
||||
progressColor: '#6e44ba',
|
||||
hideScrollbar: true,
|
||||
url: blobUrl,
|
||||
plugins,
|
||||
});
|
||||
@ -50,6 +66,8 @@ export default function AudioTrimmer({
|
||||
region.remove();
|
||||
}
|
||||
});
|
||||
setClipStart(newRegion.start);
|
||||
setClipEnd(newRegion.end);
|
||||
},
|
||||
[plugins, wavesurfer],
|
||||
);
|
||||
@ -57,6 +75,8 @@ export default function AudioTrimmer({
|
||||
useEffect(() => {
|
||||
console.log('ready, setting up regions plugin', wavesurfer);
|
||||
if (trimStart !== undefined && trimEnd !== undefined) {
|
||||
setClipStart(trimStart);
|
||||
setClipEnd(trimEnd);
|
||||
plugins[0].addRegion({
|
||||
start: trimStart,
|
||||
end: trimEnd,
|
||||
@ -64,6 +84,9 @@ export default function AudioTrimmer({
|
||||
drag: false,
|
||||
resize: true,
|
||||
});
|
||||
} else {
|
||||
setClipStart(0);
|
||||
setClipEnd(wavesurfer ? wavesurfer.getDuration() : 0);
|
||||
}
|
||||
|
||||
plugins[0].enableDragSelection({
|
||||
@ -104,17 +127,56 @@ export default function AudioTrimmer({
|
||||
}
|
||||
};
|
||||
|
||||
const formatTime = (seconds: number) => {
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const secs = (seconds % 60).toFixed(0);
|
||||
return `${minutes}:${secs.padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="shadow-[0_4px_6px_rgba(0,0,0,0.5)] m-2 p-4 rounded-lg bg-darkDrop">
|
||||
<div>
|
||||
<text className="m-2 font-bold text-lg">{title}</text>
|
||||
</div>
|
||||
|
||||
<div className="w-[100%] m-2 ">
|
||||
<div ref={containerRef} />
|
||||
<button type="button" onClick={onPlayPause}>
|
||||
{isPlaying ? 'Pause' : 'Play'}
|
||||
</button>
|
||||
{/* <div className="flex flex-col"> */}
|
||||
<div className="">
|
||||
<div className="grid justify-items-stretch grid-cols-2">
|
||||
<div className="m-1 mb-5px flex flex-col">
|
||||
<text className="font-bold text-lg">{title}</text>
|
||||
<text className="text-sm text-neutral-500">{filePath}</text>
|
||||
</div>
|
||||
<div className="flex justify-end">
|
||||
<button
|
||||
type="button"
|
||||
className="bg-plum hover:bg-plumDark text-white font-bold h-11 w-11 rounded-md ml-1"
|
||||
onClick={onPlayPause}
|
||||
>
|
||||
{isPlaying ? <PauseIcon /> : <PlayArrowIcon />}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-plum hover:bg-plumDark text-white font-bold h-11 w-11 rounded-md ml-1"
|
||||
onClick={onSave}
|
||||
>
|
||||
<SaveIcon />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="bg-plum hover:bg-plumDark text-white font-bold h-11 w-11 rounded-md ml-1"
|
||||
onClick={onDelete}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-1 wavesurfer-scroll-container">
|
||||
<div ref={containerRef} className="wavesurfer-inner" />
|
||||
</div>
|
||||
<div className="grid justify-items-stretch grid-cols-2 text-neutral-500">
|
||||
<div className="m-1">
|
||||
<text className="text-sm ">Start: {formatTime(clipStart)}</text>
|
||||
</div>
|
||||
<div className="mx-1 flex justify-end">
|
||||
<text className="text-sm">End: {formatTime(clipEnd)}</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user