lucid-hf commited on
Commit
396f512
Β·
verified Β·
1 Parent(s): 7e6fce1

CI: deploy Docker/PDM Space

Browse files
services/app_service/pages/signal_watch.py CHANGED
@@ -241,13 +241,22 @@ def extract_youtube_stream_url(url: str, cookies_path: str | None = None) -> str
241
  st.error("yt-dlp found but not working properly.")
242
  return None
243
 
 
 
 
 
 
 
 
 
 
244
  try:
245
  # Show progress message
246
  with st.spinner("Extracting YouTube stream URL..."):
247
  # Try multiple format options with different cookie strategies
248
  format_options = ["best[height<=720]", "best[height<=480]", "best", "worst"]
249
 
250
- # First try with cookies if provided
251
  if cookies_path and Path(cookies_path).exists():
252
  st.info("Using provided cookies for YouTube authentication...")
253
  for fmt in format_options:
@@ -277,6 +286,50 @@ def extract_youtube_stream_url(url: str, cookies_path: str | None = None) -> str
277
  else:
278
  st.warning(f"yt-dlp failed with format {fmt}: {result.stderr}")
279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  # Try with browser cookies (Chrome, Firefox, Safari)
281
  st.info("Trying to use browser cookies for YouTube authentication...")
282
  browsers = ["chrome", "firefox", "safari", "edge"]
@@ -524,7 +577,12 @@ def run_video_feed_detection(
524
 
525
  # Set buffer size for live streams to reduce latency
526
  if is_youtube or isinstance(cap_source, str):
527
- cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)
 
 
 
 
 
528
 
529
  # Check if it's a local file (not a URL)
530
  is_file = False
@@ -548,7 +606,7 @@ def run_video_feed_detection(
548
  i = 0
549
  last_preview_update = 0
550
  preview_update_interval = (
551
- 1 # Update preview every frame for more responsive display
552
  )
553
 
554
  writer = None
@@ -562,11 +620,28 @@ def run_video_feed_detection(
562
  )
563
 
564
  try:
 
 
 
565
  while True:
 
 
 
 
 
566
  ok, frame = cap.read()
567
  if not ok:
568
  break
569
 
 
 
 
 
 
 
 
 
 
570
  if i % max(1, stride) == 0:
571
  if model_key == "deim":
572
  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
@@ -586,19 +661,35 @@ def run_video_feed_detection(
586
  text=f"Processing frame {i + 1}/{total if total > 0 else '∞'}...",
587
  )
588
 
589
- # Throttle preview updates to prevent freezing
590
  if (
591
  frame_ph is not None
592
  and (i - last_preview_update) >= preview_update_interval
593
  ):
594
- # display_frame = _resize_for_preview(vis, preview_max_width)
595
- frame_ph.image(
596
- cv2.cvtColor(vis, cv2.COLOR_BGR2RGB),
597
- use_container_width=True,
598
- output_format="JPEG",
599
- channels="RGB",
600
- )
601
- last_preview_update = i
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
 
603
  if writer is not None:
604
  writer.write(vis)
@@ -624,9 +715,16 @@ def run_video_feed_detection(
624
  if elapsed >= max_seconds:
625
  return
626
 
627
- # Add small delay to prevent overwhelming the system
628
- if not is_file: # Only for live sources
629
- time.sleep(0.033) # ~30 FPS max
 
 
 
 
 
 
 
630
 
631
  except Exception as e:
632
  st.error(f"Error during processing: {e!s}")
@@ -635,6 +733,8 @@ def run_video_feed_detection(
635
  cap.release()
636
  if writer is not None:
637
  writer.release()
 
 
638
 
639
  stream_type = "YouTube" if is_youtube else ("Live" if not is_file else "File")
640
  st.success(f"Done processing {stream_type} stream!")
@@ -649,7 +749,14 @@ def run_video_feed_detection(
649
  )
650
 
651
 
 
 
 
 
652
  if run_detection:
 
 
 
653
  src = resolve_video_source(src_choice, cookies_path)
654
  if not src:
655
  st.warning("Please select a valid source (pick a file or enter a URL).")
 
241
  st.error("yt-dlp found but not working properly.")
242
  return None
243
 
244
+ # Hardcoded cookies as fallback (from your provided cookies.txt)
245
+ hardcoded_cookies = """# Netscape HTTP Cookie File
246
+ # https://curl.haxx.se/rfc/cookie_spec.html
247
+ # This is a generated file! Do not edit.
248
+
249
+ .youtube.com TRUE / TRUE 1776851748 VISITOR_INFO1_LIVE m4CAb_qRhZM
250
+ .youtube.com TRUE / TRUE 1776851748 VISITOR_PRIVACY_METADATA CgJBVRIEGgAgQw%3D%3D
251
+ .youtube.com TRUE / TRUE 1772413113 __Secure-ROLLOUT_TOKEN CKPJ4ZHJ2ajAZhD82ZLUsbuPAxjFtqHUsbuPAw%3D%3D"""
252
+
253
  try:
254
  # Show progress message
255
  with st.spinner("Extracting YouTube stream URL..."):
256
  # Try multiple format options with different cookie strategies
257
  format_options = ["best[height<=720]", "best[height<=480]", "best", "worst"]
258
 
259
+ # First try with provided cookies if available
260
  if cookies_path and Path(cookies_path).exists():
261
  st.info("Using provided cookies for YouTube authentication...")
262
  for fmt in format_options:
 
286
  else:
287
  st.warning(f"yt-dlp failed with format {fmt}: {result.stderr}")
288
 
289
+ # Try with hardcoded cookies as fallback
290
+ st.info("Trying with hardcoded cookies for YouTube authentication...")
291
+ with tempfile.NamedTemporaryFile(
292
+ mode="w", suffix=".txt", delete=False
293
+ ) as temp_cookies:
294
+ temp_cookies.write(hardcoded_cookies)
295
+ temp_cookies_path = temp_cookies.name
296
+
297
+ try:
298
+ for fmt in format_options:
299
+ cmd = [
300
+ ytdlp_path,
301
+ "--get-url",
302
+ "--format",
303
+ fmt,
304
+ "--no-playlist",
305
+ "--no-warnings",
306
+ "--cookies",
307
+ temp_cookies_path,
308
+ url,
309
+ ]
310
+
311
+ result = subprocess.run(
312
+ cmd, check=False, capture_output=True, text=True, timeout=30
313
+ )
314
+
315
+ if result.returncode == 0:
316
+ stream_url = result.stdout.strip()
317
+ if stream_url and stream_url.startswith("http"):
318
+ st.success(
319
+ f"Successfully extracted YouTube stream URL with hardcoded cookies! (format: {fmt})"
320
+ )
321
+ return stream_url
322
+ else:
323
+ st.warning(
324
+ f"Hardcoded cookies failed with format {fmt}: {result.stderr[:100]}..."
325
+ )
326
+ finally:
327
+ # Clean up temporary file
328
+ try:
329
+ Path(temp_cookies_path).unlink()
330
+ except:
331
+ pass
332
+
333
  # Try with browser cookies (Chrome, Firefox, Safari)
334
  st.info("Trying to use browser cookies for YouTube authentication...")
335
  browsers = ["chrome", "firefox", "safari", "edge"]
 
577
 
578
  # Set buffer size for live streams to reduce latency
579
  if is_youtube or isinstance(cap_source, str):
580
+ cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # Minimal buffer for live streams
581
+ # Additional settings for better live stream performance
582
+ cap.set(cv2.CAP_PROP_FPS, 25) # Set target FPS
583
+ cap.set(
584
+ cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"MJPG")
585
+ ) # Use MJPG codec for better streaming
586
 
587
  # Check if it's a local file (not a URL)
588
  is_file = False
 
606
  i = 0
607
  last_preview_update = 0
608
  preview_update_interval = (
609
+ 0 # Update preview every frame for live streams to prevent freezing
610
  )
611
 
612
  writer = None
 
620
  )
621
 
622
  try:
623
+ frame_skip_count = 0
624
+ max_frame_skip = 5 # Skip up to 5 frames if we're falling behind
625
+
626
  while True:
627
+ # Check for stop signal
628
+ if st.session_state.get("stop_processing", False):
629
+ st.info("πŸ›‘ Stopping detection...")
630
+ break
631
+
632
  ok, frame = cap.read()
633
  if not ok:
634
  break
635
 
636
+ # For live streams, skip frames if we're falling behind
637
+ if (
638
+ is_youtube or isinstance(cap_source, str)
639
+ ) and frame_skip_count < max_frame_skip:
640
+ frame_skip_count += 1
641
+ continue
642
+ else:
643
+ frame_skip_count = 0
644
+
645
  if i % max(1, stride) == 0:
646
  if model_key == "deim":
647
  frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
 
661
  text=f"Processing frame {i + 1}/{total if total > 0 else '∞'}...",
662
  )
