Mohammedkarnoub071/liveStream
0
1from flask import Flask, Response, request2from io import BytesIO3import threading4from PIL import Image, ImageDraw, ImageFont5import time6import logging7 8app = Flask(__name__)9 10# إعدادات البث11IMAGE_WIDTH = 32012IMAGE_HEIGHT = 24013BUFFER_SIZE = 114frame_buffer = []15buffer_lock = threading.Lock()16 17# إنشاء صورة بديلة18def create_placeholder():19 img = Image.new('RGB', (IMAGE_WIDTH, IMAGE_HEIGHT), '#222')20 draw = ImageDraw.Draw(img)21 text = "Waiting for stream..."22 font = ImageFont.load_default()23 draw.text((10, IMAGE_HEIGHT//2), text, fill="#fff", font=font)24 buf = BytesIO()25 img.save(buf, format='JPEG', quality=10)26 return buf.getvalue()27 28@app.route('/stream')29def stream():30 """نقطة النهاية للبث المباشر مع التحديث التلقائي"""31 def generate():32 while True:33 with buffer_lock:34 frame = frame_buffer[-1] if frame_buffer else create_placeholder()35 36 # استخدام multipart/x-mixed-replace للتحديث التلقائي37 yield (b'--frame\r\n'38 b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')39 40 time.sleep(0.1) # ~10 FPS41 42 return Response(generate(),43 mimetype='multipart/x-mixed-replace; boundary=frame')44 45@app.route('/upload', methods=['POST'])46def upload():47 """استقبال الإطارات من ESP32-CAM"""48 if request.data:49 with buffer_lock:50 if len(frame_buffer) >= BUFFER_SIZE:51 frame_buffer.pop(0)52 frame_buffer.append(request.data)53 return "OK", 20054 return "No data", 40055 56@app.route('/')57def index():58 """واجهة ويب بسيطة للعرض فقط"""59 return """60 <!DOCTYPE html>61 <html>62 <head>63 <meta charset="UTF-8">64 <meta name="viewport" content="width=device-width, initial-scale=1.0">65 <title>ESP32-CAM Live Stream</title>66 <style>67 body { margin: 0; background: #000; }68 img { display: block; width: 100vw; height: 100vh; object-fit: contain; }69 </style>70 </head>71 <body>72 <img src="/stream">73 </body>74 </html>75 """76 77if __name__ == '__main__':78 app.run(host='0.0.0.0', port=7860)