Metadata-Version: 2.4
Name: streamsnapper
Version: 0.5.0
Summary: Extract and analyze YouTube video streams with intelligent quality selection, language fallback, and comprehensive metadata retrieval
Keywords: stream,snapper,scraper,downloader,merger,youtube,youtube-music,media,video,audio
Author: henrique-coder
Author-email: henrique-coder <henriquemoreira10fk@gmail.com>
License-Expression: MIT
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Internet
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Multimedia
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Multimedia :: Sound/Audio
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Classifier: Typing :: Typed
Requires-Dist: curl-cffi>=0.14.0
Requires-Dist: ffmpeg-python>=0.2.0
Requires-Dist: loguru>=0.7.3
Requires-Dist: orjson>=3.11.7
Requires-Dist: pydantic>=2.12.5
Requires-Dist: secretstorage>=3.5.0
Requires-Dist: yt-dlp[default]>=2026.2.21
Requires-Python: >=3.10, <=3.14
Project-URL: Homepage, https://github.com/henrique-coder/streamsnapper
Project-URL: Documentation, https://github.com/henrique-coder/streamsnapper/blob/main/README.md
Project-URL: Repository, https://github.com/henrique-coder/streamsnapper
Project-URL: Issues, https://github.com/henrique-coder/streamsnapper/issues
Project-URL: Changelog, https://github.com/henrique-coder/streamsnapper/releases
Description-Content-Type: text/markdown

<div align="center">

# StreamSnapper

![PyPI - Version](https://img.shields.io/pypi/v/streamsnapper?style=for-the-badge&logo=pypi&logoColor=white&color=0066cc)
![Python Versions](https://img.shields.io/pypi/pyversions/streamsnapper?style=for-the-badge&logo=python&logoColor=white&color=306998)
![License](https://img.shields.io/pypi/l/streamsnapper?style=for-the-badge&color=blue)
![Code Style](https://img.shields.io/badge/code%20style-ruff-000000.svg?style=for-the-badge)

**Intuitive, high-performance YouTube data extraction library for Python.**

[🚀 Quick Start](#-quick-start) • [📖 API Reference](#-api-reference) • [💡 Examples](#-examples)

</div>

---

## 🌟 Overview

StreamSnapper provides a clean, pythonic interface for extracting YouTube metadata and streams. It wraps `yt-dlp` with an intuitive object-oriented API, automatic quality enhancements, and robust type safety.

- **Intuitive API**: Access data via properties (`yt.streams.video.best`).
- **Smart Categorization**: Videos, audios, and subtitles are automatically sorted and filtered.
- **Modern Tech**: Built with `pydantic` v2 and `orjson` for high performance.
- **AI Detection**: Automatically detects AI-upscaled content.
- **Type Safe**: Fully typed for excellent IDE support.

## 🔧 Installation

```shell
uv add streamsnapper
```

**Requirements:** Python 3.10+

## 🚀 Quick Start

### Basic Usage

```python
from streamsnapper import YouTube

# automatic extraction on initialization
yt = YouTube("https://www.youtube.com/watch?v=dQw4w9WgXcQ")

# Video Metadata
print(f"Title: {yt.metadata.title}")
print(f"Views: {yt.metadata.view_count}")
print(f"Duration: {yt.metadata.duration_formatted}")

# Stream Access (Automatically sorted by quality)
print(f"Best Video: {yt.streams.video.best.url}")
print(f"Best Audio: {yt.streams.audio.best.url}")
```

### Filtering Streams

StreamSnapper offers a readable fluent interface for filtering:

```python
# specific resolution
stream = yt.streams.video.filter(resolution="1080p").best

# specific codec and frame rate
stream = yt.streams.video.filter(codec="vp9", fps=60).best

# High quality audio
stream = yt.streams.audio.filter(min_bitrate=128).best
```

## 💡 Key Features

### Intelligent Thumbnails

We automatically filter and deduplicate thumbnails to give you exactly what you need:

- `yt.metadata.thumbnails`: A curated list of high-quality thumbnails (maxres, sd, hq).
- `yt.metadata.all_thumbnails`: The complete raw list of all available thumbnails.

### AI Upscaling Detection

Detects if a stream has been AI-upscaled (e.g., "1080p Premium" or similar enhancements):

```python
if stream.is_ai_upscaled:
    print("This stream is AI upscaled!")
```

### JSON Serialization

All models support high-performance JSON serialization using `orjson`:

```python
json_data = yt.metadata.to_json()
```

## 📖 API Reference

### `YouTube` Class

The main entry point.

```python
yt = YouTube(
    url="https://...",
    cookies=None,      # Optional: CookieFile or CookieBrowser
    logging=False      # Optional: Enable verbose logging
)
```

**Properties:**

- `.metadata`: `VideoInformation` object (title, id, description, stats, etc.)
- `.streams`: `Streams` object containing:
  - `.video`: `VideoStreamCollection`
  - `.audio`: `AudioStreamCollection`
  - `.subtitle`: `SubtitleStreamCollection`

### `VideoStream` Model

Represents a single video format. Key attributes:

- `url`: Direct download URL.
- `resolution`: string (e.g., "1080p").
- `codec`: string (e.g., "vp9").
- `bitrate`: float (Mbps/Kbps).
- `is_hdr`: boolean.
- `is_ai_upscaled`: boolean.

## 🛡️ Authentication (Premium/Age-Restricted)

Access private or age-restricted content using cookies. **Cookies are automatically reused across extraction and all subsequent downloads** — they are extracted a single time and propagated to every stream, so you never hit unnecessary re-authentication.

```python
from streamsnapper import YouTube, CookieBrowser, CookieFile

# Use cookies from local Chrome browser
yt = YouTube(url, cookies=CookieBrowser.CHROME)

# Use a Netscape-formatted cookie file
yt = YouTube(url, cookies=CookieFile("cookies.txt"))
```

## ⬇️ Downloading

### Download individual stream

```python
# Download best video-only stream
path = yt.streams.video.best.download(output_path="downloads/")

# Download best audio-only stream
path = yt.streams.audio.best.download(output_path="downloads/")
```

Default filenames follow the convention:

- Video-only: `<Title> (video-only) [yt-<ID>].ext`
- Audio-only: `<Title> (audio-only) [yt-<ID>].ext`

### Download and merge (video + audio)

YouTube separates high-quality video and audio into distinct streams. Use `download_with_audio` to merge them automatically with `ffmpeg`:

```python
video = yt.streams.video.best
audio = yt.streams.audio.best

# Merge and save — requires ffmpeg in PATH
path = video.download_with_audio(audio=audio, output_path="downloads/")
# Result filename: <Title> [yt-<ID>].ext
```

> [!NOTE]
> `ffmpeg` must be installed and available in your system PATH for merging to work.

## 📝 License

MIT License - see [LICENSE](LICENSE) file.
