4 releases (breaking)
Uses new Rust 2024
| 0.4.0 | Apr 3, 2026 |
|---|---|
| 0.3.0 | Apr 2, 2026 |
| 0.2.0 | Apr 1, 2026 |
| 0.1.0 | Apr 1, 2026 |
#1007 in Text processing
49KB
994 lines
Bad Crab Apple π¦π
A standalone, single-binary CLI player for "Bad Apple!!" written in Rust. Audio and video are compiled directly into the binary β no external files or dependencies needed at runtime.
Building
cargo build --release
This takes a moment: it embeds ~15MB of compressed audio and video frames into the binary.
Running
./target/release/bad-apple
This plays the video in the default block mode. The video scales automatically to your terminal size, maintaining the original 4:3 aspect ratio. Press q, Esc, or Ctrl+C to quit.
Render Modes
The renderer maps each 1-bit pixel to a terminal character. Because terminal characters are taller than they are wide, each row samples two video rows (top half and bottom half), giving four possible states per character: empty, top-lit, bottom-lit, and fully-lit.
There are five built-in modes:
| Mode | Flag | Characters | Notes |
|---|---|---|---|
classic |
--classic |
' ' - * @ |
Default. Sampled from " .:-=+*#%@". |
block |
--block |
' ' β β β |
Highest visual quality. |
ascii |
--ascii |
'.' ^ v @ |
Narrow ASCII characters. |
shading |
--shading |
' ' β β β |
Unicode block shading. |
korean |
--korean |
μ λ½ λ λΎ |
Wide (2-column) Korean glyphs. Aspect ratio is corrected automatically. |
Use either the flag shorthand or --mode <name>:
./target/release/bad-apple --shading
./target/release/bad-apple --mode shading
Custom Characters
--chars β specify all four states directly
Provide exactly 4 characters in the order: empty Β· top-lit Β· bottom-lit Β· fully-lit.
./target/release/bad-apple --chars " .':"
./target/release/bad-apple --chars " κ°μλΏ"
--gradient / -g β sample from a palette
Provide a string of 2 or more characters from darkest to brightest. Four characters are sampled evenly from it (at 0%, 33%, 67%, 100%) and used for the four states.
./target/release/bad-apple -g " .:-=+*#%@"
./target/release/bad-apple -g " ββββ"
For both options, character display width is detected automatically β wide/CJK characters (2 columns) get a different aspect ratio correction than narrow characters (1 column).
How it works
The original video was thresholded to 1-bit per pixel (pure black and white) and scaled to 160Γ120. At 1 bit per pixel, 8 pixels pack into a single byte. The resulting frames.bin contains 6,572 frames at 30 fps and is ~15MB. Audio is stored as a compressed MP3. Both are embedded into the binary at compile time via include_bytes!.
Dependencies
~9β42MB
~619K SLoC