File size: 3,221 Bytes
f10370d
a69de24
62c200f
a8b0b5f
19dff2a
cb56c4a
a8b0b5f
 
 
f10370d
a69de24
 
ab8eba2
a69de24
62c200f
 
 
 
a8b0b5f
 
 
 
62c200f
 
 
ab8eba2
 
62c200f
ab8eba2
 
 
 
a8b0b5f
 
 
ab8eba2
 
 
a8b0b5f
 
ab8eba2
 
 
a8b0b5f
ab8eba2
a8b0b5f
ab8eba2
 
 
f10370d
ab8eba2
f10370d
11ab6b8
f10370d
11ab6b8
a69de24
 
11ab6b8
 
f10370d
62c200f
 
 
f10370d
ab8eba2
42c920a
ab8eba2
42c920a
 
62c200f
42c920a
 
 
 
 
 
 
ab8eba2
 
19dff2a
42c920a
f10370d
11ab6b8
a8b0b5f
f10370d
11ab6b8
 
7c2ccb3
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import streamlit as st
import cv2  # OpenCV for image processing
import numpy as np
import av  # REQUIRED: Must be in requirements.txt (pip install av)
from streamlit_webrtc import webrtc_streamer, VideoProcessorBase, WebRtcMode 

# --- PLACEHOLDER IMPORTS (Adjust as needed) ---
# NOTE: The logic here is temporarily simplified to test WebRTC stability.
# The heavy imports (deepface, etc.) should be outside the cached function.

# --- CONFIGURATION ---
RECOGNITION_THRESHOLD = 0.6
FRAME_SKIP = 3


# --- CRITICAL FIX 1: CACHE THE HEAVY MODELS SEPARATELY ---
@st.cache_resource
def load_deepface_models():
    """Loads all heavy models only once, safely outside the thread."""
    # NOTE: Keep your actual heavy model loading logic here (e.g., DeepFace.build_model)
    # This function is retained to verify if the issue is in the loading itself.
    return "LOADED_MODELS_PLACEHOLDER" 


# --- CRITICAL FIX 2: CACHE THE FACTORY ---
@st.cache_resource
def get_face_processor_factory():
    """Returns the processor class, ensuring its initialization is thread-safe."""
    
    class FaceRecognitionProcessor(VideoProcessorBase):
        """Processes video frames using the standard VideoProcessorBase."""
        def __init__(self):
            # We call the model loading function, but we won't use the result in recv
            # This tests if the memory consumption is the issue.
            self.models_placeholder = load_deepface_models() 
            self.frame_count = 0
            
        def recv(self, frame: av.VideoFrame) -> av.VideoFrame:
            # --- SIMPLIFIED PROCESSING LOGIC (TEMPORARY DEBUGGING) ---
            
            # Convert frame from av.VideoFrame to numpy array (BGR)
            img = frame.to_ndarray(format="bgr24")
            
            # Simple, lightweight OpenCV draw operation for verification
            h, w, _ = img.shape
            cv2.putText(img, "WebRTC OK", (10, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 2)
            
            # Convert back to av.VideoFrame before returning
            return av.VideoFrame.from_ndarray(img, format="bgr24")

    return FaceRecognitionProcessor

# --- STREAMLIT UI ---

def main():
    global RECOGNITION_THRESHOLD
    
    st.title("Smart Office Face Recognition System 📸")
    st.sidebar.title("Configuration")

    RECOGNITION_THRESHOLD = st.sidebar.slider(
        "Recognition Threshold", min_value=0.0, max_value=1.0, value=0.6, step=0.05
    )

    # --- FINAL WEBRTC STREAMER CALL ---
    webrtc_streamer(
        key="face-recognition-stream-final-cache",  
        mode=WebRtcMode.SENDRECV,
        
        # --- Enhanced STUN/TURN configuration to stabilize cloud connection ---
        rtc_configuration={
            "iceServers": [
                {"urls": ["stun:stun.l.google.com:19302"]},
                {"urls": ["stun:stun.services.mozilla.com"]}
            ]
        },
        
        # Use the CACHED factory function
        video_processor_factory=get_face_processor_factory,  
        async_processing=True                                
    )

    st.markdown("---")
    st.subheader("Access Log (Placeholder)")

# --- EXECUTION ---
if __name__ == "__main__":
    main()