nca-toolkit / static /app.js
ismdrobiul489's picture
Initial deployment with LFS
1aa90a9
// API base URL
const API_BASE = '';
// DOM elements
const videoForm = document.getElementById('videoForm');
const scenesContainer = document.getElementById('scenesContainer');
const addSceneBtn = document.getElementById('addScene');
const statusDiv = document.getElementById('status');
const videosListDiv = document.getElementById('videosList');
let sceneCount = 1;
// Add new scene
addSceneBtn.addEventListener('click', () => {
sceneCount++;
const sceneDiv = document.createElement('div');
sceneDiv.className = 'scene';
sceneDiv.innerHTML = `
<div class="form-group">
<label>Scene ${sceneCount} - Text to Narrate</label>
<textarea class="scene-text input" rows="3" placeholder="Enter the narration text..." required></textarea>
</div>
<div class="form-group">
<label>Search Keywords (comma separated)</label>
<input type="text" class="scene-keywords input" placeholder="nature, forest, trees" required>
</div>
`;
scenesContainer.appendChild(sceneDiv);
});
// Submit form
videoForm.addEventListener('submit', async (e) => {
e.preventDefault();
// Gather scenes
const scenes = Array.from(document.querySelectorAll('.scene')).map(scene => {
const text = scene.querySelector('.scene-text').value;
const keywords = scene.querySelector('.scene-keywords').value;
return {
text,
searchTerms: keywords.split(',').map(k => k.trim()).filter(k => k)
};
});
// Gather config
const config = {
orientation: document.getElementById('orientation').value,
voice: document.getElementById('voice').value,
music: document.getElementById('music').value || null,
musicVolume: document.getElementById('musicVolume').value,
captionPosition: document.getElementById('captionPosition').value,
paddingBack: 0
};
// Show processing status
showStatus('Creating video... This may take a few minutes.', 'processing');
try {
const response = await fetch(`${API_BASE}/api/short-video`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ scenes, config })
});
if (!response.ok) {
throw new Error('Failed to create video');
}
const data = await response.json();
const videoId = data.videoId;
showStatus(`Video queued! ID: ${videoId}`, 'success');
// Start polling for status
pollVideoStatus(videoId);
// Refresh video list
setTimeout(loadVideos, 1000);
} catch (error) {
showStatus(`Error: ${error.message}`, 'error');
}
});
// Poll video status
async function pollVideoStatus(videoId) {
const maxAttempts = 120; // 10 minutes
let attempts = 0;
const interval = setInterval(async () => {
attempts++;
if (attempts > maxAttempts) {
clearInterval(interval);
showStatus('Video processing timeout', 'error');
return;
}
try {
const response = await fetch(`${API_BASE}/api/short-video/${videoId}/status`);
const data = await response.json();
if (data.status === 'ready') {
clearInterval(interval);
showStatus('Video ready! Check your videos list below.', 'success');
loadVideos();
} else if (data.status === 'failed') {
clearInterval(interval);
showStatus('Video processing failed', 'error');
loadVideos();
}
} catch (error) {
console.error('Error polling status:', error);
}
}, 5000); // Poll every 5 seconds
}
// Show status message
function showStatus(message, type) {
statusDiv.textContent = message;
statusDiv.className = `status ${type}`;
statusDiv.classList.remove('hidden');
}
// Load videos list
async function loadVideos() {
try {
const response = await fetch(`${API_BASE}/api/short-videos`);
const data = await response.json();
if (data.videos.length === 0) {
videosListDiv.innerHTML = '<p class="loading">No videos yet. Create one above!</p>';
return;
}
videosListDiv.innerHTML = data.videos.map(video => `
<div class="video-card">
<h3>Video ID: ${video.id}</h3>
<span class="video-status ${video.status}">${video.status.toUpperCase()}</span>
<div class="video-actions">
${video.status === 'ready' ? `
<a href="${API_BASE}/api/short-video/${video.id}" download class="btn btn-primary">Download</a>
` : ''}
<button onclick="deleteVideo('${video.id}')" class="btn btn-secondary">Delete</button>
</div>
</div>
`).join('');
} catch (error) {
console.error('Error loading videos:', error);
videosListDiv.innerHTML = '<p class="loading">Error loading videos</p>';
}
}
// Delete video
async function deleteVideo(videoId) {
if (!confirm('Are you sure you want to delete this video?')) {
return;
}
try {
await fetch(`${API_BASE}/api/short-video/${videoId}`, {
method: 'DELETE'
});
loadVideos();
} catch (error) {
alert('Error deleting video');
}
}
// Load videos on page load
loadVideos();
// Auto-refresh videos list every 10 seconds
setInterval(loadVideos, 10000);