MySafeCode commited on
Commit
0f9e483
·
verified ·
1 Parent(s): 54b22e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -62
app.py CHANGED
@@ -12,43 +12,51 @@ pygame.init()
12
 
13
  WIDTH, HEIGHT = 800, 600
14
  shared = {
15
- "latest_frame": None,
16
  "frame_count": 0,
17
- "streaming": True
 
18
  }
19
 
20
- def capture_loop():
21
- """Simple game loop - creates surface ONCE"""
22
  screen = pygame.Surface((WIDTH, HEIGHT))
23
- circle_x, circle_y = WIDTH//2, HEIGHT//2
24
- speed_x, speed_y = 4, 3
 
 
 
 
25
 
26
  while shared["streaming"]:
27
- start_time = time.time()
28
-
29
- # Update position
30
- circle_x += speed_x
31
- circle_y += speed_y
32
- if circle_x < 30 or circle_x > WIDTH-30: speed_x *= -1
33
- if circle_y < 30 or circle_y > HEIGHT-30: speed_y *= -1
34
-
35
- # Draw on existing surface
36
- screen.fill((25, 25, 45))
37
- pygame.draw.circle(screen, (255, 80, 80), (int(circle_x), int(circle_y)), 30)
38
-
39
- # Convert to JPEG
40
- frame_str = pygame.image.tostring(screen, 'RGB')
41
- img = Image.frombytes('RGB', (WIDTH, HEIGHT), frame_str)
42
- buf = BytesIO()
43
- img.save(buf, format='JPEG', quality=85)
44
- shared["latest_frame"] = base64.b64encode(buf.getvalue()).decode('utf-8')
45
-
46
- shared["frame_count"] += 1
 
 
 
 
 
 
47
 
48
- # Control FPS
49
- elapsed = time.time() - start_time
50
- if elapsed < 1.0/30:
51
- time.sleep(1.0/30 - elapsed)
52
 
53
  app = Flask(__name__)
54
 
@@ -57,29 +65,59 @@ HTML = '''<html>
57
  <style>
58
  body { background:#0f172a; color:white; text-align:center; padding:20px; }
59
  #streamImg { border:3px solid #60a5fa; width:400px; height:300px; }
 
 
60
  </style>
61
  </head>
62
  <body>
63
- <h1>PyGame Stream</h1>
64
  <img id="streamImg" src="/stream">
65
- <p>Frames: <span id="count">0</span></p>
66
 
67
  <script>
 
 
68
  function updateStream() {
69
  const img = document.getElementById('streamImg');
70
- // ADD cache-busting timestamp
71
- img.src = '/stream?t=' + new Date().getTime();
72
 
73
- fetch('/stats')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  .then(r => r.json())
75
  .then(data => {
76
- document.getElementById('count').textContent = data.frame_count;
77
- });
 
 
 
 
 
 
 
 
 
 
78
  }
79
- // Update every 33ms (30 FPS)
80
- setInterval(updateStream, 33);
81
- // Start immediately
82
  updateStream();
 
 
83
  </script>
84
  </body>
85
  </html>'''
@@ -90,34 +128,53 @@ def index():
90
 
91
  @app.route('/stats')
92
  def stats():
93
- return {'frame_count': shared['frame_count']}
 
 
 
94
 
95
  @app.route('/stream')
96
  def stream():
97
- if shared['latest_frame']:
98
- frame_bytes = base64.b64decode(shared['latest_frame'])
99
- # ADD anti-cache headers
100
- return Response(
101
- frame_bytes,
102
- mimetype='image/jpeg',
103
- headers={
104
- 'Cache-Control': 'no-cache, no-store, must-revalidate',
105
- 'Pragma': 'no-cache',
106
- 'Expires': '0'
107
- }
108
- )
109
- return Response(b'', mimetype='image/jpeg')
 
 
 
 
 
 
 
 
110
 
111
  if __name__ == "__main__":
112
- # Start game thread
113
- thread = threading.Thread(target=capture_loop, daemon=True)
114
- thread.start()
 
 
 
 
 
 
 
 
115
 
116
- # Wait for first frame
117
- for _ in range(30):
118
- if shared['latest_frame']:
119
- break
120
- time.sleep(0.1)
121
 
122
  # Start server
