Metadata-Version: 2.4
Name: miyuki-dlp
Version: 0.3.2
Summary: Stealth HLS stream downloader — bypass Cloudflare, intercept M3U8 playlists, and download videos via browser automation and ffmpeg
Project-URL: Homepage, https://github.com/muginami/miyuki-dlp
Project-URL: Repository, https://github.com/muginami/miyuki-dlp
Project-URL: Issues, https://github.com/muginami/miyuki-dlp/issues
Author-email: Muginami <muginami96@gmail.com>
License-Expression: MIT
Keywords: browser-automation,cloudflare-bypass,ffmpeg,hls,m3u8,patchright,stealth,video-downloader
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Multimedia :: Video
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: m3u8>=6.0.0
Requires-Dist: patchright>=1.50.0
Requires-Dist: rich>=13.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# miyuki-dlp

[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![PyPI version](https://img.shields.io/pypi/v/miyuki-dlp.svg)](https://pypi.org/project/miyuki-dlp/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

Stealth HLS stream downloader that bypasses Cloudflare protection using browser automation. Intercepts M3U8 playlists from network traffic and downloads via ffmpeg — no fragile URL scraping required.

## Features

- **Cloudflare bypass** — Uses Patchright (stealth-patched Playwright) with a real Chrome profile
- **Smart auto-detection** — Starts headless; auto-relaunches headed if Cloudflare blocks
- **Automatic M3U8 interception** — Captures playlist URLs from browser network traffic
- **UUID fallback** — Extracts video UUID from page source when interception fails
- **Quality selection** — Choose best, worst, or specific resolution (e.g. 720p)
- **Parallel downloads** — 16 concurrent connections for fast segment downloading
- **Multi-URL support** — Download multiple videos in a single session
- **Rich progress UI** — Colorful terminal output with download progress
- **ffmpeg integration** — Reliable stream download with copy-mux to MP4

## Requirements

- **Python 3.11+**
- **ffmpeg** — for HLS stream downloading
- **Google Chrome** — real Chrome browser (not Chromium)

## Installation

### From PyPI (recommended)

```bash
pip install miyuki-dlp

# Install the browser driver (required once)
python -m patchright install chromium
```

### From source

```bash
git clone https://github.com/muginami/miyuki-dlp.git
cd miyuki-dlp
pip install -e .

# Install the browser driver (required once)
python -m patchright install chromium
```

## Usage

### Basic download

```bash
miyuki-dlp https://example.com/video-page
```

### List available qualities

```bash
miyuki-dlp --list-qualities https://example.com/video-page
```

### Select specific quality

```bash
miyuki-dlp -q 720 https://example.com/video-page
```

### Custom output directory

```bash
miyuki-dlp -o ~/videos https://example.com/video-page
```

### Verbose mode (debug logging)

```bash
miyuki-dlp -v https://example.com/video-page
```

### Download multiple URLs

```bash
miyuki-dlp https://example.com/video-1 https://example.com/video-2
```

### Override output filename

```bash
miyuki-dlp --title "my-video" https://example.com/video-page
```

## CLI Reference

```
usage: miyuki-dlp [-h] [-o OUTPUT] [-q QUALITY] [--headful] [--timeout TIMEOUT]
                  [--profile PROFILE] [--list-qualities] [--title TITLE]
                  [-v] [--version]
                  urls [urls ...]

Stealth HLS stream downloader — bypass Cloudflare, intercept M3U8, download via ffmpeg

positional arguments:
  urls                  Video page URLs to download

options:
  -h, --help            show this help message and exit
  -o, --output OUTPUT   Output directory (default: ./downloads)
  -q, --quality QUALITY Quality: best, worst, or height like 720, 1080 (default: best)
  --headful            Force headed browser mode (skip auto-detection)
  --timeout TIMEOUT     M3U8 interception timeout in seconds (default: 30)
  --profile PROFILE     Chrome profile directory path
  --list-qualities      List available qualities and exit
  --title TITLE         Override output filename
  -v, --verbose         Verbose/debug logging
  --version             show program's version number and exit
```

## How It Works

### Cloudflare Bypass (Smart Auto-Detection)

1. **First run** — Browser starts in headless mode. If Cloudflare challenge is detected, it automatically relaunches in headed (visible) mode to solve the challenge.
2. **Cookies saved** — Once Cloudflare is cleared, session cookies are persisted to the Chrome profile (`~/.miyuki-dlp/chrome-profile`).
3. **Subsequent runs** — Headless mode works normally using the cached clearance cookies.
4. **Manual override** — If auto-detection fails, use `--headful` to force headed mode from the start.

### Pipeline

1. **Browser launch** — Patchright launches a real Chrome instance with a persistent profile, avoiding bot detection fingerprints
2. **Page navigation** — The browser navigates to the target page while a network listener captures all `.m3u8` requests
3. **M3U8 interception** — When the video player loads, it requests an HLS master playlist — miyuki-dlp intercepts this URL from network traffic
4. **UUID fallback** — If no M3U8 is captured via network (e.g. lazy-loaded players), miyuki-dlp extracts the video UUID from the page source and constructs the playlist URL directly
5. **Quality selection** — The master playlist is fetched and parsed to list available resolutions; the user's preferred quality is selected
6. **Parallel download** — Segments are downloaded with 16 concurrent HTTP/2 connections, then concatenated and remuxed to MP4 via ffmpeg

## Troubleshooting

### Cloudflare blocks the request

- The browser auto-relaunches in headed mode if Cloudflare is detected — on first run, a visible browser window is expected
- If auto-detection fails, force headed mode: `--headful`
- Clear the browser profile: `rm -rf ~/.miyuki-dlp/chrome-profile`
- Increase timeout: `--timeout 60`
- Make sure you have Google Chrome (not just Chromium) installed

### ffmpeg not found

Install ffmpeg for your platform:

```bash
# macOS
brew install ffmpeg

# Ubuntu/Debian
sudo apt install ffmpeg

# Windows
# Download from https://ffmpeg.org/download.html
```

### M3U8 not captured

- Increase the timeout: `miyuki-dlp --timeout 60 <url>`
- Run in verbose mode: `miyuki-dlp -v <url>`
- The page may require interaction (e.g. clicking a play button) — currently not supported automatically

### Download fails or produces corrupted file

- Check your ffmpeg version: `ffmpeg -version` (v6+ recommended)
- The stream may have expired — try re-running the command
- Check disk space in the output directory

## License

MIT
