142 lines
No EOL
5.1 KiB
Python
142 lines
No EOL
5.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script to check available camera indices
|
|
"""
|
|
|
|
import cv2
|
|
import logging
|
|
import sys
|
|
import subprocess
|
|
|
|
# Configure logging
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
|
|
)
|
|
logger = logging.getLogger("camera_index_test")
|
|
|
|
def test_camera_index(index):
|
|
"""Test if a camera index is available"""
|
|
try:
|
|
cap = cv2.VideoCapture(index)
|
|
if cap.isOpened():
|
|
ret, frame = cap.read()
|
|
if ret and frame is not None:
|
|
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
|
|
cap.release()
|
|
return True, f"{width}x{height} @ {fps}fps"
|
|
else:
|
|
cap.release()
|
|
return False, "Can open but cannot read frames"
|
|
else:
|
|
cap.release()
|
|
return False, "Cannot open camera"
|
|
except Exception as e:
|
|
return False, f"Error: {str(e)}"
|
|
|
|
def get_windows_cameras_ffmpeg():
|
|
"""Get available cameras on Windows using FFmpeg"""
|
|
try:
|
|
result = subprocess.run(['ffmpeg', '-f', 'dshow', '-list_devices', 'true', '-i', 'dummy'],
|
|
capture_output=True, text=True, timeout=10, encoding='utf-8', errors='ignore')
|
|
output = result.stderr
|
|
|
|
lines = output.split('\n')
|
|
video_devices = []
|
|
|
|
# Parse the output - look for lines with (video) that contain device names in quotes
|
|
for line in lines:
|
|
if '[dshow @' in line and '(video)' in line and '"' in line:
|
|
# Extract device name between first pair of quotes
|
|
start = line.find('"') + 1
|
|
end = line.find('"', start)
|
|
if start > 0 and end > start:
|
|
device_name = line[start:end]
|
|
video_devices.append(device_name)
|
|
|
|
logger.info(f"FFmpeg detected video devices: {video_devices}")
|
|
return video_devices
|
|
except Exception as e:
|
|
logger.error(f"Failed to get Windows camera names: {e}")
|
|
return []
|
|
|
|
def main():
|
|
logger.info("=== Camera Index Test ===")
|
|
|
|
# Check FFmpeg availability for Windows device detection
|
|
ffmpeg_available = False
|
|
try:
|
|
result = subprocess.run(['ffmpeg', '-version'], capture_output=True, text=True, timeout=5)
|
|
if result.returncode == 0:
|
|
ffmpeg_available = True
|
|
logger.info("FFmpeg is available")
|
|
except:
|
|
logger.info("FFmpeg not available")
|
|
|
|
# Get Windows camera names if possible
|
|
if sys.platform.startswith('win') and ffmpeg_available:
|
|
logger.info("\n=== Windows Camera Devices (FFmpeg) ===")
|
|
cameras = get_windows_cameras_ffmpeg()
|
|
if cameras:
|
|
for i, camera in enumerate(cameras):
|
|
logger.info(f"Device {i}: {camera}")
|
|
else:
|
|
logger.info("No cameras detected via FFmpeg")
|
|
|
|
# Test camera indices 0-9
|
|
logger.info("\n=== Testing Camera Indices ===")
|
|
available_cameras = []
|
|
|
|
for index in range(10):
|
|
logger.info(f"Testing camera index {index}...")
|
|
is_available, info = test_camera_index(index)
|
|
|
|
if is_available:
|
|
logger.info(f"✓ Camera {index}: AVAILABLE - {info}")
|
|
available_cameras.append(index)
|
|
else:
|
|
logger.info(f"✗ Camera {index}: NOT AVAILABLE - {info}")
|
|
|
|
# Summary
|
|
logger.info("\n=== Summary ===")
|
|
if available_cameras:
|
|
logger.info(f"Available camera indices: {available_cameras}")
|
|
logger.info(f"Default camera index to use: {available_cameras[0]}")
|
|
|
|
# Test the first available camera more thoroughly
|
|
logger.info(f"\n=== Detailed Test for Camera {available_cameras[0]} ===")
|
|
cap = cv2.VideoCapture(available_cameras[0])
|
|
if cap.isOpened():
|
|
# Get properties
|
|
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
|
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
backend = cap.getBackendName()
|
|
|
|
logger.info(f"Resolution: {width}x{height}")
|
|
logger.info(f"FPS: {fps}")
|
|
logger.info(f"Backend: {backend}")
|
|
|
|
# Test frame capture
|
|
ret, frame = cap.read()
|
|
if ret and frame is not None:
|
|
logger.info(f"Frame capture: SUCCESS")
|
|
logger.info(f"Frame shape: {frame.shape}")
|
|
logger.info(f"Frame dtype: {frame.dtype}")
|
|
else:
|
|
logger.info(f"Frame capture: FAILED")
|
|
|
|
cap.release()
|
|
else:
|
|
logger.error("No cameras available!")
|
|
logger.info("Possible solutions:")
|
|
logger.info("1. Check if camera is connected and not used by another application")
|
|
logger.info("2. Check camera permissions")
|
|
logger.info("3. Try different camera indices")
|
|
logger.info("4. Install camera drivers")
|
|
|
|
if __name__ == "__main__":
|
|
main() |