Metadata-Version: 2.4
Name: copyyoutube
Version: 0.1.0
Summary: YouTube downloader with yt-dlp-inspired architecture
Author: Bayu Randu
License: MIT
Project-URL: Homepage, https://github.com/bayurandu/copyyoutube
Project-URL: Repository, https://github.com/bayurandu/copyyoutube
Project-URL: Issues, https://github.com/bayurandu/copyyoutube/issues
Keywords: youtube,downloader,yt-dlp,video,cli
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27.0
Requires-Dist: yt-dlp>=2024.1.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Dynamic: license-file

# copyyoutube

YouTube downloader dengan arsitektur terinspirasi [yt-dlp](https://github.com/yt-dlp/yt-dlp).

## Arsitektur

```
URL → CopyYoutubeDL (orchestrator)
         ├─ InfoExtractor   → info_dict (metadata + formats)
         ├─ Format selection
         ├─ FileDownloader  → download file(s)
         └─ PostProcessor   → merge / extract audio / etc.
```

Komponen utama:

| Modul | Peran |
|---|---|
| `orchestrator.py` | `CopyYoutubeDL` — koordinator pusat (seperti `YoutubeDL`) |
| `extractor/youtube.py` | `YoutubeIE` — YouTube via yt-dlp |
| `extractor/ytdlp_generic.py` | Fallback untuk Vimeo, Dailymotion, dll. |
| `extractor/generic.py` | Direct media URL (.mp4, .webm, …) |
| `plugins.py` | Plugin discovery (`copyyoutube_plugins/`) |
| `utils/progress.py` | Progress bar terminal |
| `downloader/` | `FileDownloader` base + `HttpFD` |
| `postprocessor/` | `PostProcessor` base + FFmpeg merger/audio |
| `options.py` | CLI argparse → params dict |
| `globals.py` | Registry extractor & post-processor |

Data mengalir melalui **`info_dict`** — dictionary yang diperkaya di setiap tahap pipeline.

## Instalasi

```bash
pip install -e .
# atau
pip install httpx yt-dlp
PYTHONPATH=. python3 -m copyyoutube "URL"
```

## Tests

```bash
pip install pytest
PYTHONPATH=. python3 -m pytest tests/ -v
```

## Penggunaan

### CLI

```bash
# Download video terbaik
copyyoutube "https://www.youtube.com/watch?v=VIDEO_ID"

# Download video + audio terpisah, merge otomatis (butuh ffmpeg)
copyyoutube -f bestvideo+bestaudio "https://youtu.be/VIDEO_ID"

# Extract audio saja
copyyoutube -x --audio-format mp3 "https://youtu.be/VIDEO_ID"

# Dump info JSON tanpa download
copyyoutube -j "https://youtu.be/VIDEO_ID"

# Pilih output directory
copyyoutube -P ./downloads "https://youtu.be/VIDEO_ID"

# Progress bar (aktif default, nonaktifkan dengan --no-progress)
copyyoutube --no-progress "URL"

# List extractor terdaftar
copyyoutube --list-extractors

# Site lain (Vimeo, Dailymotion, dll.) via yt-dlp fallback
copyyoutube "https://vimeo.com/VIDEO_ID"

# Direct media URL
copyyoutube "https://example.com/video.mp4"
```

### Plugin

```bash
# Load plugin custom
copyyoutube --plugin-dirs ./examples/sample_plugin --list-extractors

# Disable plugin
copyyoutube --no-plugins "URL"
```

Struktur plugin:

```
my_plugin/
└── copyyoutube_plugins/
    ├── extractor/
    │   └── mysite.py      # class MySiteIE(InfoExtractor)
    └── postprocessor/
        └── mypp.py        # class MyCustomPP(PostProcessor)
```

Plugin juga bisa dipasang di `~/.config/copyyoutube/plugins/`.

### Library

```python
from copyyoutube import CopyYoutubeDL

# Extract info saja
with CopyYoutubeDL({"quiet": True}) as ydl:
    info = ydl.extract_info("https://youtu.be/VIDEO_ID", download=False)
    print(info["title"], info["formats"])

# Download penuh
ydl_opts = {
    "format": "bestvideo+bestaudio",
    "output_dir": "./downloads",
    "postprocessors": [{"key": "FFmpegMerger"}],
}
with CopyYoutubeDL(ydl_opts) as ydl:
    ydl.download(["https://youtu.be/VIDEO_ID"])
```

## Menambah Extractor Baru

```python
from copyyoutube.extractor import register_extractor
from copyyoutube.extractor.common import InfoExtractor

@register_extractor
class MySiteIE(InfoExtractor):
    _VALID_URL = r"https?://example\.com/video/(?P<id>[0-9]+)"
    IE_NAME = "example"

    def _real_extract(self, url):
        video_id = self._match_id(url)
        return {
            "id": video_id,
            "title": "...",
            "formats": [{"url": "...", "ext": "mp4", "protocol": "https"}],
        }
```

## Requirements

- Python 3.10+
- `httpx` — HTTP client untuk downloader
- `yt-dlp` — ekstraksi metadata & format URL YouTube (PO token, decipher, dll.)
- `ffmpeg` (opsional) — merge video+audio dan extract audio

> **Catatan:** YouTube saat ini memerlukan PO token / signature decipher yang terus berubah. Extractor YouTube kita menggunakan yt-dlp sebagai backend ekstraksi, sementara pipeline download & post-process tetap diimplementasi sendiri mengikuti arsitektur yt-dlp.
