Metadata-Version: 2.4
Name: termflux
Version: 1.0.0
Summary: Terminal media engine with pixel-accurate rendering at 60fps
Author: MERO:TG@QP4RM
License: Proprietary
Project-URL: Homepage, https://github.com/6x-u/termflux
Project-URL: Repository, https://github.com/6x-u/termflux
Keywords: terminal,media,player,video,audio,image,pixel,rendering,cli,tui
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: Android
Classifier: Programming Language :: C
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
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: Topic :: Multimedia
Classifier: Topic :: Multimedia :: Video :: Display
Classifier: Topic :: Multimedia :: Sound/Audio :: Players
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# termflux

**Terminal Media Engine — Pixel-Perfect Rendering at 60fps**

Render images, play videos, and stream audio entirely inside your terminal.
Native C engine with Sixel graphics, Lanczos3 interpolation, and quarter-block Unicode for HD output on any platform.

```
Author  : MERO:TG@QP4RM
Version : 1.0.0
License : Proprietary (see LICENSE)
```

---

## Overview

termflux is a Python library backed by a C rendering engine. It decodes media with FFmpeg and draws pixels directly into the terminal — no GUI, no browser, no external windows.

Three render modes:

| Mode | Resolution | Method | Terminal Support |
|------|-----------|--------|-----------------|
| **Sixel** | Up to 1920x1080 real pixels | Sixel bitmap protocol | mlterm, foot, WezTerm, iTerm2 |
| **Quarter-Block** | 2x columns, 2x rows | 16 Unicode block patterns | All terminals |
| **Half-Block** | columns, 2x rows | Upper/lower half blocks | All terminals |

Core capabilities:
- Image display with 24-bit true color
- Video playback at native framerate (up to 60fps)
- Audio playback with built-in terminal visualizer (waveform, progress, metadata)
- URL loading — pass a link, termflux downloads and renders
- Color filters: brightness, contrast, saturation, grayscale, invert
- 5 border styles with custom RGB colors, thickness 1-5, configurable padding
- 9 screen positions (center, top, bottom, left, right, corners)
- 3 aspect ratio modes (fit, fill, stretch)
- Cross-platform: Linux, Windows 10+, macOS, Android (Termux / Pydroid / QPython)
- Pure Python fallback when no C compiler is available

---

## Installation

```bash
pip install termflux
```

### Dependencies

- **Python** >= 3.8
- **FFmpeg** (video/image decoding and audio playback)

```bash
# Debian / Ubuntu
sudo apt install ffmpeg

# macOS
brew install ffmpeg

# Windows
# Download from https://ffmpeg.org/download.html and add to PATH

# Android Termux
pkg install python ffmpeg
```

### From Source

```bash
git clone https://github.com/6x-u/termflux.git
cd termflux
pip install -e .
```

The C extensions (`_engine` and `_decoder`) build automatically. If compilation fails (e.g., no FFmpeg dev headers), the library falls back to pure Python.

---

## Quick Start

### Display an Image

```python
import termflux

img = termflux.Image("photo.jpg")
img.show(
    border_style=termflux.BORDER_ROUND,
    border_r=255, border_g=215, border_b=0,
    render_mode=termflux.RENDER_QUARTER,
)
input()
termflux.reset()
```

### Play a Video

```python
import termflux

vid = termflux.Video("video.mp4")
vid.play(
    render_mode=termflux.RENDER_QUARTER,
    with_audio=True,
    brightness=1.05,
    saturation=1.15,
)
```

### Play Audio (Terminal UI)

```python
import termflux

audio = termflux.Audio("track.mp3")
audio.play()
```

Displays a full terminal UI with waveform visualization, progress bar, elapsed time, codec info, and playback status.

### Load from URL

```python
import termflux

img = termflux.Image("https://example.com/photo.jpg")
img.show()

vid = termflux.Video("https://example.com/clip.mp4")
vid.play(with_audio=True)
```

---

## CLI

```bash
# Basic image display
termflux photo.jpg

# Gold round border
termflux photo.jpg -b round --border-color 255,215,0

# Video with audio
termflux video.mp4

# Sixel mode (pixel-perfect on supported terminals)
termflux photo.jpg -r sixel

# Grayscale with thick double border
termflux photo.jpg --grayscale -b double --border-thick 3

# High contrast vivid video
termflux video.mp4 --contrast 1.4 --saturation 1.6 --brightness 1.1

# Audio playback
termflux song.mp3 -t audio

# Custom position and size
termflux photo.jpg -p top-left -W 60 -H 30 -b single

# Inverted colors with padding
termflux photo.jpg --invert --padding 2 -b round

# Stretch to fill
termflux photo.jpg --aspect stretch

# Loop video
termflux video.mp4 -l
```

### CLI Options

