flaskdockernew / app.py
MySafeCode's picture
Update app.py
9eb92c0 verified
Raw
History Blame
3.15 kB
import pygame, time, threading, base64, os
from flask import Flask, render_template_string
from flask_socketio import SocketIO, emit
from io import BytesIO
from PIL import Image
os.environ['SDL_VIDEODRIVER'] = 'dummy'
pygame.init()
WIDTH, HEIGHT = 400, 300 # Smaller for faster transfer
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode='threading')
# Shared state
shared = {"frame_count": 0, "streaming": True}
def game_loop():
"""Game loop that emits frames via WebSocket"""
screen = pygame.Surface((WIDTH, HEIGHT))
circle_x, circle_y = WIDTH//2, HEIGHT//2
speed_x, speed_y = 3, 2
while shared["streaming"]:
start = time.time()
# Update 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
screen.fill((25, 25, 45))
pygame.draw.circle(screen, (255, 80, 80), (int(circle_x), int(circle_y)), 20)
# Convert to JPEG (small, efficient)
frame_str = pygame.image.tostring(screen, 'RGB')
img = Image.frombytes('RGB', (WIDTH, HEIGHT), frame_str)
buf = BytesIO()
img.save(buf, format='JPEG', quality=85) # Smaller file
frame_b64 = base64.b64encode(buf.getvalue()).decode('utf-8')
# Emit to ALL connected clients
socketio.emit('new_frame', {
'frame': frame_b64,
'count': shared["frame_count"]
})
shared["frame_count"] += 1
# Control FPS
elapsed = time.time() - start
if elapsed < 1.0/30:
time.sleep(1.0/30 - elapsed)
HTML = '''<!DOCTYPE html>
<html>
<head>
<style>
body { background:#0f172a; color:white; text-align:center; padding:20px; }
#streamImg { border:3px solid #60a5fa; width:400px; height:300px; }
</style>
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"></script>
</head>
<body>
<h1>🎮 Real-time PyGame Stream</h1>
<img id="streamImg" src="">
<p>Frames: <span id="count">0</span></p>
<script>
const socket = io();
const img = document.getElementById('streamImg');
socket.on('connect', () => {
console.log('Connected to stream');
});
socket.on('new_frame', (data) => {
img.src = 'data:image/jpeg;base64,' + data.frame;
document.getElementById('count').textContent = data.count;
});
socket.on('disconnect', () => {
console.log('Disconnected');
});
</script>
</body>
</html>'''
@app.route('/')
def index():
return render_template_string(HTML)
if __name__ == '__main__':
# Start game loop in background
threading.Thread(target=game_loop, daemon=True).start()
# Start server
socketio.run(app,
host='0.0.0.0',
port=int(os.environ.get('PORT', 7860)),
debug=False,
allow_unsafe_werkzeug=True)