663
 
664
+ # Optimized preview updates for live streams
665
  if (
666
  frame_ph is not None
667
  and (i - last_preview_update) >= preview_update_interval
668
  ):
669
+ try:
670
+ # Convert to RGB and resize for better performance
671
+ display_frame = cv2.cvtColor(vis, cv2.COLOR_BGR2RGB)
672
+
673
+ # Resize large frames to improve performance
674
+ height, width = display_frame.shape[:2]
675
+ if width > 1280: # Resize if too large
676
+ scale = 1280 / width
677
+ new_width = 1280
678
+ new_height = int(height * scale)
679
+ display_frame = cv2.resize(
680
+ display_frame, (new_width, new_height)
681
+ )
682
+
683
+ frame_ph.image(
684
+ display_frame,
685
+ use_container_width=True,
686
+ output_format="JPEG",
687
+ channels="RGB",
688
+ )
689
+ last_preview_update = i
690
+ except Exception as e:
691
+ # If display fails, continue processing but log the error
692
+ st.warning(f"Display update failed: {e}")
693
 
694
  if writer is not None:
695
  writer.write(vis)
 
715
  if elapsed >= max_seconds:
716
  return
717
 
718
+ # For live streams, add adaptive delay based on processing speed
719
+ if not is_file:
720
+ elapsed = time.time() - start_t
721
+ if elapsed > 0:
722
+ current_fps = i / elapsed
723
+ # Target 15-20 FPS for live streams to prevent freezing
724
+ if current_fps > 20:
725
+ time.sleep(0.05) # Slow down if too fast
726
+ elif current_fps < 10:
727
+ time.sleep(0.01) # Speed up if too slow
728
 
729
  except Exception as e:
730
  st.error(f"Error during processing: {e!s}")
 
733
  cap.release()
734
  if writer is not None:
735
  writer.release()
736
+ # Reset stop flag
737
+ st.session_state.stop_processing = False
738
 
739
  stream_type = "YouTube" if is_youtube else ("Live" if not is_file else "File")
740
  st.success(f"Done processing {stream_type} stream!")
 
749
  )
750
 
751
 
752
+ if stop_detection:
753
+ st.session_state.stop_processing = True
754
+ st.info("πŸ›‘ Stop signal sent. Detection will stop after current frame.")
755
+
756
  if run_detection:
757
+ # Reset stop flag when starting new detection
758
+ st.session_state.stop_processing = False
759
+
760
  src = resolve_video_source(src_choice, cookies_path)
761
  if not src:
762
  st.warning("Please select a valid source (pick a file or enter a URL).")