Untitled
unknown
plain_text
a year ago
2.9 kB
10
Indexable
const fetchAndDecodeAudio = async (url: string): Promise<AudioBuffer> => {
const response = await fetch(url);
const audioData = await response.arrayBuffer();
const audioContext = new AudioContext();
return audioContext.decodeAudioData(audioData);
};
const analyzePlaybackAudio = (
audioBuffer: AudioBuffer,
segmentDuration: number
) => {
const sampleRate = audioBuffer.sampleRate;
const segmentSize = Math.floor(segmentDuration * sampleRate);
const totalSamples = audioBuffer.length;
const numberOfSegments = Math.ceil(audioBuffer.length / segmentSize);
const volumeData = [];
for (let i = 0; i < numberOfSegments; i++) {
const startSample = i * segmentSize;
const endSample = Math.min(startSample + segmentSize, totalSamples);
const segment = audioBuffer
.getChannelData(0)
.slice(startSample, endSample);
const rms = Math.sqrt(
segment.reduce((sum, value) => sum + value * value, 0) /
segment.length
);
volumeData.push(rms);
}
return volumeData;
};
const drawPlaybackRecording = async (
volumeData: number[],
canvas: HTMLCanvasElement
) => {
const ctx = canvas.getContext("2d");
if (!ctx) return;
const width = canvas.width;
const height = canvas.height;
const gap = 2;
const totalGapWidth = (volumeData.length - 1) * gap;
const availableWidth = width - totalGapWidth;
const barWidth = availableWidth / volumeData.length;
const sliceWidth = barWidth + gap;
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = "white";
let maxVolume = volumeData[0];
let minVolume = volumeData[0];
volumeData.forEach((volume) => {
if (volume > maxVolume) {
maxVolume = volume;
}
if (volume < minVolume) {
minVolume = volume;
}
});
let normalizedVolumeData = volumeData.map(
(volume) => (volume - minVolume) / (maxVolume - minVolume)
);
let x = 0;
normalizedVolumeData.forEach((volume, index) => {
const barHeight = (Math.log10(volume * 100) * height) / 5;
console.log(Math.log10(volume * 1000));
let y = (height - barHeight) / 2;
ctx.fillRect(x, y, barWidth, barHeight);
x += sliceWidth;
});
};
const processAndVisualizePlayback = async (
audioUrl: string,
segmentDuration: number
) => {
const audioBuffer = await fetchAndDecodeAudio(audioUrl);
const analyzedData = analyzePlaybackAudio(audioBuffer, segmentDuration);
playbackCanvas.value = document.querySelector(
"#playback"
) as HTMLCanvasElement;
drawPlaybackRecording(analyzedData, playbackCanvas.value);
};Editor is loading...
Leave a Comment