File size: 6,168 Bytes
c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 3dc3878 c0942b9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Downloadwella to Hugging Face Frame Extractor</title>
<style>
body { font-family: sans-serif; margin: 20px; background-color: #f4f4f4; color: #333; }
.container { max-width: 800px; margin: auto; background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
h1 { color: #0056b3; }
form { margin-top: 20px; display: flex; flex-direction: column; gap: 10px; }
input[type="text"] { padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 16px; }
button { padding: 10px 15px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; }
button:hover { background-color: #0056b3; }
.status-box { background-color: #e9ecef; border: 1px solid #ced4da; padding: 15px; border-radius: 4px; margin-top: 20px; }
.log-entry { margin-bottom: 5px; border-bottom: 1px dotted #ccc; padding-bottom: 3px; }
.error { color: red; font-weight: bold; }
.success { color: green; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>Downloadwella to Hugging Face Frame Extractor</h1>
<p>Enter a Downloadwella URL to download the video, extract frames, and upload them as a zip to Hugging Face.</p>
<form id="processForm">
<input type="text" id="videoUrl" name="video_url" placeholder="Enter Downloadwella URL (e.g., https://downloadwella.com/some-video-id)" required>
<button type="submit">Start Processing</button>
</form>
<div class="status-box">
<h2>Processing Status</h2>
<p><strong>Is Running:</strong> <span id="isRunning">{{ status.is_running }}</span></p>
<p><strong>Current Action:</strong> <span id="currentAction">{{ status.current_action }}</span></p>
<p><strong>Last Processed URL:</strong> <span id="lastProcessedUrl">{{ status.last_processed_url if status.last_processed_url else 'N/A' }}</span></p>
<p><strong>Processed Count:</strong> <span id="processedCount">{{ status.processed_count }}</span></p>
<h3>Logs:</h3>
<div id="logs" style="max-height: 300px; overflow-y: scroll; background-color: #fff; padding: 10px; border-radius: 4px;">
{% for log in status.logs %}
<div class="log-entry">{{ log }}</div>
{% endfor %}
</div>
</div>
</div>
<script>
const processForm = document.getElementById('processForm');
const videoUrlInput = document.getElementById('videoUrl');
const isRunningSpan = document.getElementById('isRunning');
const currentActionSpan = document.getElementById('currentAction');
const lastProcessedUrlSpan = document.getElementById('lastProcessedUrl');
const processedCountSpan = document.getElementById('processedCount');
const logsDiv = document.getElementById('logs');
processForm.addEventListener('submit', async (event) => {
event.preventDefault();
const videoUrl = videoUrlInput.value;
if (!videoUrl) return;
logsDiv.innerHTML = ''; // Clear previous logs
addLog('Initiating processing...');
try {
const response = await fetch('/start', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `video_url=${encodeURIComponent(videoUrl)}`
});
const data = await response.json();
addLog(data.message);
if (data.message === "Processor started") {
// Start polling for status updates
pollStatus();
}
} catch (error) {
addLog(`Error starting process: ${error}`, true);
}
});
async function fetchStatus() {
try {
const response = await fetch('/stats');
const status = await response.json();
isRunningSpan.textContent = status.is_running;
currentActionSpan.textContent = status.current_action;
lastProcessedUrlSpan.textContent = status.last_processed_url || 'N/A';
processedCountSpan.textContent = status.processed_count;
// Only update logs if there are new entries or status changed
if (status.logs.length !== logsDiv.children.length) {
logsDiv.innerHTML = '';
status.logs.forEach(log => addLog(log));
}
return status.is_running;
} catch (error) {
addLog(`Error fetching status: ${error}`, true);
return false;
}
}
function addLog(message, isError = false) {
const logEntry = document.createElement('div');
logEntry.classList.add('log-entry');
if (isError) {
logEntry.classList.add('error');
}
logEntry.textContent = message;
logsDiv.appendChild(logEntry);
logsDiv.scrollTop = logsDiv.scrollHeight; // Auto-scroll to bottom
}
let pollingInterval;
function pollStatus() {
if (pollingInterval) clearInterval(pollingInterval);
pollingInterval = setInterval(async () => {
const running = await fetchStatus();
if (!running && currentActionSpan.textContent !== "Idle" && currentActionSpan.textContent !== "Error") {
addLog("Processing finished or stopped.");
clearInterval(pollingInterval);
}
}, 3000); // Poll every 3 seconds
}
// Initial status fetch on page load
fetchStatus();
pollStatus(); // Start polling immediately
</script>
</body>
</html>
|