This commit is contained in:
2025-12-09 21:13:54 +09:00
parent a30239a4fe
commit c21bbb779f

View File

@@ -1066,6 +1066,9 @@ async def client_websocket_endpoint(websocket: WebSocket, room_id: str, password
message = data.get("text") or data.get("bytes") message = data.get("text") or data.get("bytes")
if isinstance(message, bytes): if isinstance(message, bytes):
if frame_count == 0:
print(f"[WebSocket Client] ✓ FIRST FRAME RECEIVED from {client_id}! Size: {len(message)} bytes")
if client_id in video_queues: if client_id in video_queues:
if not video_queues[client_id].full(): if not video_queues[client_id].full():
video_queues[client_id].put(message) video_queues[client_id].put(message)
@@ -3430,6 +3433,9 @@ def create_html_templates():
<div class="main-content"> <div class="main-content">
<!-- Video Container --> <!-- Video Container -->
<div class="video-container"> <div class="video-container">
<!-- Canvas для отображения видеокадров -->
<canvas id="videoCanvas" style="width: 100%; height: auto; display: none; background: #000;"></canvas>
<div class="video-placeholder" id="videoPlaceholder"> <div class="video-placeholder" id="videoPlaceholder">
<i class="fas fa-video"></i> <i class="fas fa-video"></i>
<h3>Waiting for Video Stream</h3> <h3>Waiting for Video Stream</h3>
@@ -3577,10 +3583,17 @@ def create_html_templates():
ws.onmessage = function(event) { ws.onmessage = function(event) {
try { try {
const data = JSON.parse(event.data); // Проверяем, это бинарные данные (видеокадр) или текст (JSON)
handleWebSocketMessage(data); 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) { } 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 // Initialize sliders
function initializeSliders() { function initializeSliders() {
// Quality slider // Quality slider