'use client' import { useState, useEffect, useCallback, useRef } from 'react' interface StreamStatus { is_streaming: boolean frame_count: number width: number height: number quality: number uptime_seconds: string } interface StreamFrameResponse { success: boolean frame_count?: number width?: number height?: number data?: string // Base64 encoded JPEG message?: string } interface GameViewProps { isUnityOnline: boolean isPlaying?: boolean } export default function GameView({ isUnityOnline, isPlaying }: GameViewProps) { const [isStreaming, setIsStreaming] = useState(false) const [streamStatus, setStreamStatus] = useState(null) const [frameData, setFrameData] = useState(null) const [frameCount, setFrameCount] = useState(0) const [fps, setFps] = useState(0) const [error, setError] = useState(null) const [isLoading, setIsLoading] = useState(false) const lastFrameTimeRef = useRef(Date.now()) const frameCountRef = useRef(0) const fpsIntervalRef = useRef(null) const streamIntervalRef = useRef(null) // Fetch stream status const fetchStreamStatus = useCallback(async () => { if (!isUnityOnline) return try { const res = await fetch('/api/admin/unity-bridge?action=stream-status') if (res.ok) { const data: StreamStatus = await res.json() setStreamStatus(data) setIsStreaming(data.is_streaming) } } catch { // Ignore errors } }, [isUnityOnline]) // Capture single screenshot const captureScreenshot = async () => { if (!isUnityOnline) return setIsLoading(true) setError(null) try { const res = await fetch('/api/admin/unity-bridge?action=screenshot') if (res.ok) { const blob = await res.blob() const url = URL.createObjectURL(blob) setFrameData(url) setFrameCount(prev => prev + 1) } else { const errorData = await res.json() setError(errorData.error || 'Screenshot fehlgeschlagen') } } catch (err) { setError('Verbindung fehlgeschlagen') } setIsLoading(false) } // Start streaming const startStreaming = async () => { if (!isUnityOnline) return setIsLoading(true) setError(null) try { const res = await fetch('/api/admin/unity-bridge?action=stream-start') if (res.ok) { const data = await res.json() if (data.success) { setIsStreaming(true) frameCountRef.current = 0 } else { setError(data.message || 'Streaming konnte nicht gestartet werden') } } } catch { setError('Verbindung fehlgeschlagen') } setIsLoading(false) } // Stop streaming const stopStreaming = async () => { setIsLoading(true) try { const res = await fetch('/api/admin/unity-bridge?action=stream-stop') if (res.ok) { setIsStreaming(false) } } catch { // Ignore errors } setIsLoading(false) } // Fetch frame during streaming const fetchFrame = useCallback(async () => { if (!isStreaming || !isUnityOnline) return try { const res = await fetch('/api/admin/unity-bridge?action=stream-frame') if (res.ok) { const data: StreamFrameResponse = await res.json() if (data.success && data.data) { setFrameData(`data:image/jpeg;base64,${data.data}`) setFrameCount(data.frame_count || 0) frameCountRef.current++ } } } catch { // Ignore single frame failures } }, [isStreaming, isUnityOnline]) // Calculate FPS every second useEffect(() => { if (isStreaming) { fpsIntervalRef.current = setInterval(() => { setFps(frameCountRef.current) frameCountRef.current = 0 }, 1000) } else { if (fpsIntervalRef.current) { clearInterval(fpsIntervalRef.current) fpsIntervalRef.current = null } setFps(0) } return () => { if (fpsIntervalRef.current) { clearInterval(fpsIntervalRef.current) } } }, [isStreaming]) // Streaming loop - fetch frames at ~10 FPS useEffect(() => { if (isStreaming) { // Initial fetch fetchFrame() // Setup interval for continuous fetching streamIntervalRef.current = setInterval(fetchFrame, 100) // 10 FPS } else { if (streamIntervalRef.current) { clearInterval(streamIntervalRef.current) streamIntervalRef.current = null } } return () => { if (streamIntervalRef.current) { clearInterval(streamIntervalRef.current) } } }, [isStreaming, fetchFrame]) // Initial status fetch useEffect(() => { fetchStreamStatus() }, [fetchStreamStatus]) return (
{/* Header */}

Game View

{isStreaming && ( LIVE )}
{/* Screenshot Button */} {/* Stream Toggle */} {isStreaming ? ( ) : ( )}
{/* Game View Area */}
{error ? (

{error}

) : !isUnityOnline ? (

Unity Bridge offline

Starte den Server in Unity

) : !frameData ? (

Kein Bild verfügbar

{isPlaying ? 'Klicke "Stream" um die Spielansicht zu sehen' : 'Starte Play Mode und dann den Stream'}

) : ( // eslint-disable-next-line @next/next/no-img-element Unity Game View )} {/* Loading Overlay */} {isLoading && (
)}
{/* Status Bar */}
Resolution:{' '} {streamStatus ? `${streamStatus.width}x${streamStatus.height}` : '1280x720'} Quality:{' '} {streamStatus ? `${streamStatus.quality}%` : '75%'}
{isStreaming && ( <> FPS: {fps} Frames: {frameCount} )} {isUnityOnline ? 'Connected' : 'Disconnected'}
) }