import cv2
import websocket
import struct
import time
import json
import threading

# --- 配置 ---
# 替换为您的服务器地址
WS_URL = "ws://192.168.1.28/ws/" 
# 替换为您的 API Key，本地部署apikey可以设置为空
API_KEY = "sk-ignis-2DBwKz7-gbQJ412UFCj6-uWZ_NIdBrFG"

def on_message(ws, message):
    """处理服务器返回的分析结果"""
    try:
        data = json.loads(message)
        # 这里只打印心率和情绪，您可以根据需要提取更多数据，开始几秒心率数据还没有
        print(f"收到数据: 心率: {data.get('hrv', {}).get('meanHr', '计算中...')} | 情绪: {data.get('emotion_short_res', '分析中...')}")
    except Exception as e:
        print(f"数据解析错误: {e}")

def on_error(ws, error):
    print(f"WS 错误: {error}")

def on_close(ws, close_status_code, close_msg):
    print("连接已关闭")

def on_open(ws):
    print("WS 连接成功，开始发送视频流...")
    
    # 在单独线程中运行视频采集，以免阻塞 WebSocket 接收
    def run_camera():
        cap = cv2.VideoCapture(0) # 0 代表默认摄像头
        
        # 降低分辨率以提高传输速度 (参考 monitoring.js 的默认 640x480)
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

        while ws.sock and ws.sock.connected:
            ret, frame = cap.read()
            if not ret:
                break

            # 1. 压缩图片为 JPEG
            _, jpeg_data = cv2.imencode('.jpg', frame, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
            jpeg_bytes = jpeg_data.tobytes()

            # 2. 构建协议头 (参考 monitoring.js)
            # 格式: [1字节 类型(0=视频)] + [8字节 时间戳(Double, 小端)] + [JPEG数据]
            timestamp = time.time()
            header = struct.pack('<Bd', 0, timestamp) # < 代表小端模式, B=uchar, d=double

            # 3. 发送二进制数据
            try:
                ws.send(header + jpeg_bytes, opcode=websocket.ABNF.OPCODE_BINARY)
            except Exception as e:
                print(f"发送失败: {e}")
                break
            
            # 控制帧率 (约30fps)
            time.sleep(0.033)

        cap.release()
        print("摄像头已关闭")

    threading.Thread(target=run_camera).start()

if __name__ == "__main__":
    # 构建带 Token 的 URL
    target_url = f"{WS_URL}?token={API_KEY}"
    
    ws = websocket.WebSocketApp(target_url,
                                on_open=on_open,
                                on_message=on_message,
                                on_error=on_error,
                                on_close=on_close)
    
    ws.run_forever()