CLI tool
maxcurzi/tplay avatar
maxcurzi/tplay

tplay: a terminal media player that renders video as ASCII art

A terminal ASCII media player. View images, gifs, videos, webcam, YouTube, etc.. directly in the terminal as ASCII art.

697 stars42 forksRustMIT

At a glance

What is it?
A Rust crate that plays images, gifs, videos, YouTube links, webcam and live streams as characters in the terminal, with sound, subtitles and RGB colour. The author lists replacing a fully fledged media player as an explicit non goal, and calls the project early development.
Who is it for?
Adopt tplay if you work in a terminal and want to watch a clip, check a webcam or share a video without opening a graphical player, and you are happy with ASCII fidelity. Skip it if you need picture quality, since a character grid cannot carry it, and skip it on native Windows, where the readme says installation is lengthy, error prone and very slow and recommends WSL instead.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 55 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What it does, and the checklist it publishes

The project is a terminal ASCII media player. View images, gifs, videos, webcam, YouTube and more directly in the terminal as ASCII art, and the readme is quick to point out that all the images shown are just characters on the terminal command line, drawn really fast.

The feature list is a checklist, and reading it as a checklist tells you the shape of the tool better than a paragraph would. Done: converts and shows any media to ASCII art in the terminal. Supports images, gifs, videos, webcam, YouTube links, and streaming protocols, specifically RTSP, RTMP, SRT, UDP, TCP, RTP, MMS and HLS. Any resolution, aspect ratio and framerate. Use any character set as supported by your terminal. Handy pause and unpause with character map selection controls. RGB colours on terminals that support them. Play sounds. Full media controls, forward and backwards and so on. Subtitles. And spark joy.

Not done: replace a fully-fledged media player. That line is in the list as an unchecked box, which is a more honest framing than most projects manage, and it tells you the author is not competing with mpv or vlc on features.

The audience section is equally direct, and it is charming rather than corporate. You really don't like graphical applications or work on a computer without graphical capabilities. You are looking for a quick way to convert visual media to ASCII art. You want to watch a video in the terminal but do not want to use mpv or vlc because they are too mainstream. You want to show off your terminal skills to your friends and make them think you are a hacker.

So this is a toy that happens to be genuinely useful, and knowing which of those two it is for you matters.

The dependency chain is the real cost of running it

The prerequisites section is where the project's character shows, because it is a Rust crate with a substantial native dependency list, and the readme lists every piece.

Rust itself is the first requirement, with the installation instructions linked. Then FFmpeg development libraries, tested with FFmpeg 6.1 and 7.1 on Linux and 9.x on macOS through Homebrew. Then libmpv-dev, the development libraries for audio playback and subtitles. And an optional dependency for YouTube playback support, yt-dlp.

The Cargo manifest confirms how these are used. ffmpeg-next at 9.0.0 is the Rust binding to FFmpeg, which is where the decoding and the frame conversion happen. libmpv is version 5.0.3, packaged as libmpv2 and optional, and the comment on that line says MPV 0.35+. rodio is version 0.20.1 and also optional, described as an audio playback alternative to mpv. youtube_dl at 0.10 handles the YouTube side.

The features section shows how the optional pieces compose. The default feature set is mpv, and the mpv feature enables libmpv, while rodio_audio enables rodio. So the default build routes audio through mpv, and the alternative exists for people who would rather not link libmpv.

The rest of the dependencies are the ordinary Rust terminal stack. clap 4.2 with derive for the command line, crossterm 0.28 for terminal control, image 0.25 and fast_image_resize 5.0.0 for decoding and scaling frames to the character grid, libwebp-sys 0.11 for WebP, gif 0.13.1 and gif-dispose 5.0.0-beta.2 for animated images, crossbeam-channel 0.5 for the worker channels, and reqwest with the blocking feature for network access. The crate declares a default-run of tplay and a single binary at src/main.rs, and the package metadata includes Debian packaging with a maintainer and a dependency list of ffmpeg, libavfilter-dev, libavdevice-dev and libasound2-dev.

Installing on Linux, macOS and the advice to skip Windows

