/** * WebSocket-Client fuer Echtzeit-Updates * Verbindet sich mit dem Server und aktualisiert Dashboard dynamisch */ let ws = null; let videoActive = {}; let videoQueue = {}; let reconnectTimer = null; // WebSocket verbinden function connectWebSocket() { if (!window.WS_URL) return; ws = new WebSocket(WS_URL); ws.onopen = function () { console.log("WebSocket verbunden:", WS_URL); if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; } }; ws.onmessage = function (event) { try { const packet = JSON.parse(event.data); if (packet.data_flow !== undefined) { updateProgress(packet.data_flow); } else if (packet.data_convert !== undefined) { updateActiveConversions(packet.data_convert); } else if (packet.data_queue !== undefined) { updateQueue(packet.data_queue); } else if (packet.data_log !== undefined) { // Log-Nachrichten ans Benachrichtigungs-System weiterleiten if (typeof addNotification === "function") { addNotification(packet.data_log.message, packet.data_log.level); } } else if (packet.data_import !== undefined) { // Import-Fortschritt an Library weiterleiten if (typeof handleImportWS === "function") { handleImportWS(packet.data_import); } } else if (packet.data_library_scan !== undefined) { // Scan-Fortschritt an Library weiterleiten if (typeof handleScanWS === "function") { handleScanWS(packet.data_library_scan); } } // Globaler Progress-Balken aktualisieren if (typeof _updateGlobalProgress === "function") { _updateGlobalProgress(packet); } } catch (e) { console.error("WebSocket Nachricht parsen fehlgeschlagen:", e); } }; ws.onclose = function () { console.log("WebSocket getrennt, Reconnect in 3s..."); reconnectTimer = setTimeout(connectWebSocket, 3000); }; ws.onerror = function (err) { console.error("WebSocket Fehler:", err); }; } // === Aktive Konvertierungen === function updateActiveConversions(data) { const container = document.getElementById("active-conversions"); if (!container) return; // Entfernte Jobs loeschen for (const key in videoActive) { if (!(key in data)) { const elem = document.getElementById("convert_" + key); if (elem) elem.remove(); delete videoActive[key]; } } // Neue Jobs hinzufuegen for (const [key, video] of Object.entries(data)) { if (!videoActive[key]) { const card = document.createElement("div"); card.className = "video-card"; card.id = "convert_" + key; card.innerHTML = `

${video.source_file_name} → ${video.target_file_name}

0%
Frames
0
FPS
0
Speed
0x
Groesse
0 KiB
Bitrate
0 kbits/s
Zeit
0 Min
Verbleibend
-
`; container.appendChild(card); videoActive[key] = video; } } } function updateProgress(flow) { const container = document.getElementById("convert_" + flow.id); if (!container) return; container.querySelector(".frames").textContent = flow.frames || 0; container.querySelector(".fps").textContent = flow.fps || 0; container.querySelector(".speed").textContent = flow.speed || 0; container.querySelector(".size").textContent = flow.size ? flow.size[0] : 0; container.querySelector(".size_unit").textContent = flow.size ? flow.size[1] : "KiB"; container.querySelector(".bitrate").textContent = flow.bitrate ? flow.bitrate[0] : 0; container.querySelector(".bitrate_unit").textContent = flow.bitrate ? flow.bitrate[1] : "kbits/s"; container.querySelector(".time").textContent = flow.time || "0 Min"; container.querySelector(".eta").textContent = flow.time_remaining || "-"; container.querySelector(".loading-pct").textContent = (flow.loading || 0).toFixed(1); const bar = container.querySelector(".progress-bar"); bar.style.width = (flow.loading || 0) + "%"; } // === Warteschlange === function updateQueue(data) { const container = document.getElementById("queue"); if (!container) return; // Entfernte/geaenderte Jobs loeschen for (const key in videoQueue) { if (!(key in data) || videoQueue[key]?.status !== data[key]?.status) { const elem = document.getElementById("queue_" + key); if (elem) elem.remove(); delete videoQueue[key]; } } // Neue Jobs hinzufuegen for (const [key, video] of Object.entries(data)) { if (!videoQueue[key]) { const card = document.createElement("div"); card.className = "queue-card"; card.id = "queue_" + key; let statusHtml; if (video.status === 1) { statusHtml = 'Aktiv'; } else if (video.status === 3) { statusHtml = 'Fehler'; } else if (video.status === 4) { statusHtml = 'Abgebrochen'; } else { statusHtml = 'Wartend'; } card.innerHTML = `

${video.source_file_name}

`; container.appendChild(card); videoQueue[key] = video; } } } // === Befehle senden === function sendCommand(command, id) { if (ws && ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify({ data_command: { cmd: command, id: id } })); } else { console.warn("WebSocket nicht verbunden"); } } // Verbindung herstellen connectWebSocket();