| Option | Short | Default | Description |
|--------|-------|---------|-------------|
| `source` | | required | File path or URL |
| `--type` | `-t` | auto | Force type: `image`, `video`, `audio` |
| `--width` | `-W` | auto | Width in columns |
| `--height` | `-H` | auto | Height in rows |
| `--position` | `-p` | `center` | `center`, `top`, `bottom`, `left`, `right`, `top-left`, `top-right`, `bottom-left`, `bottom-right` |
| `--border` | `-b` | `none` | `none`, `single`, `double`, `bold`, `round` |
| `--border-color` | | `255,255,255` | RGB values comma-separated |
| `--border-thick` | | `1` | Border thickness (1-5) |
| `--padding` | | `0` | Padding inside border |
| `--render` | `-r` | `quarter` | `sixel`, `quarter`, `half` |
| `--aspect` | | `fit` | `fit`, `fill`, `stretch` |
| `--brightness` | | `1.0` | 0.0 - 3.0 |
| `--contrast` | | `1.0` | 0.0 - 3.0 |
| `--saturation` | | `1.0` | 0.0 - 3.0 |
| `--grayscale` | | `false` | Convert to grayscale |
| `--invert` | | `false` | Invert colors |
| `--loop` | `-l` | `false` | Loop video |

---

## Python API

### termflux.Image

```python
img = termflux.Image(source)          # file path or URL

img.width                              # source width in pixels
img.height                             # source height in pixels
img.pixels                             # raw RGB bytes (width * height * 3)

img.show(
    border_style=termflux.BORDER_NONE, # BORDER_NONE / SINGLE / DOUBLE / BOLD / ROUND
    border_r=255, border_g=255, border_b=255,
    position="center",
    width=None, height=None,           # override display size
    render_mode=termflux.RENDER_QUARTER,  # RENDER_SIXEL / RENDER_QUARTER / RENDER_HALF
    border_thick=1,
    padding=0,
    brightness=1.0,
    contrast=1.0,
    saturation=1.0,
    grayscale=False,
    invert=False,
    aspect="fit",                      # fit / fill / stretch
)
```

### termflux.Video

```python
vid = termflux.Video(source)

vid.width                              # frame width
vid.height                             # frame height
vid.fps                                # frames per second
vid.duration                           # duration in seconds

vid.play(
    border_style=termflux.BORDER_NONE,
    border_r=255, border_g=255, border_b=255,
    position="center",
    width=None, height=None,
    with_audio=True,                   # sync audio playback
    loop=False,
    render_mode=termflux.RENDER_QUARTER,
    border_thick=1,
    padding=0,
    brightness=1.0,
    contrast=1.0,
    saturation=1.0,
    grayscale=False,
    invert=False,
    aspect="fit",
)
```

### termflux.Audio

```python
audio = termflux.Audio(source)

audio.play()                           # blocking, shows terminal UI
audio.play(show_ui=False)              # blocking, no UI
audio.play_background()                # non-blocking background playback
audio.stop()
audio.is_playing                       # bool
```

### termflux.Player (Unified)

```python
p = termflux.Player(source, media_type=None)  # auto-detects type
p.border(termflux.BORDER_ROUND, 255, 215, 0)
p.border_thickness(2)
p.set_padding(1)
p.position("center")
p.size(width=80, height=40)
p.render_mode(termflux.RENDER_QUARTER)
p.set_aspect("fit")
p.set_brightness(1.1)
p.set_contrast(1.2)
p.set_saturation(1.3)
p.set_grayscale(False)
p.set_invert(False)
p.loop(True)
p.show()
```

### Low-Level Functions

```python
# Terminal control
termflux.clear_screen()
termflux.hide_cursor()
termflux.show_cursor()
termflux.reset()
cols, rows = termflux.get_terminal_size()

# Render raw RGB data to terminal escape sequences
frame = termflux.render_frame(
    pixels, width, height,
    term_width=80, term_height=24,
    offset_x=0, offset_y=0,
    border_style=termflux.BORDER_NONE,
    border_r=255, border_g=255, border_b=255,
    render_mode=termflux.RENDER_QUARTER,
    border_thick=1, padding=0,
    brightness=1.0, contrast=1.0, saturation=1.0,
    grayscale=0, invert=0,
)
termflux.flush_frame(frame)

# Scale pixel data (uses Lanczos3 for large ratios, bilinear otherwise)
scaled = termflux.scale(pixels, src_w, src_h, dst_w, dst_h)

# Precise sleep (nanosleep on POSIX, QueryPerformanceCounter on Windows)
termflux.sleep_precise(0.016)

# Windows ANSI support
termflux.enable_ansi()
```

---

## Constants

```python
# Border styles
termflux.BORDER_NONE    # 0
termflux.BORDER_SINGLE  # 1 — ┌─┐│└─┘
termflux.BORDER_DOUBLE  # 2 — ╔═╗║╚═╝
termflux.BORDER_BOLD    # 3 — ┏━┓┃┗━┛
termflux.BORDER_ROUND   # 4 — ╭─╮│╰─╯

# Render modes
termflux.RENDER_HALF    # 0 — classic half-block
termflux.RENDER_QUARTER # 1 — HD quarter-block (default)
termflux.RENDER_SIXEL   # 2 — pixel-perfect Sixel bitmap
```

---

## Render Modes

### Sixel (RENDER_SIXEL)