The installation instructions are per platform, and the macOS section is the most careful one, which tells you the author has actually hit these problems.

On Ubuntu you install Rust first, and then the dependency packages:

bash
sudo apt install libssl-dev ffmpeg libavfilter-dev libavdevice-dev libavformat-dev libavcodec-dev libswscale-dev libasound2-dev yt-dlp libmpv-dev clang

That list is what libmpv and FFmpeg need to build against, and it is long enough that the readme includes a per-distribution breakdown rather than a one line install.

On macOS the setup is described as minimal, using Homebrew, and the commands set the needed environment variables, run quick checks, then install:

bash
# 1) Install dependencies
xcode-select -p >/dev/null 2>&1 || xcode-select --install
brew update
brew install pkg-config cmake ffmpeg yt-dlp mpv

The reason for the extra steps is that pkg-config has to find FFmpeg, which Homebrew does not put on the default search path:

bash
# 2) Session-only exports so pkg-config can find FFmpeg
export PKG_CONFIG_PATH="$(brew --prefix)/lib/pkgconfig:$(brew --prefix)/share/pkgconfig:$(brew --prefix ffmpeg)/lib/pkgconfig:${PKG_CONFIG_PATH:-}"

Then a check that should print a version:

bash
# 3) Quick checks (should print versions)
pkg-config --modversion libavutil

And the install itself, with a forced variant for updating an existing copy:

bash
# 4) Install / update
cargo install tplay         # fresh install
# or
cargo install tplay --force # update existing

There is a one-off troubleshooting note for when that check fails, pointing pkg-config at a specific Homebrew formula for a single command only, using brew install ffmpeg@7.

The Windows section is the most valuable one to read, and it is a warning. The crate can run on Windows and all prerequisites can be installed with vcpkg, but the installation and setup process is lengthy and prone to errors, and performance is also very poor. The recommendation is to use WSL and follow the Linux instructions instead.

The features that are about the terminal, not about the media

Several of the checked features are about the terminal rather than the playback, and they are what separates this from a script that prints a frame once.

Dynamic resize means the rendering follows the window when you resize the terminal. Live update when updating character size means the picture redraws as you change the font size, which is a different thing, because a terminal font size change is a display property rather than a viewport size change and a naive renderer will not notice it. On-the-fly character map selection lets you change which characters are used for the luminance ramp without restarting, which is the fastest way to find a character set that suits the content.

Use any character set as supported by your terminal is the framing for all of that, and it is where the tool gets its look. The character ramp is the palette, and a monochrome terminal is the limiting case.

RGB colours work on terminals that support them, and the readme is honest that this is conditional.

Emojis get their own entry, which is the most unusual of the group. Emoji are a natural fit for a character grid, and rendering a colour emoji as an ASCII approximation is a different problem from rendering a photograph, because the source is already a small grid of coloured cells.

Together these are the features that make the tool pleasant to use rather than merely possible, and they are all terminal problems. The media side is delegated to FFmpeg and mpv, and the interesting engineering is in the layer between them.

Where this is the wrong tool

There are several situations where tplay is the wrong answer, and one where it is a security consideration rather than a preference.

The first is picture quality. A character grid has a hard ceiling on what it can represent, and no amount of tuning gets you closer to the source. If the point of playing the video is to see it, rather than to prove you can watch it in a terminal, this is the wrong tool and mpv or vlc will serve you better in every respect except the aesthetic.

The second is the checklist item. Replace a fully-fledged media player is explicitly not a goal, and the feature list has gaps you can see. So this is not the tool for a media library workflow, for a playlist you intend to work through, or for anything where you want the full set of codecs, subtitle formats and container support that a mature player has accumulated.

The third is native Windows, where the readme's own advice is to use WSL. A tool whose own documentation tells you to run it in a Linux subsystem is telling you something about its Windows support, and the note about poor performance and a lengthy, error prone setup is the honest version.

The fourth is the build cost. Rust, FFmpeg development libraries, libmpv development libraries, and on Ubuntu a list of ten packages including clang. If you are on a locked down machine, this is a heavy dependency set for a media player, and the wheel-based install path exists precisely because the source build is not trivial.

