Skip to content

6x-u/termflux

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

pip install termflux

Dependencies

  • Python >= 3.8
  • FFmpeg (video/image decoding and audio playback)
# 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

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

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

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)

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

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

# 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

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

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

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)

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

# 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

# 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

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

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.

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 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

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors