Pygrabber only for Windows

pull/844/head
KRSHH 2024-12-16 18:41:39 +05:30
parent c72582506d
commit a9e8f27360
2 changed files with 77 additions and 48 deletions

View File

@ -27,6 +27,7 @@ from modules.utilities import (
has_image_extension,
)
from modules.video_capture import VideoCapturer
import platform
ROOT = None
POPUP = None
@ -771,6 +772,7 @@ def webcam_preview(root: ctk.CTk, camera_index: int):
def get_available_cameras():
"""Returns a list of available camera names and indices."""
if platform.system() == "Windows":
try:
graph = FilterGraph()
devices = graph.get_input_devices()
@ -803,6 +805,23 @@ def get_available_cameras():
except Exception as e:
print(f"Error detecting cameras: {str(e)}")
return [], ["No cameras found"]
else:
# Unix-like systems (Linux/Mac) camera detection
camera_indices = []
camera_names = []
# Test the first 10 indices
for i in range(10):
cap = cv2.VideoCapture(i)
if cap.isOpened():
camera_indices.append(i)
camera_names.append(f"Camera {i}")
cap.release()
if not camera_names:
return [], ["No cameras found"]
return camera_indices, camera_names
def create_webcam_preview(camera_index: int):

View File

@ -1,13 +1,16 @@
import cv2
import numpy as np
from pygrabber.dshow_graph import FilterGraph
import threading
from typing import Optional, Tuple, Callable
import platform
import threading
# Only import Windows-specific library if on Windows
if platform.system() == "Windows":
from pygrabber.dshow_graph import FilterGraph
class VideoCapturer:
def __init__(self, device_index: int):
self.graph = FilterGraph()
self.device_index = device_index
self.frame_callback = None
self._current_frame = None
@ -15,6 +18,9 @@ class VideoCapturer:
self.is_running = False
self.cap = None
# Initialize Windows-specific components if on Windows
if platform.system() == "Windows":
self.graph = FilterGraph()
# Verify device exists
devices = self.graph.get_input_devices()
if self.device_index >= len(devices):
@ -25,7 +31,8 @@ class VideoCapturer:
def start(self, width: int = 960, height: int = 540, fps: int = 60) -> bool:
"""Initialize and start video capture"""
try:
# Try different capture methods in order
if platform.system() == "Windows":
# Windows-specific capture methods
capture_methods = [
(self.device_index, cv2.CAP_DSHOW), # Try DirectShow first
(self.device_index, cv2.CAP_ANY), # Then try default backend
@ -41,9 +48,12 @@ class VideoCapturer:
self.cap.release()
except Exception:
continue
else:
# Unix-like systems (Linux/Mac) capture method
self.cap = cv2.VideoCapture(self.device_index)
if not self.cap or not self.cap.isOpened():
raise RuntimeError("Failed to open camera with all available methods")
raise RuntimeError("Failed to open camera")
# Configure format
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)