termframe
termframe turns video and images into ASCII art in the terminal, with color and half-block modes. It's a Python library with a Rust core, and it doesn't require FFmpeg to be installed on your system.
The Rust core does the pixel-to-ASCII conversion (this part is adapted from tplay, built with PyO3 and maturin). Video decoding happens in Python through PyAV, which bundles FFmpeg inside its own wheels. So the whole thing installs with pip, and you don't have to install system libraries or match FFmpeg versions.
Install
pip install termframe
This also pulls in av (PyAV) and numpy, both as prebuilt wheels, so there's
no Rust toolchain or FFmpeg install involved.
Quick start
AsciiVideo owns the decode loop, so you iterate over it to get frames:
from termframe import AsciiVideo
video = AsciiVideo("song.mp4", out_width=100, out_height=40,
charset="halfblock", pad=True, loop=True)
for frame in video: # runs forever while loop=True
print("\x1b[H" + frame.to_ansi()) # draw the video area
print(" now playing: My Song, My Artist")
It opens the file, decodes, loops, and seeks for you. Draw whatever you want
around each frame. There's a paced player in
examples/demo.py.
AsciiVideo
AsciiVideo(path, *, out_width=80, out_height=24, charset="chars3",
half_block=None, preserve_aspect_ratio=True, char_aspect_ratio=2.0,
pad=False, smooth=False, loop=False)
- Iterable, yields
AsciiFrame(runs forever whenloop=True). .fps,.dimensions,.duration_secsfor source metadata..seek(seconds)for an absolute seek (applies on the next frame)..set_size(w, h)to change the target grid, for example on a terminal resize..close(), and it works as a context manager (with AsciiVideo(...) as v:).
path can be anything FFmpeg opens: local files, HLS/RTSP, or http(s) streams.
AsciiFrame
.text: raw grid characters, row-major, no newlines (len == width*height).width,.height: grid shape, so you can re-slice or composite it yourself.color: per-cell RGBbytes(3 per cell normally, 6 per cell in half-block mode).half_block: whether half-block mode was used.to_plain(): grayscale text with\nbetween rows.to_ansi(): a truecolor string you can print directly
Charsets: chars1, chars2, chars3 (default), halfblock (highest fidelity,
2 pixels per cell using foreground and background color), solid, dotted,
gradient, blackwhite, bw_dotted, braille.
Sizing: by default the frame is fitted inside out_width by out_height while
keeping its aspect ratio (using char_aspect_ratio, around 2.0 for typical
terminal cells). Set pad=True to center-pad it to exactly that grid if you
want a stable layout, or preserve_aspect_ratio=False to stretch it.
Low-level API
If you decode frames somewhere else (OpenCV, Pillow, a capture device), skip
AsciiVideo and call the converter directly:
import termframe
# raw RGB24 bytes: width*height*3, row-major
frame = termframe.frame_to_ascii(rgb_bytes, width=w, height=h,
out_width=100, out_height=40, charset="halfblock")
# or a single image file (PNG/JPEG)
frame = termframe.image_to_ascii("cover.png", out_width=80, out_height=24)
Building from source
You only need the Rust toolchain for this, not FFmpeg:
pip install maturin
maturin develop --features python # into the active venv
# or a distributable wheel:
maturin build --release --features python
Using it from Rust
The core is also a regular Rust crate. See src/converter.rs for
rgb_frame_to_ascii, image_to_ascii, AsciiConfig, and AsciiFrame.
Metadata
Release files for termframe 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| termframe-0.1.0.tar.gz | 21.4 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| termframe-0.1.0-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details |
| termframe-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| termframe-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| termframe-0.1.0-cp38-abi3-macosx_11_0_arm64.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64 | Details |
| termframe-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl | CPython 3.8 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 5.3 MB
Release files / termframe-0.1.0.tar.gz
| Download URL | termframe-0.1.0.tar.gz |
|---|---|
| Size | 21.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5ce8d5a61a2d9668af888136178f20942a3db112502e7e6428542ccd96cf7bcb
|
|
BLAKE2b-256 checksum How to use checksums |
ed9722fb7504c14db025e015e6b40d22d76a4730b20b1ec1f6e82d19738504c1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logRelease files / termframe-0.1.0-cp38-abi3-win_amd64.whl
| Download URL | termframe-0.1.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 966.2 kB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
545191183d4f3bd8e8928c9756b4862c6009a13a8d93f2ec2a38f46a39416f45
|
|
BLAKE2b-256 checksum How to use checksums |
93d830c7c024bf4e651c4b005d9752aa7daf86ca0f50aaedc39ffeb4e4edace9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logRelease files / termframe-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | termframe-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
a40f4ee970feba7e937310266cbccfe1bfa7f8739f77322de8e4edde3778e3d5
|
|
BLAKE2b-256 checksum How to use checksums |
2cb3f7fc14f5bc88f31d49952930c50a11b84e4d799bc30e98037662accff6d5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logRelease files / termframe-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | termframe-0.1.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 987.0 kB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
7d1f608246679929cf6f4e5d41d1c10de162197fc49849bde53a96332ebf0acf
|
|
BLAKE2b-256 checksum How to use checksums |
606d531b0cba3f7df93ec799c4c78ec8742d29612c87e46b401f5dafeb548277
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logRelease files / termframe-0.1.0-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | termframe-0.1.0-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 955.2 kB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b3b301b4058c6cf576e311cea67368b70b6b034a9e1f7315af1fe54126e9ac27
|
|
BLAKE2b-256 checksum How to use checksums |
290b1048ce40951eab5bcc6ca87fdf7a926aa8c8f85eab8391009d94cb423571
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency logRelease files / termframe-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | termframe-0.1.0-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
2ca68b8e0275502047902976b35229c3d740efc8aee601ac94062b25911674c4
|
|
BLAKE2b-256 checksum How to use checksums |
7bb9a40de2afe079347d59b12b97f0358443432ed0d8af9e6c21d2ab0ac1f036
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 23, 2026.
Transparency log