And the fifth is the YouTube path, which depends on yt-dlp and therefore on a third party tool that changes shape often. That is a moving dependency in a project that is itself described as being in early development, and the last push was on 2026-08-31 with the most recent release v0.10.0 the same day.

Against a real media player, and against a one shot image converter

Two comparisons clarify where tplay earns its place.

The first is against mpv or vlc. The difference in approach is what the tool is for. mpv is a media player first, and its rendering is a means to an end. tplay is a renderer first, and the media pipeline is a means to an end. The result is that tplay can do things a conventional player will not, such as drawing a video in a terminal that has no graphics capability at all, and it can change its character map while playing. What it gives up is everything a mature player has, and the readme's own checklist says the same thing.

The second is against a one-shot conversion script. Plenty of people have written a small tool that decodes an image and prints it as characters, and that approach has a real advantage over tplay: it is small, has no dependency on FFmpeg development libraries, and does one thing. tplay is a player, so it has to handle streams, audio, subtitles, seeking, and resize events, and the dependency chain follows from that scope.

The decision rule is roughly this. If you want to convert one image to ASCII art once, a small script is less trouble. If you want to watch something in a terminal, play a webcam in ASCII, or stream a camera over the network into a text window, tplay is doing something a script does not, and the dependencies are the price of that.

One more practical point about the two audio backends. The default is mpv through libmpv, and rodio is the optional alternative, and they are not equivalent. libmpv gives you a full player under the hood, and rodio is a Rust audio output path. Choosing rodio removes the libmpv dependency but also removes much of what a media player does.

Editorial conclusion

Adopt tplay if you work in a terminal and want to watch a clip, check a webcam or share a video without opening a graphical player, and you are happy with ASCII fidelity. Skip it if you need picture quality, since a character grid cannot carry it, and skip it on native Windows, where the readme says installation is lengthy, error prone and very slow and recommends WSL instead. Verify first that FFmpeg and libmpv development libraries are present, that your terminal supports RGB colour if you want it, and that the mpv-backed default is what you want rather than the optional rodio audio path.

Frequently asked questions

What media can tplay show in the terminal?

Images, gifs, videos, webcam input, YouTube links, and streaming protocols including RTSP, RTMP, SRT, UDP, TCP, RTP, MMS and HLS, at any resolution, aspect ratio and framerate, using any character set your terminal supports.

What does tplay need installed before it will build?

Rust, FFmpeg development libraries, tested with FFmpeg 6.1 and 7.1 on Linux and 9.x on macOS, and libmpv-dev for audio playback and subtitles, with yt-dlp as an optional dependency for YouTube playback support. The Cargo manifest also pulls in clap, crossterm, image, fast_image_resize, ffmpeg-next and libmpv.

How do I install tplay from source on Ubuntu?

Install Rust first with the rustup script, then the dependency packages with apt, which covers libssl-dev, ffmpeg, the libav and libswscale dev packages, libasound2-dev, yt-dlp, libmpv-dev and clang. Once those are present, cargo install tplay builds the binary, and cargo install tplay --force updates an existing installation.

Does tplay work on Windows?

The crate can run on Windows and the prerequisites can be installed with vcpkg, but the readme says the installation and setup process is lengthy and prone to errors and that performance is very poor. It recommends using WSL and following the Linux instructions instead.

What are the two audio backends in tplay?

The default feature is mpv, which enables libmpv 5.0.3 packaged as libmpv2 for MPV 0.35 and later. The optional rodio_audio feature enables rodio 0.20.1 as an alternative audio playback path, and the default set in the Cargo manifest is the mpv feature.

How active is tplay right now?

The readme describes the crate as still in early development, and the project keeps a checklist of what it can and cannot do, with replace a fully-fledged media player explicitly not a goal. The recent releases are v0.9.2 on 2026-04-01, v0.9.3 on 2026-04-13 and v0.10.0 on 2026-08-31, and the last push was on 2026-08-31. The licence is MIT.

Official sources

  1. Issues
  2. License: MIT
  3. maxcurzi/tplay on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/maxcurzi-tplay.svg)](https://hysenlabs.com/projects/maxcurzi-tplay)

Was this useful?