cascii - Interactive ASCII Frame Generator
cascii is a high-performance, interactive tool for converting videos and image sequences into ASCII art frames.
New: cascii can now be used as both a CLI tool and a Rust library!
When converting a video, the output files will be placed in a directory named after the video file. For example, cascii my_video.mp4 will create a my_video directory.
I recommend installing cascii-viewer to easily play any ascii animation generated or decorator
Features
- Interactive Mode: If you don't provide arguments,
casciiwill prompt you for them. - Flexible Input: Works with video files or directories of PNGs.
- Performance: Uses
ffmpegfor fast frame extraction and parallel processing with Rayon for ASCII conversion. - Video Segments: Specify start and end times to convert only a portion of a video.
- Presets:
--smalland--largeflags for quick quality adjustments. - Non-interactive Mode: Use
--defaultto run without prompts, using default values. - Library Support: Use cascii as a dependency in your own Rust projects.
- Flexible FFmpeg: Uses system ffmpeg by default, or accepts custom paths for bundled/embedded ffmpeg binaries.
Requirements
- FFmpeg: Required for video conversion. cascii uses
ffmpegfor frame extraction andffprobefor video metadata.- By default, cascii looks for
ffmpegandffprobeon your system PATH - For library usage, you can specify custom paths (useful for bundling ffmpeg with your application)
- By default, cascii looks for
Installation
As a CLI Tool
An install.sh script is provided to build and install cascii to /usr/local/bin.
# Make sure you are in the cascii directory
You will be prompted for your password as it uses sudo to copy the binary.
Alternatively, install from crates.io (once published):
As a Library
Add to your Cargo.toml:
[]
= "0.1"
CLI Usage
cascii
Interactive
Run cascii without any arguments to be guided through the process:
It will first ask you to select an input file from the current directory, then prompt for the output directory, and finally for the quality settings.
With Arguments
You can also provide arguments directly:
# Basic usage with a video file
# Using presets
# Non-interactive mode (will fail if input is not provided)
# Convert a 5-second clip starting at 10 seconds into the video
Options
[input]: (Optional) The input video file or directory of images.-o,--out: (Optional) The output directory. Defaults to the current directory.--columns: (Optional) The width of the output ASCII art.--fps: (Optional) The frames per second to extract from a video.--font-ratio: (Optional) The aspect ratio of the font used for rendering.--start: (Optional) The start time for video conversion (e.g.,00:01:23.456or83.456).--end: (Optional) The end time for video conversion.--preprocess: (Optional) ffmpeg-vffiltergraph applied before ASCII conversion (video and single-image inputs).--preprocess-preset: (Optional) Built-in preprocessing preset (use--list-preprocess-presets).--list-preprocess-presets: List built-in preprocessing presets and exit.--default: Skips all prompts and uses default values for any missing arguments.-s,--small: Uses smaller default values for quality settings.-l,--large: Uses larger default values for quality settings.--colors: Generate both.txtand.cframe(color) output files.--color-only: Generate only.cframefiles (no.txt).--audio: Extract audio from the video toaudio.mp3.--luminance: Luminance threshold (0-255) for what is considered transparent.--keep-images: Keep intermediate PNG frames after conversion.--to-video: Render ASCII frames into a video file (.mp4) instead of frame files. See Export Movie.--video-font-size: Font size in pixels for--to-videorendering (default:14).--crf: CRF quality for--to-videoencoding (0-51, lower = better, default:18).--trim: Trim equally from all sides of existing frames. Directional overrides:--trim-left,--trim-right,--trim-top,--trim-bottom.--find-loop: Detect repeated frame loops in a directory offrame_*.txtfiles.-h,--help: Shows the help message.-V,--version: Shows the version information.
Export Movie
cascii can render ASCII art frames into an MP4 video file using --to-video. This works both from a source video (full pipeline) and from a directory of previously generated frames.
From a Video File
Convert a video to an ASCII video in one command:
# White on black (default)
# Color — each character rendered in its original pixel color
# Color with audio
From Existing Frames
If you already have a directory of .cframe or .txt files from a previous cascii run, you can render them to video directly:
# From .cframe files (color) — auto-detected if present
# From .txt files (white on black) — used if no .cframe files exist
# With audio (uses audio.mp3 from the directory if present)
When rendering from a directory, cascii scans for .cframe files first (full color). If none are found, it falls back to .txt files (white on black).
Options
| Flag | Description | Default |
|---|---|---|
--to-video |
Enable video output mode | off |
--colors / --color-only |
Generate color data (needed for color video from a source video) | off (white on black) |
--video-font-size <PX> |
Font size in pixels — controls output video resolution | 14 |
--crf <0-51> |
H.264 quality (lower = better quality, larger file) | 18 (visually lossless) |
--audio |
Mux audio into the output video | off |
--columns <N> |
ASCII width in characters | 400 |
--fps <N> |
Frames per second | 30 |
Output resolution is determined by columns × font_size. For example:
| Columns | Font Size | Approximate Width |
|---|---|---|
| 120 | 10 | ~960px |
| 200 | 14 | ~2800px |
| 200 | 32 | ~6400px |
| 400 | 14 | ~5600px |
Examples
# Small compact video
# Medium, readable characters
# Large characters, high resolution
# Lower quality, smaller file size
# Custom output path
# Contour-style preprocessing (raw ffmpeg filtergraph)
# Built-in preprocessing preset
# Specific time range with audio
# Render existing frames to video
Examples:
Source image:

