from flask import Flask, render_template, Response, request
import cv2
import json
import time
import threading

app = Flask(__name__)

camera_urls = {
    '581FG06': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/102',
    '581FG05': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/202',
    '581FG02': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/902',
    '581BE02': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/402',
    '581BE01': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/902',
    '581FG01': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/602',
    '581FG04': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/702',
    '581FG03': 'rtsp://admin:longson9999@115.75.221.184:554/Streaming/Channels/802',
    'bancan11': 'rtsp://admin:longson2016@192.168.15.99:554/Streaming/Channels/102',
    'bancan12': 'rtsp://admin:longson2016@192.168.15.99:554/Streaming/Channels/202',
    'bancan21': 'rtsp://admin:longson2016@192.168.15.99:554/Streaming/Channels/302',
    'bancan22': 'rtsp://admin:longson2016@192.168.15.99:554/Streaming/Channels/402',
}

camera_client_counts = {}
camera_threads = {}
camera_frames = {}
def clear_camera_cache(camera_id):
    if camera_id in camera_frames:
        del camera_frames[camera_id]
        print(f"Đã xóa cache cho camera {camera_id}")
def generate_frames(rtsp_url, camera_id, interval=0.1):
    cap = cv2.VideoCapture(rtsp_url)
    cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)  # Thiết lập kích thước buffer

    if not cap.isOpened():
        print(f"Không thể kết nối với {rtsp_url}. Đang thử lại sau 5 giây...")
        cap.release()
        time.sleep(5)
        return

    last_frame_time = time.time()

    while True:
        success, frame = cap.read()
        if not success:
            print(f"Mất kết nối với {rtsp_url}. Đang thử lại...")
            cap.release()
            time.sleep(5)
            cap = cv2.VideoCapture(rtsp_url)
            continue

        current_time = time.time()
        elapsed_time = current_time - last_frame_time
        frame = cv2.resize(frame, (640, 320))  # Giảm độ phân giải
        if elapsed_time >= interval:
            last_frame_time = current_time
            _, buffer = cv2.imencode('.jpg', frame)
            frame = buffer.tobytes()
            camera_frames[camera_id] = frame

        time.sleep(0.01)

    cap.release()

@app.route('/')
def index():
    camera_ids = request.args.getlist('id')  # Lấy danh sách id camera từ query string
    return render_template('index.html', camera_ids_json=json.dumps(camera_ids))

@app.route('/video_feed')
def video_feed():
    camera_id = request.args.get('id', default='581FG06', type=str)  # Lấy id camera từ query string
    rtsp_url = camera_urls.get(camera_id, '')  # Lấy URL RTSP từ camera_id

    if rtsp_url:
        if camera_id not in camera_threads:
            # Start a new thread for this camera
            thread = threading.Thread(target=generate_frames, args=(rtsp_url, camera_id))
            thread.daemon = True
            thread.start()
            camera_threads[camera_id] = thread
        if camera_id in camera_client_counts:
            camera_client_counts[camera_id] += 1
        else:
            camera_client_counts[camera_id] = 1
        def generate_response():
            while True:
                frame = camera_frames.get(camera_id)
                if frame:
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
                time.sleep(0.1)  # Thay đổi độ trễ nếu cần
        def cleanup_client():
            if camera_id in camera_client_counts:
                camera_client_counts[camera_id] -= 1
                if camera_client_counts[camera_id] == 0:
                    clear_camera_cache(camera_id)  # Xóa cache khi không còn client nào
                    del camera_client_counts[camera_id]  # Xóa khỏi dictionary

        response = Response(generate_response(), mimetype='multipart/x-mixed-replace; boundary=frame')

        # Đảm bảo xóa cache khi client ngắt kết nối
        response.call_on_close(cleanup_client)
        return response
    else:
        return "Camera không tồn tại", 404

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)
#python -m waitress --listen=0.0.0.0:5000 --threads=16 app:app

###chaycode
#pip install waitress
#python -m waitress --listen=0.0.0.0:5000 app:app