Pixel-level bitmap rendering using the Sixel protocol. Renders actual pixels — not character approximations. Supports up to 256 colors with Floyd-Steinberg dithering and RLE compression. Best quality available.

Supported terminals: mlterm 3.9+, foot, WezTerm, iTerm2 3.3+, xterm (with sixel compiled in), mintty.

### Quarter-Block (RENDER_QUARTER)

Uses 16 Unicode quarter-block characters (U+2580-U+259F) to render a 2x2 pixel grid per terminal cell. Each cell maps 4 sub-pixels to 2 colors (foreground + background) using perceptual color distance. Double the horizontal resolution of half-block mode.

Scaling uses Lanczos3 interpolation for downsampling ratios > 1.2x, producing sharper output than bilinear filtering.

### Half-Block (RENDER_HALF)

Classic rendering using upper-half (▀) and lower-half (▄) block characters. One cell = 2 vertical pixels. Compatible with every terminal that supports 24-bit ANSI color.

---

## Platform Support

| Platform | Engine | Audio | Video | Sixel |
|----------|--------|-------|-------|-------|
| **Linux x86_64** | C native | ffplay, mpv, aplay | FFmpeg C API | depends on terminal |
| **Linux aarch64** | C native | ffplay, mpv, aplay | FFmpeg C API | depends on terminal |
| **Windows x86** | C native | ffplay, mpv | FFmpeg C API | limited |
| **Windows x64** | C native | ffplay, mpv | FFmpeg C API | limited |
| **macOS** | C native | ffplay, mpv, play | FFmpeg C API | iTerm2 |
| **Android Termux** | C native | termux-media-player, ffplay | FFmpeg C API | depends on terminal |
| **Android Pydroid** | Python fallback | limited | FFmpeg subprocess | limited |
| **Android QPython** | Python fallback | limited | FFmpeg subprocess | limited |

The pure Python fallback (`_fallback.py`) provides full rendering capabilities without requiring C compilation. It activates automatically when the C extension fails to load.

---

## Architecture

```
termflux/
├── _engine.c          C rendering engine
│                      - Bilinear + Lanczos3 scaling
│                      - Half-block, quarter-block, Sixel renderers
│                      - Color filters (brightness, contrast, saturation)
│                      - Border drawing with 5 styles
│                      - Perceptual color distance
│
├── _decoder.c         C media decoder (FFmpeg API)
│                      - Video frame extraction (rgb24)
│                      - Seek support
│
├── _fallback.py       Pure Python rendering engine
│                      - Full feature parity with C engine
│                      - Works on Android without C compiler
│
├── image.py           Image display API
├── video.py           Video playback with frame timing + audio sync
├── audio.py           Audio playback with terminal UI visualizer
├── player.py          Unified Player API
├── loader.py          URL fetcher + file resolver
├── cli.py             Command-line interface
└── __init__.py        Package exports
```

---

## Examples

See the `examples/` directory:

| Script | Description |
|--------|-------------|
| `show_image.py` | Display image with golden round border |
| `play_video.py` | Play video with pink bold border and audio |
| `play_audio.py` | Play audio with terminal visualizer |
| `color_filters.py` | Demonstrate brightness, contrast, saturation, grayscale, invert |
| `border_styles.py` | Show all 5 border styles side by side |
| `player_api.py` | Unified Player API usage |
| `video_with_headers.py` | Video playback with HUD overlay (title, progress, timer) |
| `demo.py` | Full feature demo script |

### Shell Scripts

```bash
scripts/quick_image.sh    # One-liner image display
scripts/quick_video.sh    # One-liner video playback
scripts/quick_audio.sh    # One-liner audio playback
```

---

## Building Wheels

### Local Build

```bash
pip install build
python -m build
```

### Cross-Platform (CI)

The repository includes GitHub Actions workflow (`.github/workflows/build.yml`) that builds:

- **Linux**: x86_64, aarch64 (manylinux)
- **Windows**: AMD64 (x64), x86 (32-bit)
- **Source distribution**: universal

Triggered on version tags (`v*`) or manual dispatch.

```bash
git tag v1.0.0
git push origin v1.0.0
```

---

## Supported Media Formats

### Images
`.png` `.jpg` `.jpeg` `.bmp` `.gif` `.tiff` `.webp` `.ico`

### Video
`.mp4` `.avi` `.mkv` `.mov` `.webm` `.flv` `.wmv` `.m4v`

### Audio
`.mp3` `.wav` `.ogg` `.flac` `.aac` `.m4a` `.wma` `.opus`

Any format supported by FFmpeg works. The above are auto-detected by file extension.

---

## License

Proprietary. See [LICENSE](LICENSE) for terms.

- Free to use in personal and commercial projects
- Modification allowed
- Must retain author attribution: **MERO:TG@QP4RM**
- Must retain project name: **termflux**
- Cannot remove or change copyright notices
- Cannot redistribute as standalone library under different name/author

---

```
termflux v1.0.0
Author: MERO:TG@QP4RM
https://github.com/6x-u/termflux
```
