diff --git a/test-runpod.html b/test-runpod.html index 1327abe..83ce88a 100644 --- a/test-runpod.html +++ b/test-runpod.html @@ -456,6 +456,107 @@ document.getElementById('status').classList.remove('show'); } + async function pollForCompletion(endpointId, jobId, apiKey, startTime) { + const statusUrl = `https://api.runpod.ai/v2/${endpointId}/status/${jobId}`; + const maxPolls = 120; // 10 minutes with 5s intervals + let pollCount = 0; + + while (pollCount < maxPolls) { + pollCount++; + const elapsed = ((Date.now() - startTime) / 1000).toFixed(0); + showStatus(`⏳ Generating video... (${elapsed}s elapsed, poll #${pollCount})`, 'info'); + + await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds + + try { + const response = await fetch(statusUrl, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${apiKey}` + } + }); + + if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); + } + + const result = await response.json(); + + // Update JSON output + document.getElementById('jsonOutput').innerHTML = + 'Raw Response:
' +
+                        JSON.stringify(result, null, 2) +
+                        '
'; + + if (result.status === 'COMPLETED' || result.status === 'FAILED') { + return result; + } + + // Still in progress, continue polling + } catch (error) { + console.error('Poll error:', error); + // Continue polling despite errors + } + } + + throw new Error('Timeout: Job did not complete within 10 minutes'); + } + + async function handleResult(result, startTime, endpointId, apiKey) { + const elapsed = ((Date.now() - startTime) / 1000).toFixed(2); + + // If still in progress, poll for completion + if (result.status === 'IN_PROGRESS' || result.status === 'IN_QUEUE') { + showStatus(`⏳ Job ${result.id} is ${result.status}. Polling for completion...`, 'info'); + result = await pollForCompletion(endpointId, result.id, apiKey, startTime); + + // Update JSON output with final result + document.getElementById('jsonOutput').innerHTML = + 'Raw Response:
' +
+                    JSON.stringify(result, null, 2) +
+                    '
'; + } + + const finalElapsed = ((Date.now() - startTime) / 1000).toFixed(2); + + if (result.status === 'COMPLETED' && result.output) { + showStatus(`✅ Video generated successfully in ${finalElapsed}s`, 'success'); + + const outputContainer = document.getElementById('outputContainer'); + + if (result.output.video) { + // Base64 video + const videoElem = document.createElement('video'); + videoElem.className = 'output-video'; + videoElem.controls = true; + videoElem.autoplay = true; + videoElem.loop = true; + videoElem.src = 'data:video/mp4;base64,' + result.output.video; + outputContainer.appendChild(videoElem); + } else if (result.output.image) { + // Base64 image + const imgElem = document.createElement('img'); + imgElem.className = 'output-video'; + imgElem.src = 'data:image/png;base64,' + result.output.image; + outputContainer.appendChild(imgElem); + } else if (result.output.file_path) { + // File path (large output) + const fileInfo = document.createElement('div'); + fileInfo.className = 'status info show'; + fileInfo.innerHTML = ` + Large output saved to:
+ ${result.output.file_path}

+ File is too large to display (>10MB). Access it on your RunPod volume. + `; + outputContainer.appendChild(fileInfo); + } + } else if (result.status === 'FAILED') { + showStatus('❌ Generation failed: ' + (result.error || 'Unknown error'), 'error'); + } else { + showStatus('⚠️ Unexpected response status: ' + result.status, 'error'); + } + } + async function submitRequest() { // Validation const endpointId = document.getElementById('endpointId').value.trim(); @@ -531,42 +632,7 @@ ''; // Handle response - if (result.status === 'COMPLETED' && result.output) { - showStatus(`✅ Video generated successfully in ${elapsed}s`, 'success'); - - const outputContainer = document.getElementById('outputContainer'); - - if (result.output.video) { - // Base64 video - const videoElem = document.createElement('video'); - videoElem.className = 'output-video'; - videoElem.controls = true; - videoElem.autoplay = true; - videoElem.loop = true; - videoElem.src = 'data:video/mp4;base64,' + result.output.video; - outputContainer.appendChild(videoElem); - } else if (result.output.image) { - // Base64 image - const imgElem = document.createElement('img'); - imgElem.className = 'output-video'; - imgElem.src = 'data:image/png;base64,' + result.output.image; - outputContainer.appendChild(imgElem); - } else if (result.output.file_path) { - // File path (large output) - const fileInfo = document.createElement('div'); - fileInfo.className = 'status info show'; - fileInfo.innerHTML = ` - Large output saved to:
- ${result.output.file_path}

- File is too large to display (>10MB). Access it on your RunPod volume. - `; - outputContainer.appendChild(fileInfo); - } - } else if (result.status === 'FAILED') { - showStatus('❌ Generation failed: ' + (result.error || 'Unknown error'), 'error'); - } else { - showStatus('⚠️ Unexpected response status: ' + result.status, 'error'); - } + await handleResult(result, startTime, endpointId, apiKey); } catch (error) { showStatus('❌ Error: ' + error.message, 'error'); diff --git a/workflows/Wan22-I2V-Remix-API.json b/workflows/Wan22-I2V-Remix-API.json index 00ecd8b..08dbb64 100644 --- a/workflows/Wan22-I2V-Remix-API.json +++ b/workflows/Wan22-I2V-Remix-API.json @@ -362,7 +362,7 @@ "end_latent_strength": 1, "force_offload": true, "fun_or_fl2v_model": false, - "tiled_vae": false, + "tiled_vae": true, "augment_empty_frames": 0, "vae": [ "157",