123
  app.run(
 
12
 
13
  WIDTH, HEIGHT = 800, 600
14
  shared = {
15
+ "current_file": "frame_a.jpg",
16
  "frame_count": 0,
17
+ "streaming": True,
18
+ "last_switch": time.time()
19
  }
20
 
21
+ def pingpong_loop():
22
+ """Alternate between two files"""
23
  screen = pygame.Surface((WIDTH, HEIGHT))
24
+
25
+ # Two different colored circles
26
+ circles = [
27
+ {"x": 200, "y": 300, "color": (255, 80, 80), "size": 50}, # Red
28
+ {"x": 600, "y": 300, "color": (80, 180, 255), "size": 50} # Blue
29
+ ]
30
 
31
  while shared["streaming"]:
32
+ # Switch files every 0.5 seconds
33
+ current_time = time.time()
34
+ if current_time - shared["last_switch"] > 0.5:
35
+ if shared["current_file"] == "frame_a.jpg":
36
+ shared["current_file"] = "frame_b.jpg"
37
+ # Draw blue circle
38
+ screen.fill((25, 25, 45))
39
+ pygame.draw.circle(screen, circles[1]["color"],
40
+ (circles[1]["x"], circles[1]["y"]), circles[1]["size"])
41
+ else:
42
+ shared["current_file"] = "frame_a.jpg"
43
+ # Draw red circle
44
+ screen.fill((25, 25, 45))
45
+ pygame.draw.circle(screen, circles[0]["color"],
46
+ (circles[0]["x"], circles[0]["y"]), circles[0]["size"])
47
+
48
+ # Save to file
49
+ frame_str = pygame.image.tostring(screen, 'RGB')
50
+ img = Image.frombytes('RGB', (WIDTH, HEIGHT), frame_str)
51
+ img.save(shared["current_file"], quality=85)
52
+
53
+ shared["last_switch"] = current_time
54
+ shared["frame_count"] += 1
55
+
56
+ # Log to console
57
+ print(f"Switched to: {shared['current_file']} | Frame: {shared['frame_count']}")
58
 
59
+ time.sleep(0.1) # Check 10 times per second
 
 
 
60
 
61
  app = Flask(__name__)
62
 
 
65
  <style>
66
  body { background:#0f172a; color:white; text-align:center; padding:20px; }
67
  #streamImg { border:3px solid #60a5fa; width:400px; height:300px; }
68
+ .file-a { border-color: #ff5050 !important; }
69
+ .file-b { border-color: #50aaff !important; }
70
  </style>
71
  </head>
72
  <body>
73
+ <h1>PyGame Ping-Pong Test</h1>
74
  <img id="streamImg" src="/stream">
75
+ <p>Frame: <span id="count">0</span> | File: <span id="filename">none</span></p>
76
 
77
  <script>
78
+ let lastFrame = 0;
79
+
80
  function updateStream() {
81
  const img = document.getElementById('streamImg');
82
+ const timestamp = new Date().getTime();
 
83
 
84
+ // Force fresh request
85
+ fetch('/stream?_=' + timestamp)
86
+ .then(response => response.blob())
87
+ .then(blob => {
88
+ const url = URL.createObjectURL(blob);
89
+ img.src = url;
90
+
91
+ // Clean up previous blob URL
92
+ if (img.dataset.lastUrl) {
93
+ URL.revokeObjectURL(img.dataset.lastUrl);
94
+ }
95
+ img.dataset.lastUrl = url;
96
+
97
+ // Update stats
98
+ return fetch('/stats?_=' + timestamp);
99
+ })
100
  .then(r => r.json())
101
  .then(data => {
102
+ if (data.frame_count !== lastFrame) {
103
+ document.getElementById('count').textContent = data.frame_count;
104
+ document.getElementById('filename').textContent = data.current_file;
105
+
106
+ // Visual feedback
107
+ img.className = data.current_file === 'frame_a.jpg' ? 'file-a' : 'file-b';
108
+
109
+ console.log(`New frame: ${data.frame_count} (${data.current_file})`);
110
+ lastFrame = data.frame_count;
111
+ }
112
+ })
113
+ .catch(err => console.log('Error:', err));
114
  }
115
+
116
+ // Update every 100ms (10 FPS)
117
+ setInterval(updateStream, 100);
118
  updateStream();
119
+
120
+ console.log('Ping-pong test started');
121
  </script>
122
  </body>
123
  </html>'''
 
128
 
129
  @app.route('/stats')
130
  def stats():
131
+ return {
132
+ 'frame_count': shared['frame_count'],
133
+ 'current_file': shared['current_file']
134
+ }
135
 
136
  @app.route('/stream')
137
  def stream():
138
+ try:
139
+ if os.path.exists(shared["current_file"]):
140
+ with open(shared["current_file"], 'rb') as f:
141
+ frame_bytes = f.read()
142
+
143
+ return Response(
144
+ frame_bytes,
145
+ mimetype='image/jpeg',
146
+ headers={
147
+ 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
148
+ 'Pragma': 'no-cache',
149
+ 'Expires': '0',
150
+ 'Last-Modified': time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime())
151
+ }
152
+ )
153
+ except Exception as e:
154
+ print(f"Stream error: {e}")
155
+
156
+ # Return a small black image as fallback
157
+ fallback = base64.b64decode('/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCdABmX/9k=')
158
+ return Response(fallback, mimetype='image/jpeg')
159
 
160
  if __name__ == "__main__":
161
+ # Create initial files
162
+ screen = pygame.Surface((WIDTH, HEIGHT))
163
+ screen.fill((25, 25, 45))
164
+ pygame.draw.circle(screen, (255, 80, 80), (200, 300), 50)
165
+ img = Image.frombytes('RGB', (WIDTH, HEIGHT), pygame.image.tostring(screen, 'RGB'))
166
+ img.save("frame_a.jpg", quality=85)
167
+
168
+ screen.fill((25, 25, 45))
169
+ pygame.draw.circle(screen, (80, 180, 255), (600, 300), 50)
170
+ img = Image.frombytes('RGB', (WIDTH, HEIGHT), pygame.image.tostring(screen, 'RGB'))
171
+ img.save("frame_b.jpg", quality=85)
172
 
173
+ print("Created initial files: frame_a.jpg (red) and frame_b.jpg (blue)")
174
+
175
+ # Start ping-pong thread
176
+ thread = threading.Thread(target=pingpong_loop, daemon=True)
177
+ thread.start()
178
 
179
  # Start server
180
  app.run(