Metadata-Version: 2.4
Name: streambud
Version: 0.1.0
Summary: Download HLS video streams and split videos into PNG-wrapped fragments
Author: streambud
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# streambud

Work with HLS video streams and PNG-wrapped fragments.

```
streambud download <playlist.m3u8> [output.mp4]   Download HLS → MP4
streambud split    <video> [duration] [out_dir]    Split video → PNG-wrapped TS fragments + M3U8
streambud assemble <dir|playlist.m3u8> [output]    Assemble fragments → MP4
```

## Commands

### `download`

Downloads segments from an M3U8 playlist, strips PNG wrappers, and concatenates into an MP4.

```
streambud download [-w N] [-b URL] [-ss TIME] [-to TIME] <playlist.m3u8> [output.mp4]
```

- **Master playlist** support — interactively pick resolution/bitrate
- **Parallel** downloads (default 10 workers, set with `-w`)
- **Resume** — skips already-downloaded `.ts` fragments on re-run
- **Retries** failed segments up to 3 times
- **Trim** with `-ss`/`-to` (ffmpeg time format, e.g. `00:01:30` or `90`)
- Handles **Google Drive PNG-wrapped** segments (strips the PNG container)

### `split`

Splits a video into MPEG-TS segments and wraps each in a minimal valid PNG (1×1 white pixel, Google Drive style). Writes a `playlist.m3u8` compatible with `download`.

```
streambud split <video> [segment_duration=10] [output_dir=png_fragments]
```

- Uses ffmpeg's segment muxer (`-c copy`, no re-encode)
- Each segment = PNG header + IEND chunk + raw TS data
- Output M3U8 ready for upload to Google Drive or `streambud download`

### `assemble`

Converts PNG-wrapped `.ts` fragments back into a playable MP4. Accepts a directory of fragments or an M3U8 playlist.

```
streambud assemble [-ss TIME] [-to TIME] <fragments_dir|playlist.m3u8> [output.mp4]
```

- Strips PNG wrappers before concatenation
- Two-step trim (`-ss`/`-to`): concat all → trim result (avoids concat demuxer timestamp issues)

## Requirements

- `curl`
- `ffmpeg` (concat demuxer + segment muxer)
- Python 3.10+

## Install

```bash
pip install streambud              # from PyPI
pip install git+https://github.com/<user>/streambud   # directly from GitHub
```

Or use without install:

```bash
export PYTHONPATH=src
python3 -m streambud download ...
```

## Development

```bash
# Tests
python3 -m unittest tests/test_streambud.py -v

# Linting & formatting
python3 -m venv .venv
.venv/bin/pip install ruff pre-commit
.venv/bin/pre-commit install   # runs ruff + tests on every commit
```

## CI/CD

Push a version tag to trigger publish to PyPI:

```bash
git tag v0.1.0
git push origin v0.1.0
```

Requires a `PYPI_TOKEN` secret set in GitHub repo settings (Settings → Secrets and variables → Actions).

## Architecture

```
src/streambud/
├── __init__.py    # Public API exports
├── __main__.py    # CLI entry point (python -m streambud)
├── download.py    # HLS download + PNG stripping + ffmpeg concat
├── split.py       # Video → PNG-wrapped fragments
└── assemble.py    # Fragments → MP4 reassembly

.github/workflows/
├── ci.yml         # Lint + test on every push
└── publish.yml    # Build + publish to PyPI on tags
```

All modules use only Python stdlib — no external PyPI dependencies.
