#!/usr/bin/env python3
# minimal_working.py - Simple guaranteed working version
import pygame
import time
import threading
import base64
import os
from flask import Flask, Response
import numpy
# ===== 1. BASIC SETUP =====
os.environ['SDL_VIDEODRIVER'] = 'dummy'
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'
# Hugging Face uses port 7860
PORT = int(os.getenv('PORT', 7860))
# Simple shared state
shared = {
"latest_frame": None,
"frame_count": 0,
"streaming": True
}
# ===== 2. CREATE FLASK APP =====
app = Flask(__name__)
# ===== 3. SIMPLE HTML =====
HTML = '''
PyGame Stream
PyGame Stream - WORKING
Frames: 0
Status: Loading...
'''
@app.route('/')
def index():
return HTML
@app.route('/stats')
def stats():
return {'frame_count': shared['frame_count']}
@app.route('/stream')
def stream():
"""Simple stream endpoint that definitely works"""
if shared['latest_frame']:
try:
# Decode and serve
image_data = base64.b64decode(shared['latest_frame'])
return Response(
image_data,
mimetype='image/png', # Use PNG for reliability
headers={
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': '0'
}
)
except Exception as e:
print(f"Stream error: {e}")
# Return a simple test image
return create_test_image()
# No frame yet
return create_test_image()
def create_test_image():
"""Create a simple test image that definitely works"""
# Create a 2x2 pixel red image as fallback
test_image = base64.b64decode('iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAFElEQVR4nGJ89eoVAwMDIyMjAwMDAAY4AWWBtBcPAAAAAElFTkSuQmCC')
return Response(
test_image,
mimetype='image/png',
headers={'Cache-Control': 'no-cache'}
)
# ===== 4. SIMPLE CAPTURE LOOP =====
def simple_capture():
"""Simple guaranteed-working capture loop"""
try:
pygame.init()
print("✅ PyGame initialized")
except Exception as e:
print(f"PyGame init error: {e}")
return
# Create surface
W, H = 400, 300
surface = pygame.Surface((W, H))
# Simple animation
x, y = W//2, H//2
dx, dy = 3, 2
print("🎬 Starting capture...")
while shared["streaming"]:
try:
# Clear with black
surface.fill((0, 0, 0))
# Update position
x += dx
y += dy
# Bounce
if x < 20 or x > W-20:
dx = -dx
if y < 20 or y > H-20:
dy = -dy
# Draw a moving rectangle
pygame.draw.rect(surface, (255, 0, 0), (x-20, y-20, 40, 40))
# Draw frame number
font = pygame.font.Font(None, 36)
text = font.render(f"Frame: {shared['frame_count']}", True, (255, 255, 255))
surface.blit(text, (10, 10))
# Draw time
time_text = font.render(time.strftime("%H:%M:%S"), True, (200, 200, 255))
surface.blit(time_text, (10, 50))
# Save to buffer
import io
buffer = io.BytesIO()
pygame.image.save(surface, buffer, 'PNG') # Use PNG for reliability
buffer.seek(0)
# Encode and store
shared["latest_frame"] = base64.b64encode(buffer.getvalue()).decode('utf-8')
shared["frame_count"] += 1
# Log every 30 frames
if shared['frame_count'] % 30 == 0:
print(f"Frame {shared['frame_count']} captured")
# Control frame rate
time.sleep(1/30) # 30 FPS
except Exception as e:
print(f"Capture error: {e}")
break
pygame.quit()
print("Capture stopped")
# ===== 5. MAIN =====
def main():
print("="*50)
print("🚀 Starting PyGame + Flask (MINIMAL WORKING VERSION)")
print(f"📡 Port: {PORT}")
print("="*50)
# Start capture thread
thread = threading.Thread(target=simple_capture, daemon=True)
thread.start()
# Give it time to start
time.sleep(1)
# Start Flask
print("🌐 Starting Flask server...")
try:
app.run(
host='0.0.0.0',
port=PORT,
debug=False,
threaded=True,
use_reloader=False
)
except Exception as e:
print(f"Server error: {e}")
finally:
shared['streaming'] = False
thread.join(timeout=2)
print(f"Total frames: {shared['frame_count']}")
print("✅ Done")
if __name__ == "__main__":
main()