Testimony Adekoya commited on
Commit
f4fd68f
·
1 Parent(s): b94e066

Pushing code for rtc loading

Browse files
Files changed (1) hide show
  1. pages/1_Live_Detection.py +37 -46
pages/1_Live_Detection.py CHANGED
@@ -17,8 +17,6 @@ from src.alerting.alert_system import get_alerter
17
  def load_app_config():
18
  """Loads config from yaml and .env files."""
19
  load_dotenv()
20
- gemini_api_key = os.getenv("GEMINI_API_KEY")
21
- # Navigate up to the root to find the config file
22
  config_path = "/config.yaml" if os.path.exists("/config.yaml") else "config.yaml"
23
  with open(config_path, 'r') as f:
24
  config = yaml.safe_load(f)
@@ -32,11 +30,11 @@ def load_app_config():
32
 
33
  config, secrets = load_app_config()
34
 
35
- # --- Initialize Session State (if not already done in main.py) ---
36
- if "play_audio" not in st.session_state:
37
- st.session_state.play_audio = None
38
- if "active_alerts" not in st.session_state:
39
- st.session_state.active_alerts = {"status": "Awake"}
40
 
41
  # --- Client-Side Audio Playback Function ---
42
  def autoplay_audio(audio_bytes: bytes):
@@ -51,7 +49,10 @@ def autoplay_audio(audio_bytes: bytes):
51
 
52
  # --- WebRTC Video Processor ---
53
  class VideoProcessor(VideoProcessorBase):
54
- def __init__(self):
 
 
 
55
  self._detector = get_detector(config)
56
  self._alerter = get_alerter(config, secrets["gemini_api_key"])
57
 
@@ -61,24 +62,24 @@ class VideoProcessor(VideoProcessorBase):
61
  strategy = config.get('detection_strategy')
62
  if strategy == 'hybrid':
63
  processed_frame, alert_triggered, active_alerts = self._detector.process_frame(img)
64
- st.session_state.active_alerts = active_alerts if alert_triggered else {"status": "Awake"}
65
- else: # Fallback for simpler strategies
 
66
  processed_frame, indicators = self._detector.process_frame(img)
67
- alert_triggered = any(indicators.values())
68
- st.session_state.active_alerts = indicators if alert_triggered else {"status": "Awake"}
69
 
70
  if alert_triggered:
71
  audio_data = self._alerter.trigger_alert()
72
  if audio_data:
73
- st.session_state.play_audio = audio_data
 
74
  else:
75
  self._alerter.reset_alert()
76
 
77
  return av.VideoFrame.from_ndarray(processed_frame, format="bgr24")
78
 
79
  # --- Page UI ---
80
- # The st.set_page_config() call has been removed from this file.
81
- # The configuration from main.py will apply to this page.
82
  st.title("📹 Live Drowsiness Detection")
83
  st.info("Press 'START' to activate your camera and begin monitoring.")
84
 
@@ -87,16 +88,8 @@ ice_servers = [{'urls': 'stun:global.stun.twilio.com:3478'}]
87
  if secrets["turn_username"] and secrets["turn_credential"]:
88
  print("TURN credentials found, adding TURN servers to config.")
89
  turn_servers = [
90
- {
91
- 'urls': 'turn:global.turn.twilio.com:3478?transport=udp',
92
- 'username': secrets["turn_username"],
93
- 'credential': secrets["turn_credential"]
94
- },
95
- {
96
- 'urls': 'turn:global.turn.twilio.com:3478?transport=tcp',
97
- 'username': secrets["turn_username"],
98
- 'credential': secrets["turn_credential"]
99
- }
100
  ]
101
  ice_servers.extend(turn_servers)
102
 
@@ -108,8 +101,12 @@ col1, col2 = st.columns([3, 1])
108
  with col1:
109
  webrtc_ctx = webrtc_streamer(
110
  key="drowsiness-detection",
111
- video_processor_factory=VideoProcessor,
112
- rtc_configuration=RTC_CONFIGURATION, # Use the new robust configuration
 
 
 
 
113
  media_stream_constraints={"video": True, "audio": False},
114
  async_processing=True,
115
  )
@@ -126,25 +123,18 @@ with col2:
126
  audio_placeholder = st.empty()
127
 
128
  if webrtc_ctx.state.playing:
129
- # --- Polling Loop ---
 
 
130
  try:
 
131
  status_result = st.session_state.status_queue.get(timeout=0.1)
 
132
  except queue.Empty:
133
- status_result = None
134
 
135
- # Check for new audio alerts
136
- try:
137
- audio_data = st.session_state.audio_queue.get(timeout=0.1)
138
- except queue.Empty:
139
- audio_data = None
140
-
141
  with status_placeholder.container():
142
- # Persist the last known status if there's no new one
143
- if status_result:
144
- st.session_state.last_status = status_result
145
-
146
- last_status = getattr(st.session_state, 'last_status', {"status": "Awake"})
147
-
148
  if last_status.get("Low Light"):
149
  st.warning("⚠️ Low Light Detected! Accuracy may be affected.")
150
  elif last_status.get("status") == "Awake":
@@ -152,17 +142,18 @@ if webrtc_ctx.state.playing:
152
  else:
153
  st.error("🚨 DROWSINESS DETECTED!")
154
  for key, value in last_status.items():
155
- if key != "Low Light":
156
  st.warning(f"-> {key}: {value:.2f}" if isinstance(value, float) else f"-> {key}")
