Compare commits
2 Commits
367540a380
...
3eec087640
| Author | SHA1 | Date | |
|---|---|---|---|
| 3eec087640 | |||
| 229d725bd1 |
@@ -341,7 +341,17 @@ import html from '../utils/html.js';
|
||||
|
||||
// Setup canvas dimensions
|
||||
const setupCanvas = () => {
|
||||
if (!waveformCanvas || !ctx) {
|
||||
console.error('Canvas or context not available');
|
||||
return false;
|
||||
}
|
||||
|
||||
const rect = waveformCanvas.getBoundingClientRect();
|
||||
if (rect.width === 0 || rect.height === 0) {
|
||||
console.warn('Canvas has zero dimensions, retrying...');
|
||||
return false;
|
||||
}
|
||||
|
||||
const dpr = window.devicePixelRatio || 1;
|
||||
canvasWidth = rect.width * dpr;
|
||||
canvasHeight = rect.height * dpr;
|
||||
@@ -349,17 +359,30 @@ import html from '../utils/html.js';
|
||||
waveformCanvas.width = canvasWidth;
|
||||
waveformCanvas.height = canvasHeight;
|
||||
ctx.scale(dpr, dpr);
|
||||
return true;
|
||||
};
|
||||
|
||||
// Generate waveform data from audio
|
||||
const generateWaveform = async () => {
|
||||
try {
|
||||
// Ensure canvas is properly set up
|
||||
if (!setupCanvas()) {
|
||||
console.error('Failed to setup canvas for waveform');
|
||||
throw new Error('Canvas setup failed');
|
||||
}
|
||||
|
||||
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
||||
const arrayBuffer = await audioBlob.arrayBuffer();
|
||||
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
||||
|
||||
const rawData = audioBuffer.getChannelData(0);
|
||||
const samples = Math.floor(canvasWidth / 2); // Sample every 2 pixels
|
||||
|
||||
// Guard against invalid sample count
|
||||
if (samples <= 0) {
|
||||
throw new Error('Invalid canvas width for waveform generation');
|
||||
}
|
||||
|
||||
const blockSize = Math.floor(rawData.length / samples);
|
||||
const filteredData = [];
|
||||
|
||||
@@ -386,22 +409,30 @@ import html from '../utils/html.js';
|
||||
const drawWaveform = () => {
|
||||
if (!waveformData || !ctx) return;
|
||||
|
||||
// Use the container's logical dimensions for consistent rendering
|
||||
const rect = waveformCanvas.getBoundingClientRect();
|
||||
const width = rect.width;
|
||||
const height = rect.height;
|
||||
const logicalWidth = rect.width;
|
||||
const logicalHeight = rect.height;
|
||||
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
// Clear the entire canvas using its actual dimensions
|
||||
ctx.clearRect(0, 0, logicalWidth, logicalHeight);
|
||||
ctx.fillStyle = '#e0e0e0';
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
ctx.fillRect(0, 0, logicalWidth, logicalHeight);
|
||||
|
||||
const barWidth = width / waveformData.length;
|
||||
// Guard against invalid dimensions
|
||||
if (logicalWidth <= 0 || logicalHeight <= 0 || waveformData.length === 0) return;
|
||||
|
||||
const barWidth = logicalWidth / waveformData.length;
|
||||
const maxAmplitude = Math.max(...waveformData);
|
||||
|
||||
// Guard against invalid amplitude data
|
||||
if (maxAmplitude <= 0) return;
|
||||
|
||||
ctx.fillStyle = '#007cba';
|
||||
for (let i = 0; i < waveformData.length; i++) {
|
||||
const barHeight = (waveformData[i] / maxAmplitude) * height * 0.8;
|
||||
const barHeight = (waveformData[i] / maxAmplitude) * logicalHeight * 0.8;
|
||||
const x = i * barWidth;
|
||||
const y = (height - barHeight) / 2;
|
||||
const y = (logicalHeight - barHeight) / 2;
|
||||
|
||||
ctx.fillRect(x, y, Math.max(1, barWidth - 1), barHeight);
|
||||
}
|
||||
@@ -510,6 +541,7 @@ import html from '../utils/html.js';
|
||||
|
||||
const setupAudioControls = () => {
|
||||
console.log(`Setup attempt ${retryCount + 1}, duration:`, audio.duration, 'ready state:', audio.readyState, 'stored duration:', storedDuration);
|
||||
console.log('Audio duration isFinite:', isFinite(audio.duration), 'Audio duration !== Infinity:', audio.duration !== Infinity);
|
||||
|
||||
// Use stored duration if available and valid
|
||||
if (storedDuration && isFinite(storedDuration) && storedDuration > 0) {
|
||||
@@ -519,21 +551,19 @@ import html from '../utils/html.js';
|
||||
updateDisplay();
|
||||
updateSubmitButton();
|
||||
// Initialize waveform
|
||||
setupCanvas();
|
||||
generateWaveform();
|
||||
console.log('Using stored duration:', audioDuration);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise try to get duration from audio element
|
||||
if (audio.duration && isFinite(audio.duration) && audio.duration > 0) {
|
||||
// Otherwise try to get duration from audio element (reject Infinity)
|
||||
if (audio.duration && isFinite(audio.duration) && audio.duration > 0 && audio.duration !== Infinity) {
|
||||
audioDuration = audio.duration;
|
||||
startTimeDisplay.textContent = '0:00';
|
||||
endTimeDisplay.textContent = formatTime(audioDuration);
|
||||
updateDisplay();
|
||||
updateSubmitButton();
|
||||
// Initialize waveform
|
||||
setupCanvas();
|
||||
generateWaveform();
|
||||
console.log('Audio controls setup complete, duration:', audioDuration);
|
||||
} else if (retryCount < maxRetries) {
|
||||
@@ -550,7 +580,6 @@ import html from '../utils/html.js';
|
||||
updateDisplay();
|
||||
updateSubmitButton();
|
||||
// Initialize waveform even with estimated duration
|
||||
setupCanvas();
|
||||
generateWaveform();
|
||||
console.log('Using estimated duration:', audioDuration);
|
||||
}
|
||||
@@ -583,8 +612,9 @@ import html from '../utils/html.js';
|
||||
// Handle window resize to redraw waveform
|
||||
window.addEventListener('resize', () => {
|
||||
if (waveformData) {
|
||||
setupCanvas();
|
||||
drawWaveform();
|
||||
if (setupCanvas()) {
|
||||
drawWaveform();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user