Metadata-Version: 2.4
Name: streamcap
Version: 1.0.0
Summary: Unified video capture for USB, RTSP, ESP32-CAM, HTTP MJPEG, and file sources with auto-reconnect.
Home-page: https://github.com/ByIbos/streamcap
Author: ByIbos
Author-email: 
License: MIT
Keywords: video capture stream rtsp esp32 usb webcam opencv
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Multimedia :: Video :: Capture
Classifier: Intended Audience :: Developers
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: opencv-python
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

<div align="center">

# 📡 streamcap

**Unified Video Capture — One API for Every Source**

*USB · RTSP · ESP32-CAM · HTTP MJPEG · Video Files*

![Python](https://img.shields.io/badge/Python-3.7%2B-blue?logo=python&logoColor=white)
![OpenCV](https://img.shields.io/badge/Dependency-OpenCV-red?logo=opencv)
![License](https://img.shields.io/badge/License-MIT-yellow)

</div>

---

## ✨ Why streamcap?

| Feature | streamcap | cv2.VideoCapture | imageio |
|---|:---:|:---:|:---:|
| Universal source detection | ✅ | ❌ | ❌ |
| ESP32-CAM auto-discovery | ✅ | ❌ | ❌ |
| Auto-reconnect on failure | ✅ | ❌ | ❌ |
| Frame metadata (FPS, ID) | ✅ | ❌ | ✅ |
| Iterator interface | ✅ | ❌ | ✅ |
| Zero config needed | ✅ | ❌ | ❌ |

---

## 📦 Installation

```bash
pip install streamcap
```

---

## 🚀 Quick Start

```python
import cv2
from streamcap import StreamCap

# USB Camera
cap = StreamCap(0)

# RTSP Stream
cap = StreamCap("rtsp://192.168.1.100:554/stream")

# ESP32-CAM (auto-find on network)
cap = StreamCap("esp32://auto")

# ESP32-CAM (specific IP)
cap = StreamCap("esp32://192.168.1.50")

# Video File
cap = StreamCap("drone_footage.mp4", resolution=(1280, 720))

# Iterate over frames
for frame, meta in cap:
    cv2.putText(frame, f"FPS: {meta['fps']:.1f} | Frame: {meta['frame_id']}",
                (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
    cv2.imshow("StreamCap", frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
```

---

## 🔧 API Reference

### `StreamCap(source, resolution=None, max_retries=5, retry_delay=2.0)`

| Source Format | Type | Example |
|---|---|---|
| `int` or `"usb://N"` | USB Camera | `StreamCap(0)` |
| `"rtsp://..."` | RTSP Stream | `StreamCap("rtsp://ip/path")` |
| `"esp32://IP"` | ESP32-CAM | `StreamCap("esp32://192.168.1.50")` |
| `"esp32://auto"` | ESP32 Auto | `StreamCap("esp32://auto")` |
| `"http://..."` | HTTP MJPEG | `StreamCap("http://ip/stream")` |
| `"path/to/file"` | Video File | `StreamCap("video.mp4")` |

### `find_esp32(ip=None, subnets=None, timeout=0.3)`

Auto-discover ESP32-CAM devices on the local network by scanning common subnets.

---

## 📜 License

MIT License — use it anywhere.

<div align="center">
<i>Built with ❤️ by <a href="https://github.com/ByIbos">ByIbos</a></i>
</div>
