| | import cv2 |
| | import numpy as np |
| | from nes_py import NESEnv |
| | from flask import Flask, Response, render_template_string |
| | import time |
| | import os |
| |
|
| | |
| | app = Flask(__name__) |
| |
|
| | |
| | running = False |
| | reset_flag = False |
| |
|
| | |
| | rom_path = "/home/ubuntu/mario/Super Mario Bros.nes" |
| |
|
| | |
| | try: |
| | env = NESEnv(rom_path) |
| | obs = env.reset() |
| | done = False |
| | print("NES environment initialized successfully with ROM:", rom_path) |
| | except Exception as e: |
| | print("Error initializing NES environment:", e) |
| | exit(1) |
| |
|
| | |
| | def generate_frames(): |
| | global running, reset_flag, done, obs |
| | frame_time = 1 / 30.0 |
| | print("Starting frame generation loop...") |
| | while running: |
| | start = time.time() |
| | if reset_flag: |
| | obs = env.reset() |
| | reset_flag = False |
| | done = False |
| | print("Game reset to title screen") |
| | if done: |
| | obs = env.reset() |
| | done = False |
| | print("Game reset due to done state") |
| | |
| | obs, reward, done, info = env.step(0) |
| | print("Step executed, Reward:", reward, "Done:", done) |
| | |
| | frame = env.get_image() |
| | if frame is None: |
| | print("Warning: Frame is None!") |
| | time.sleep(frame_time) |
| | continue |
| | frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) |
| | print("Captured frame shape:", frame.shape) |
| | |
| | ret, buffer = cv2.imencode('.jpg', frame) |
| | if not ret: |
| | print("Warning: Failed to encode frame!") |
| | time.sleep(frame_time) |
| | continue |
| | frame_bytes = buffer.tobytes() |
| | yield (b'--frame\r\n' |
| | b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n') |
| | elapsed = time.time() - start |
| | if elapsed < frame_time: |
| | time.sleep(frame_time - elapsed) |
| | print("Frame sent, elapsed time:", elapsed) |
| |
|
| | |
| | @app.route('/video_feed') |
| | def video_feed(): |
| | if not running: |
| | return "Stream not running", 503 |
| | return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame') |
| |
|
| | |
| | @app.route('/') |
| | def index(): |
| | return render_template_string(''' |
| | <!DOCTYPE html> |
| | <html> |
| | <head> |
| | <title>Mario Title Screen Stream</title> |
| | <style> |
| | body { background: #1e1e1e; color: white; font-family: Arial, sans-serif; text-align: center; } |
| | img { border: 2px solid #00ff00; } |
| | </style> |
| | </head> |
| | <body> |
| | <h1>Mario Title Screen Live Stream</h1> |
| | <img src="/video_feed" width="256" height="240"> |
| | </body> |
| | </html> |
| | ''') |
| |
|
| | |
| | if __name__ == "__main__": |
| | print("Starting Flask server on http://0.0.0.0:5111...") |
| | running = True |
| | try: |
| | app.run(host='0.0.0.0', port=5111, debug=True, use_reloader=False) |
| | except KeyboardInterrupt: |
| | print("Stopping the stream...") |
| | running = False |