# app.py — PS3 Eye + Flask — FINAL, LED STAYS ON, 60 fps from flask import Flask, Response, render_template_string import cv2 import time import numpy as np app = Flask(__name__) # ←←← CAMERA IS NO LONGER GLOBAL — created on first use camera = None def get_camera(): global camera if camera is None or not camera.isOpened(): print("Initializing PS3 Eye (index 2, V4L2)...") camera = cv2.VideoCapture(2, cv2.CAP_V4L2) if not camera.isOpened(): raise RuntimeError("Cannot open PS3 Eye") camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M','J','P','G')) camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640) camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) camera.set(cv2.CAP_PROP_FPS, 60) camera.set(cv2.CAP_PROP_BUFFERSIZE, 1) # Wake-up sequence — LED turns on here and stays on print("Warming up camera — LED should turn ON now...") for i in range(60): ret, _ = camera.read() if ret and i == 30: print("Camera alive — LED ON permanently") time.sleep(0.5) w = camera.get(cv2.CAP_PROP_FRAME_WIDTH) h = camera.get(cv2.CAP_PROP_FRAME_HEIGHT) fps = camera.get(cv2.CAP_PROP_FPS) print(f"Camera initialized → {w}x{h} @ {fps} fps") return camera frame_counter = 0 last_time = time.time() def generate_frames(): global frame_counter, last_time cam = get_camera() # ← ensures camera exists and is warm while True: success, frame = cam.read() if not success: frame = np.zeros((480, 640, 3), np.uint8) cv2.putText(frame, "NO FRAME", (100, 240), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,0,255), 5) else: now = time.time() if now - last_time >= 1.0: print(f"Live → ~{frame_counter/(now-last_time):.1f} fps") frame_counter = 0 last_time = now frame_counter += 1 ret, buffer = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), 82]) yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n') @app.route('/') def index(): return render_template_string(''' PS3 Eye — 60 fps Live

PS3 Eye — 640×480 @ 60 fps

LED should stay ON permanently

''') @app.route('/video_feed') def video_feed(): return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame') # Only release when the entire Python process exits import atexit atexit.register(lambda: camera.release() if camera and camera.isOpened() else None) if __name__ == '__main__': try: app.run(host='0.0.0.0', port=5000, threaded=True) finally: if camera and camera.isOpened(): camera.release() print("Camera released on shutdown")