versão 2.0
This commit is contained in:
1 parent
d506332268
commit
fe735bf0a6
16 files changed
+1735
-1626
No files matched your search
@@ -2,44 +2,61 @@
|
||||
|
||||
/**
|
||||
* Desenha a forma de onda de um AudioBuffer em um elemento Canvas.
|
||||
* Pode desenhar apenas um segmento específico do buffer.
|
||||
* @param {HTMLCanvasElement} canvas - O elemento canvas onde o desenho será feito.
|
||||
* @param {AudioBuffer} audioBuffer - O buffer de áudio decodificado da faixa.
|
||||
* @param {string} color - A cor da forma de onda (ex: '#2ecc71').
|
||||
* @param {number} [offset=0] - O tempo em segundos de onde começar a desenhar no AudioBuffer.
|
||||
* @param {number} [duration] - A duração em segundos do segmento a ser desenhado.
|
||||
*/
|
||||
export function drawWaveform(canvas, audioBuffer, color) {
|
||||
export function drawWaveform(canvas, audioBuffer, color, offset = 0, duration) {
|
||||
if (!canvas || !audioBuffer) return;
|
||||
|
||||
const ctx = canvas.getContext('2d');
|
||||
const width = canvas.width;
|
||||
const height = canvas.height;
|
||||
const channelData = audioBuffer.getChannelData(0); // Pega os dados do primeiro canal
|
||||
const step = Math.ceil(channelData.length / width);
|
||||
const amp = height / 2; // Amplitude máxima do desenho
|
||||
const channelData = audioBuffer.getChannelData(0);
|
||||
const sampleRate = audioBuffer.sampleRate;
|
||||
|
||||
ctx.clearRect(0, 0, width, height); // Limpa o canvas
|
||||
// Se a duração não for fornecida, usa a duração total a partir do offset
|
||||
const finalDuration = duration || (audioBuffer.duration - offset);
|
||||
|
||||
// Calcula os índices de início e fim no array de dados do áudio
|
||||
const startIndex = Math.floor(offset * sampleRate);
|
||||
const endIndex = Math.floor((offset + finalDuration) * sampleRate);
|
||||
const totalSamplesInSegment = endIndex - startIndex;
|
||||
|
||||
const step = Math.ceil(totalSamplesInSegment / width);
|
||||
const amp = height / 2;
|
||||
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineWidth = 1;
|
||||
ctx.beginPath();
|
||||
|
||||
// Desenha a linha do meio (zero amplitude)
|
||||
ctx.moveTo(0, amp);
|
||||
ctx.lineTo(width, amp);
|
||||
|
||||
for (let i = 0; i < width; i++) {
|
||||
let min = 1.0;
|
||||
let max = -1.0;
|
||||
|
||||
// Encontra o valor mínimo e máximo para um bloco de amostras
|
||||
for (let j = 0; j < step; j++) {
|
||||
const datum = channelData[(i * step) + j];
|
||||
if (datum < min) {
|
||||
min = datum;
|
||||
}
|
||||
if (datum > max) {
|
||||
max = datum;
|
||||
// --- CORREÇÃO CRÍTICA AQUI ---
|
||||
// Calcula o índice da amostra considerando o startIndex do segmento
|
||||
const sampleIndex = startIndex + (i * step) + j;
|
||||
if (sampleIndex < channelData.length) {
|
||||
const datum = channelData[sampleIndex];
|
||||
if (datum < min) min = datum;
|
||||
if (datum > max) max = datum;
|
||||
}
|
||||
}
|
||||
|
||||
// Desenha a linha vertical para aquele ponto no tempo
|
||||
const x = i;
|
||||
const y_max = (1 + max) * amp;
|
||||
const y_min = (1 + min) * amp;
|
||||
// Ajusta o desenho para ser centrado verticalmente
|
||||
const y_max = (1 - max) * amp;
|
||||
const y_min = (1 - min) * amp;
|
||||
|
||||
ctx.moveTo(x, y_max);
|
||||
ctx.lineTo(x, y_min);
|
||||
|
||||
Reference in new issue
Block a user