+ + +

Waiting for Video Stream

@@ -3577,10 +3583,17 @@ def create_html_templates(): ws.onmessage = function(event) { try { - const data = JSON.parse(event.data); - handleWebSocketMessage(data); + // Проверяем, это бинарные данные (видеокадр) или текст (JSON) + if (event.data instanceof Blob) { + // Это видеокадр - отображаем на canvas + handleVideoFrame(event.data); + } else if (typeof event.data === 'string') { + // Это текстовое сообщение JSON + const data = JSON.parse(event.data); + handleWebSocketMessage(data); + } } catch (error) { - console.error('Error parsing WebSocket message:', error); + console.error('Error processing WebSocket message:', error); } }; @@ -3739,6 +3752,39 @@ def create_html_templates(): } } + // Handle video frame from admin WebSocket + function handleVideoFrame(blob) { + const canvas = document.getElementById('videoCanvas'); + const placeholder = document.getElementById('videoPlaceholder'); + + // Show canvas, hide placeholder + if (canvas.style.display === 'none') { + canvas.style.display = 'block'; + placeholder.style.display = 'none'; + } + + // Create image from blob and draw on canvas + const img = new Image(); + img.onload = function() { + const ctx = canvas.getContext('2d'); + // Set canvas size to match image + canvas.width = img.width; + canvas.height = img.height; + // Draw image + ctx.drawImage(img, 0, 0); + // Revoke the object URL to free memory + URL.revokeObjectURL(img.src); + }; + + img.onerror = function() { + console.error('Failed to load image from blob'); + URL.revokeObjectURL(img.src); + }; + + // Create object URL from blob and load as image + img.src = URL.createObjectURL(blob); + } + // Initialize sliders function initializeSliders() { // Quality slider