157
 
158
- if audio_data:
 
159
  with audio_placeholder.container():
160
  autoplay_audio(audio_data)
161
-
162
- # Force a rerun to keep the polling active
 
163
  time.sleep(0.1)
164
  st.rerun()
165
-
166
  else:
167
  with status_placeholder.container():
168
  st.info("✔️ Driver is Awake")
 
17
  def load_app_config():
18
  """Loads config from yaml and .env files."""
19
  load_dotenv()
 
 
20
  config_path = "/config.yaml" if os.path.exists("/config.yaml") else "config.yaml"
21
  with open(config_path, 'r') as f:
22
  config = yaml.safe_load(f)
 
30
 
31
  config, secrets = load_app_config()
32
 
33
+ # --- Initialize Session State for Queues at the TOP of the script ---
34
+ if "status_queue" not in st.session_state:
35
+ st.session_state.status_queue = queue.Queue()
36
+ if "audio_queue" not in st.session_state:
37
+ st.session_state.audio_queue = queue.Queue()
38
 
39
  # --- Client-Side Audio Playback Function ---
40
  def autoplay_audio(audio_bytes: bytes):
 
49
 
50
  # --- WebRTC Video Processor ---
51
  class VideoProcessor(VideoProcessorBase):
52
+ # The __init__ method now accepts the queues as arguments
53
+ def __init__(self, status_queue: queue.Queue, audio_queue: queue.Queue):
54
+ self.status_queue = status_queue
55
+ self.audio_queue = audio_queue
56
  self._detector = get_detector(config)
57
  self._alerter = get_alerter(config, secrets["gemini_api_key"])
58
 
 
62
  strategy = config.get('detection_strategy')
63
  if strategy == 'hybrid':
64
  processed_frame, alert_triggered, active_alerts = self._detector.process_frame(img)
65
+ # Use self.status_queue.put() instead of st.session_state
66
+ self.status_queue.put(active_alerts if alert_triggered or 'Low Light' in active_alerts else {"status": "Awake"})
67
+ else:
68
  processed_frame, indicators = self._detector.process_frame(img)
69
+ alert_triggered = any(v for k, v in indicators.items() if k != 'low_light')
70
+ self.status_queue.put(indicators)
71
 
72
  if alert_triggered:
73
  audio_data = self._alerter.trigger_alert()
74
  if audio_data:
75
+ # Use self.audio_queue.put()
76
+ self.audio_queue.put(audio_data)
77
  else:
78
  self._alerter.reset_alert()
79
 
80
  return av.VideoFrame.from_ndarray(processed_frame, format="bgr24")
81
 
82
  # --- Page UI ---
 
 
83
  st.title("📹 Live Drowsiness Detection")
84
  st.info("Press 'START' to activate your camera and begin monitoring.")
85
 
 
88
  if secrets["turn_username"] and secrets["turn_credential"]:
89
  print("TURN credentials found, adding TURN servers to config.")
90
  turn_servers = [
91
+ {'urls': 'turn:global.turn.twilio.com:3478?transport=udp', 'username': secrets["turn_username"], 'credential': secrets["turn_credential"]},
92
+ {'urls': 'turn:global.turn.twilio.com:3478?transport=tcp', 'username': secrets["turn_username"], 'credential': secrets["turn_credential"]}
 
 
 
 
 
 
 
 
93
  ]
94
  ice_servers.extend(turn_servers)
95
 
 
101
  with col1:
102
  webrtc_ctx = webrtc_streamer(
103
  key="drowsiness-detection",
104
+ # The factory now correctly passes the queues from session_state
105
+ video_processor_factory=lambda: VideoProcessor(
106
+ status_queue=st.session_state.status_queue,
107
+ audio_queue=st.session_state.audio_queue
108
+ ),
109
+ rtc_configuration=RTC_CONFIGURATION,
110
  media_stream_constraints={"video": True, "audio": False},
111
  async_processing=True,
112
  )
 
123
  audio_placeholder = st.empty()
124
 
125
  if webrtc_ctx.state.playing:
126
+ if "last_status" not in st.session_state:
127
+ st.session_state.last_status = {"status": "Awake"}
128
+
129
  try:
130
+ # This line will now work because st.session_state.status_queue was initialized
131
  status_result = st.session_state.status_queue.get(timeout=0.1)
132
+ st.session_state.last_status = status_result
133
  except queue.Empty:
134
+ pass
135
 
 
 
 
 
 
 
136
  with status_placeholder.container():
137
+ last_status = st.session_state.last_status
 
 
 
 
 
138
  if last_status.get("Low Light"):
139
  st.warning("⚠️ Low Light Detected! Accuracy may be affected.")
140
  elif last_status.get("status") == "Awake":
 
142
  else:
143
  st.error("🚨 DROWSINESS DETECTED!")
144
  for key, value in last_status.items():
145
+ if key != "Low Light" and key != "status":
146
  st.warning(f"-> {key}: {value:.2f}" if isinstance(value, float) else f"-> {key}")
147
 
148
+ try:
149
+ audio_data = st.session_state.audio_queue.get(timeout=0.1)
150
  with audio_placeholder.container():
151
  autoplay_audio(audio_data)
152
+ except queue.Empty:
153
+ pass
154
+
155
  time.sleep(0.1)
156
  st.rerun()
 
157
  else:
158
  with status_placeholder.container():
159
  st.info("✔️ Driver is Awake")