Test 1:
settings:
Luminance: 1
Font Ratio: 0.7
Columns: 400

Test 2:
settings:
Luminance: 35
Font Ratio: 0.7
Columns: 400

Test 3:
settings:
Luminance: 35
Font Ratio: 0.5
Columns: 400

Test 4:
settings:
Luminance: 35
Font Ratio: 1
Columns: 400

Test animation 1:
Reconstituting a few seconds from the clip Aleph 2 by Max Cooper (around 2:30 to 3:00)
Frames: 960
Luminance: 30
Font Ratio: 0.7
Columns: 400
FPS: 30

Library Usage
cascii can be used as a Rust library in your own projects.
Basic Example - Convert an Image to ASCII
use ;
use Path;
Convert Image to String (No File)
use ;
use Path;
Convert a Video to ASCII Frames
use ;
use Path;
Using Presets
use AsciiConverter;
use Path;
Custom FFmpeg Path
By default, cascii uses ffmpeg and ffprobe from your system PATH. If you need to use bundled binaries or a custom installation, use FfmpegConfig:
use ;
use Path;
This is useful for:
- Desktop applications: Bundle ffmpeg with your app for users who don't have it installed
- Tauri/Electron apps: Use sidecar binaries
- Docker containers: Use ffmpeg installed in a non-standard location
- Testing: Use a specific ffmpeg version
API Reference
AsciiConverter
Main converter struct for ASCII art generation.
Methods:
new()- Create converter with default configurationwith_config(config: AppConfig)- Create with custom configurationwith_ffmpeg_config(config: FfmpegConfig)- Set custom ffmpeg/ffprobe pathsfrom_config_file(path: &Path)- Load configuration from fileconvert_image(input, output, options)- Convert image to ASCII fileimage_to_string(input, options)- Convert image to ASCII stringconvert_video(input, output_dir, video_opts, conv_opts, keep_images)- Convert video to ASCII framesconvert_video_to_video(input, video_opts, conv_opts, to_video_opts, callback)- Convert video to ASCII video file (.mp4)render_frames_to_video(input_dir, fps, to_video_opts, callback)- Render existing .cframe/.txt frames to video fileconvert_directory(input_dir, output_dir, options, keep_images)- Convert directory of imagesget_preset(name)- Get a preset by nameoptions_from_preset(name)- Get conversion options from a preset
FfmpegConfig
Configuration for ffmpeg/ffprobe binary paths.
Methods:
new()- Create with default settings (uses system PATH)with_ffmpeg(path)- Set custom ffmpeg binary pathwith_ffprobe(path)- Set custom ffprobe binary path
ConversionOptions
Options for ASCII conversion.
Fields:
columns: Option<u32>- Target width in charactersfont_ratio: f32- Font aspect ratio (width/height)luminance: u8- Luminance threshold (0-255)ascii_chars: String- ASCII character set (darkest to lightest)
Methods:
default()- Create with default optionswith_columns(columns)- Set target widthwith_font_ratio(ratio)- Set font ratiowith_luminance(threshold)- Set luminance thresholdwith_ascii_chars(chars)- Set custom character set
VideoOptions
Options for video conversion.
Fields:
fps: u32- Frames per second to extractstart: Option<String>- Start time (e.g., "00:01:23" or "83")end: Option<String>- End timecolumns: u32- Target width in charactersextract_audio: bool- Whether to extract audio track from video
ToVideoOptions
Options for rendering ASCII frames to a video file.
Fields:
output_path: PathBuf- Output video file path (e.g., "output.mp4")font_size: f32- Font size in pixels for rendering (default: 14.0)crf: u8- H.264 quality, 0-51 (default: 18, visually lossless)mux_audio: bool- Whether to mux audio into the output video
Examples
See the examples/ directory for complete examples:
simple_image.rs- Basic image conversionsimple_video.rs- Video conversion
Run examples with:
Sample commands
Test Image
./target/release/ascii-gen
--input ./some_frames_dir
--out ../output/sunset_hl
--font-ratio 0.7
Test Video
./target/release/ascii-gen
--input ../input.webm
--out ../output/sunset_hl
--columns 800
--fps 30
--font-ratio 0.7
Acknowledgements
This project is inspired by developedbyed's video that I recommend watching, I reused the logic from his bash script and rewrote it in rust so that it could process faster files with more details.