Metadata-Version: 2.4
Name: ffplay-pixels
Version: 0.1.0
Summary: Fast, lightweight pixel blitting and video playback to ffplay windows in Python
Author: Developer
License: MIT
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Multimedia :: Video :: Display
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Provides-Extra: numpy
Requires-Dist: numpy>=1.20.0; extra == "numpy"

# ffplay-pixels

A minimal, fast, and dependency-free Python library to blit raw pixels and stream real-time video to an `ffplay` window via standard input.

## Features

- **Blazingly fast**: Streams raw byte buffers directly to FFplay's standard input.
- **Simultaneous Video Recording**: Save to MP4/MKV/AVI on the fly using `save_path="output.mp4"`.
- **Headless Mode**: Set `show_window=False` to use as a high-speed video encoder without a GUI.
- **Zero mandatory dependencies**: Works with standard library `bytes`/`bytearray` or `numpy.ndarray`.
- **Clean Context Manager API**: Automatically finalizes video encoding and cleans up processes on exit.
- **Framerate synchronization**: Handles frame pacing and rate limiting automatically.
- **Configurable**: Window titles, borderless mode, always-on-top, and custom FFmpeg/FFplay flags.

## Requirements

- FFmpeg (`ffplay`) installed and on your system `$PATH`:
  - macOS: `brew install ffmpeg`
  - Linux: `sudo apt install ffmpeg`

## Installation

Editable install for local development:
```bash
pip install -e .
```

Or with NumPy support:
```bash
pip install -e ".[numpy]"
```

## Quickstart

### Using with NumPy

```python
import numpy as np
from ffplay_pixels import VideoPlayer

width, height, fps = 640, 480, 30

with VideoPlayer(width=width, height=height, fps=fps, title="NumPy Animation") as player:
    frame_count = 0
    while player.is_alive:
        t = frame_count * 0.05
        x = np.linspace(0, 1, width, endpoint=False)
        y = np.linspace(0, 1, height, endpoint=False)
        xx, yy = np.meshgrid(x, y)

        r = ((np.sin(xx * 10 + t) + 1) * 127.5).astype(np.uint8)
        g = ((np.cos(yy * 10 + t) + 1) * 127.5).astype(np.uint8)
        b = ((np.sin((xx + yy) * 10 + t) + 1) * 127.5).astype(np.uint8)

        frame = np.stack([r, g, b], axis=-1)

        if not player.show_frame(frame):
            break
        frame_count += 1
```

### Pure Python (No NumPy)

```python
from ffplay_pixels import VideoPlayer

width, height, fps = 320, 240, 30

with VideoPlayer(width=width, height=height, fps=fps) as player:
    idx = 0
    while player.is_alive:
        # A single solid RGB pixel repeated across the frame
        r, g, b = (idx * 4) % 256, (idx * 2) % 256, 180
        frame = bytes([r, g, b]) * (width * height)

        if not player.show_frame(frame):
            break
        idx += 1
```
