Files
Viz/test_export_pipeline.mjs

138 lines
4.8 KiB
JavaScript

import fs from 'fs';
import path from 'path';
async function testPipeline() {
console.log('🧪 Starting End-to-End Test for ProRes 4444 & WebM Alpha Streaming Pipeline...');
// 1. Check audio sample file
const sampleAudioPath = 'd:/Google Drive/Videos/AIWentNonsense/022 - Swing Low - Sweet Cadence/AUDIO/Master_WAV.wav';
let audioBuffer;
if (fs.existsSync(sampleAudioPath)) {
console.log(`Found master audio: ${sampleAudioPath}`);
audioBuffer = fs.readFileSync(sampleAudioPath);
} else {
console.log('Creating synthetic dummy WAV for test...');
// Create simple 44.1kHz 1s WAV
audioBuffer = Buffer.alloc(44 + 44100 * 4);
audioBuffer.write('RIFF', 0);
audioBuffer.writeUInt32LE(36 + 44100 * 4, 4);
audioBuffer.write('WAVE', 8);
audioBuffer.write('fmt ', 12);
audioBuffer.writeUInt32LE(16, 16);
audioBuffer.writeUInt16LE(1, 20); // PCM
audioBuffer.writeUInt16LE(2, 22); // stereo
audioBuffer.writeUInt32LE(44100, 24);
audioBuffer.writeUInt32LE(44100 * 4, 28);
audioBuffer.writeUInt16LE(4, 32);
audioBuffer.writeUInt16LE(16, 34);
audioBuffer.write('data', 36);
audioBuffer.writeUInt32LE(44100 * 4, 40);
}
const formatsToTest = ['prores', 'qtrle', 'webm_alpha', 'mp4'];
const width = 640;
const height = 360;
const fps = 30;
const testFrameCount = 30; // 1 second
for (const fmt of formatsToTest) {
console.log(`\n▶️ Testing format: ${fmt}...`);
const formData = new FormData();
const blob = new Blob([audioBuffer], { type: 'audio/wav' });
formData.append('audio', blob, 'test_audio.wav');
formData.append('format', fmt);
formData.append('width', width.toString());
formData.append('height', height.toString());
formData.append('fps', fps.toString());
formData.append('title', `Test_${fmt}`);
const startRes = await fetch('http://localhost:3000/api/export/start', {
method: 'POST',
body: formData
});
if (!startRes.ok) {
const err = await startRes.text();
throw new Error(`Start failed for ${fmt}: ${err}`);
}
const { sessionId, outputFilename } = await startRes.json();
console.log(`Session initialized: ${sessionId} -> ${outputFilename}`);
// Stream 30 frames
const frameByteSize = width * height * 4;
const dummyFrame = new Uint8Array(frameByteSize);
// Fill with a vibrant glowing circle with transparent alpha background
const cx = width / 2;
const cy = height / 2;
const r = 80;
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const idx = (y * width + x) * 4;
const d = Math.hypot(x - cx, y - cy);
if (d < r) {
dummyFrame[idx] = 0; // R
dummyFrame[idx + 1] = 240; // G
dummyFrame[idx + 2] = 255; // B
dummyFrame[idx + 3] = 255; // A (100% opaque)
} else if (d < r + 20) {
const alphaFactor = (1 - (d - r) / 20);
dummyFrame[idx] = 255; // R
dummyFrame[idx + 1] = 0; // G
dummyFrame[idx + 2] = 128; // B
dummyFrame[idx + 3] = Math.round(alphaFactor * 200); // Gradual Alpha
} else {
dummyFrame[idx + 3] = 0; // Fully transparent!
}
}
}
for (let i = 0; i < testFrameCount; i++) {
const frameRes = await fetch(`http://localhost:3000/api/export/frame/${sessionId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/octet-stream' },
body: dummyFrame
});
if (!frameRes.ok) {
throw new Error(`Frame ${i} failed for ${fmt}`);
}
}
console.log(`Streamed ${testFrameCount} frames successfully.`);
const finishRes = await fetch(`http://localhost:3000/api/export/finish/${sessionId}`, {
method: 'POST'
});
if (!finishRes.ok) {
throw new Error(`Finish failed for ${fmt}: ${await finishRes.text()}`);
}
let finishData = null;
while (!finishData) {
await new Promise(r => setTimeout(r, 200));
const statusRes = await fetch(`http://localhost:3000/api/export/status/${sessionId}`);
if (!statusRes.ok) {
throw new Error(`Status check failed for ${fmt}: ${await statusRes.text()}`);
}
const statusJson = await statusRes.json();
if (statusJson.status === 'ready') {
finishData = statusJson;
break;
} else if (statusJson.status === 'error') {
throw new Error(`Status error for ${fmt}: ${statusJson.error}`);
}
}
console.log(`✅ Success for ${fmt}: Ready at ${finishData.downloadUrl} (${(finishData.sizeBytes / 1024).toFixed(1)} KB)`);
}
console.log('\n🎉 ALL EXPORT FORMATS (PRORES 4444, WEBM ALPHA, MP4) PASSED END-TO-END VALIDATION!');
}
testPipeline().catch(err => {
console.error('❌ Pipeline Test Error:', err);
process.exit(1);
});