62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
|
import { useEffect, useState, useRef } from "react";
|
||
|
|
||
|
type WaveformProps = {
|
||
|
audioContext: AudioContext;
|
||
|
};
|
||
|
|
||
|
export const Waveform: React.FC<WaveformProps> = ({ audioContext }: WaveformProps) => {
|
||
|
const [audioData, setAudioData] = useState<AudioBuffer | null>(null);
|
||
|
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||
|
|
||
|
// load audio data on page load:
|
||
|
useEffect(() => {
|
||
|
(async function() {
|
||
|
console.log("fetching audio data...");
|
||
|
|
||
|
const videoID = "s_oJYdRlrv0";
|
||
|
|
||
|
const resp = await fetch(`http://localhost:8888/api/audio?video_id=${videoID}`)
|
||
|
console.log("resp =", resp)
|
||
|
|
||
|
const body = await resp.arrayBuffer();
|
||
|
console.log("body =", body)
|
||
|
|
||
|
const data = await audioContext.decodeAudioData(body);
|
||
|
|
||
|
console.log("decodedAudio =", data, "len =", data.length);
|
||
|
setAudioData(data);
|
||
|
})();
|
||
|
}, [audioContext]);
|
||
|
|
||
|
// render waveform to canvas when audioData is updated:
|
||
|
useEffect(() => {
|
||
|
const canvas = canvasRef.current;
|
||
|
if (canvas == null) {
|
||
|
console.error("no canvas ref available");
|
||
|
return
|
||
|
}
|
||
|
|
||
|
const ctx = canvas.getContext("2d");
|
||
|
if (ctx == null) {
|
||
|
console.error("no 2d context available");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
ctx.fillStyle = 'black';
|
||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||
|
|
||
|
if (audioData == null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
console.log("rendering audio")
|
||
|
}, [audioData]);
|
||
|
|
||
|
// render component:
|
||
|
|
||
|
console.log("rendering, audioData =", audioData);
|
||
|
|
||
|
const canvasProps = {width: "100%", height: "500px"};
|
||
|
return <canvas ref={canvasRef} style={canvasProps}></canvas>
|
||
|
}
|