Spaces:
Sleeping
Sleeping
File size: 3,188 Bytes
5a7e0d5 491b00e 7076238 491b00e 5a7e0d5 491b00e 5a7e0d5 491b00e 5a7e0d5 491b00e 5a7e0d5 7076238 5a7e0d5 491b00e 5a7e0d5 491b00e 5a7e0d5 491b00e 5a7e0d5 42c9d28 5a7e0d5 491b00e 42c9d28 5a7e0d5 491b00e 42c9d28 7076238 5a7e0d5 9eb92c0 7076238 491b00e 5a7e0d5 9eb92c0 5a7e0d5 9eb92c0 5a7e0d5 9eb92c0 491b00e 9eb92c0 491b00e 5a7e0d5 9eb92c0 5a7e0d5 | 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 | import pygame
import time
import threading
import base64
import os
from flask import Flask, Response, render_template_string
from io import BytesIO
from PIL import Image
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.init()
WIDTH, HEIGHT = 800, 600
shared = {
"latest_frame": None,
"frame_count": 0,
"streaming": True
}
def capture_loop():
"""Simple game loop that updates a frame"""
screen = pygame.Surface((WIDTH, HEIGHT))
circle_x, circle_y = WIDTH//2, HEIGHT//2
speed_x, speed_y = 4, 3
while shared["streaming"]:
start_time = time.time()
# Update circle position
circle_x += speed_x
circle_y += speed_y
if circle_x < 30 or circle_x > WIDTH-30:
speed_x *= -1
if circle_y < 30 or circle_y > HEIGHT-30:
speed_y *= -1
# Draw on the surface
screen.fill((25, 25, 45))
pygame.draw.circle(screen, (255, 80, 80), (int(circle_x), int(circle_y)), 30)
# Convert to JPEG using PIL
frame_str = pygame.image.tostring(screen, 'RGB')
img = Image.frombytes('RGB', (WIDTH, HEIGHT), frame_str)
buf = BytesIO()
img.save(buf, format='JPEG', quality=85)
shared["latest_frame"] = base64.b64encode(buf.getvalue()).decode('utf-8')
shared["frame_count"] += 1
# Control frame rate
elapsed = time.time() - start_time
if elapsed < 1.0/30:
time.sleep(1.0/30 - elapsed)
app = Flask(__name__)
HTML = '''<html>
<head>
<style>
body { background:#0f172a; color:white; text-align:center; padding:20px; }
#streamImg { border:3px solid #60a5fa; width:400px; height:300px; }
</style>
</head>
<body>
<h1>PyGame Stream</h1>
<img id="streamImg" src="/stream">
<p>Frames: <span id="count">0</span></p>
<script>
function updateStream() {
const img = document.getElementById('streamImg');
img.src = '/stream?_=' + Date.now();
fetch('/stats')
.then(r => r.json())
.then(data => {
document.getElementById('count').textContent = data.frame_count;
});
}
// Update every 33ms (~30 FPS)
setInterval(updateStream, 33);
updateStream(); // Initial call
</script>
</body>
</html>'''
@app.route('/')
def index():
return render_template_string(HTML)
@app.route('/stats')
def stats():
return {'frame_count': shared['frame_count']}
@app.route('/stream')
def stream():
if shared['latest_frame']:
frame_bytes = base64.b64decode(shared['latest_frame'])
return Response(frame_bytes, mimetype='image/jpeg')
return Response(b'', mimetype='image/jpeg')
if __name__ == "__main__":
# Start game thread
thread = threading.Thread(target=capture_loop, daemon=True)
thread.start()
# Wait for first frame
for _ in range(50):
if shared['latest_frame']:
break
time.sleep(0.1)
# Start server
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 7860)), debug=False, threaded=True) |