โค ASCII Video
Renders any content as colored ASCII character video. Audio, video, images, text, or pure math in, MP4/GIF/PNG sequence out. Full RGB color per character cell, 1080p 24fps default. No GPU.
Built for Hermes Agent. Usable in any coding agent. Canonical source lives here; synced to NousResearch/hermes-agent/skills/creative/ascii-video via PR.
What this is
A skill that teaches an agent how to build single-file Python renderers for ASCII video from scratch. The agent gets the full pipeline: grid system, font rasterization, effect library, shader chain, audio analysis, parallel encoding. It writes the renderer, runs it, gets video.
The output is actual video. Not terminal escape codes. Frames are computed as grids of colored characters, composited onto pixel canvases with pre-rasterized font bitmaps, post-processed through shaders, piped to ffmpeg.
Modes
| Mode | Input | Output | |
| ------ | ------- | -------- | |
| Video-to-ASCII | A video file | ASCII recreation of the footage | |
| Audio-reactive | An audio file | Visuals driven by frequency bands, beats, energy | |
| Generative | Nothing | Procedural animation from math | |
| Hybrid | Video + audio | ASCII video with audio-reactive overlays | |
| Lyrics/text | Audio + timed text (SRT) | Karaoke-style text with effects | |
| TTS narration | Text quotes + API key | Narrated video with typewriter text and generated speech | |
| Size | Font | Grid at 1080p | Use |
| ------ | ------ | --------------- | ----- |
| xs | 8px | 400x108 | Ultra-dense data fields |
| sm | 10px | 320x83 | Rain, starfields |
| md | 16px | 192x56 | Default balanced |
| lg | 20px | 160x45 | Readable text |
| xl | 24px | 137x37 | Large titles |
| xxl | 40px | 80x22 | Giant minimal |
| Family | Examples | Feel | |
| -------- | ---------- | ------ | |
| Density ramps | .:-=+#@โ | Classic ASCII art gradient | |
| Block elements | โโโโโโโโ | Chunky, digital | |
| Braille | โ โ โ ...โ ฟ | Fine-grained pointillism | |
| Dots | โ
โโโโโ | Smooth, organic | |
| Stars | ยทโงโฆโฉโจโ
โถ | Sparkle, celestial | |
| Half-fills | โโโโโโโโโ | Directional fill progression | |
| Crosshatch | โฃโคโฅโฆโงโจโฉ | Hatched density ramp | |
| Math | ยทโโโขยฐยฑรรทโโ โกโโซโฮฉ | Scientific, abstract | |
| Box drawing | โโโโโโโโคโฌโดโผ | Structural, circuit-like | |
| Katakana | ยท๏ฝฆ๏ฝง๏ฝจ๏ฝฉ๏ฝช๏ฝซ๏ฝฌ๏ฝญ... | Matrix rain | |
| Greek | ฮฑฮฒฮณฮดฮตฮถฮทฮธ...ฯ | Classical, academic | |
| Runes | แ แขแฆแฑแทแแแแแแแ | Mystical, ancient | |
| Alchemical | โโฝโโโโโ
โโ | Esoteric | |
| Arrows | โโโโโโโโโโ | Directional, kinetic | |
| Music | โชโซโฌโฉโญโฎโฏโโ | Musical | |
| Project-specific | .ยท~=โโโกโฟโฆโ
โโโโฒโผโโ | Themed per project | |
| Strategy | How it maps hue | Good for | |
| ---------- | ---------------- | ---------- | |
| Angle-mapped | Position angle from center | Rainbow radial effects | |
| Distance-mapped | Distance from center | Depth, tunnels | |
| Frequency-mapped | Audio spectral centroid | Timbral shifting | |
| Value-mapped | Brightness level | Heat maps, fire | |
| Time-cycled | Slow rotation over time | Ambient, chill | |
| Source-sampled | Original video pixel colors | Video-to-ASCII | |
| Palette-indexed | Discrete lookup table | Retro, flat graphic | |
| Temperature | Warm-to-cool blend | Emotional tone | |
| Complementary | Hue + opposite | Bold, dramatic | |
| Triadic | Three equidistant hues | Psychedelic, vibrant | |
| Analogous | Neighboring hues | Harmonious, subtle | |
| Monochrome | Fixed hue, vary S/V | Noir, focused | |
| Field | Description | ||
| ------- | ------------- | ||
| Sine field | Layered multi-sine interference, general-purpose background | ||
| Smooth noise | Multi-octave sine approximation of Perlin noise | ||
| Rings | Concentric rings, bass-driven count and wobble | ||
| Spiral | Logarithmic spiral arms, configurable arm count/tightness | ||
| Tunnel | Infinite depth perspective (inverse distance) | ||
| Vortex | Twisting radial pattern, distance modulates angle | ||
| Interference | N overlapping sine waves creating moire | ||
| Aurora | Horizontal flowing bands | ||
| Ripple | Concentric waves from configurable source points | ||
| Plasma | Sum of sines at multiple orientations/speeds | ||
| Diamond | Diamond/checkerboard pattern | ||
| Noise/static | Random per-cell per-frame flicker | ||
| Field | Description | ||
| ------- | ------------- | ||
| Value noise | Smooth organic noise, no axis-alignment artifacts | ||
| fBM | Fractal Brownian Motion โ octaved noise for clouds, terrain, smoke | ||
| Domain warp | Inigo Quilez technique โ fBM-driven coordinate distortion for flowing organic forms | ||
| Voronoi | Moving seed points with distance, edge, and cell-ID output modes | ||
| Field | Description | ||
| ------- | ------------- | ||
| Reaction-diffusion | Gray-Scott with 7 presets: coral, spots, worms, labyrinths, mitosis, pulsating, chaos | ||
| Cellular automata | Game of Life + 4 rule variants with analog fade trails | ||
| Strange attractors | Clifford, De Jong, Bedhead โ iterated point systems binned to density fields | ||
| Temporal noise | 3D noise that morphs in-place without directional drift | ||
| Type | Behavior | ||
| ------ | ---------- | ||
| Explosion | Beat-triggered radial burst with gravity and life decay | ||
| Embers | Rising from bottom with horizontal drift | ||
| Dissolving cloud | Spreading outward with accelerating fade | ||
| Starfield | 3D projected, Z-depth stars approaching with streak trails | ||
| Orbit | Circular/elliptical paths around center | ||
| Gravity well | Attracted toward configurable point sources | ||
| Boid flocking | Separation/alignment/cohesion with spatial hash for O(n) neighbors | ||
| Flow-field | Steered by gradient of any value field | ||
| Trail particles | Fading lines between current and previous positions | ||
| Category | Shaders | ||
| ---------- | --------- | ||
| Geometry | CRT barrel, pixelate, wave distort, displacement map, kaleidoscope, mirror (h/v/quad/diag) | ||
| Channel | Chromatic aberration (beat-reactive), channel shift, channel swap, RGB split radial | ||
| Color | Invert, posterize, threshold, solarize, hue rotate, saturation, color grade, color wobble, color ramp | ||
| Glow/Blur | Bloom, edge glow, soft focus, radial blur | ||
| Noise | Film grain (beat-reactive), static noise | ||
| Lines/Patterns | Scanlines, halftone | ||
| Tone | Vignette, contrast, gamma, levels, brightness | ||
| Glitch/Data | Glitch bands (beat-reactive), block glitch, pixel sort, data bend | ||
| Mood | Shaders | ||
| ------ | --------- | ||
| Retro terminal | CRT + scanlines + grain + amber/green tint | ||
| Clean modern | Light bloom + subtle vignette | ||
| Glitch art | Heavy chromatic + glitch bands + color wobble | ||
| Cinematic | Bloom + vignette + grain + color grade | ||
| Dreamy | Heavy bloom + soft focus + color wobble | ||
| Harsh/industrial | High contrast + grain + scanlines, no bloom | ||
| Psychedelic | Color wobble + chromatic + kaleidoscope mirror | ||
| Profile | Resolution | FPS | When |
| --------- | ----------- | ----- | ------ |
draft | 960x540 | 12 | Check timing/layout |
preview | 1280x720 | 15 | Review effects |
production | 1920x1080 | 24 | Final output |
max | 3840x2160 | 30 | Ultra-high |
auto | Detected | 24 | Adapts to hardware + duration |
| Duration | 4 workers | 8 workers | 16 workers |
| ---------- | ----------- | ----------- | ------------ |
| 30s | ~3 min | ~2 min | ~1 min |
| 2 min | ~13 min | ~7 min | ~4 min |
| 5 min | ~33 min | ~17 min | ~9 min |
| 10 min | ~65 min | ~33 min | ~17 min |
720p roughly halves these. 4K roughly quadruples them.
Known pitfalls
Brightness. ASCII characters are small bright dots on black. Most frame pixels are background. Linear * N multipliers clip highlights and wash out. Use tonemap() with per-scene gamma instead. Default gamma 0.75, solarize scenes 0.55, posterize 0.50.
Render bottleneck. The per-cell Python loop compositing font bitmaps runs at ~100-150ms/frame. Unavoidable without Cython/C. Everything else must be vectorized numpy. Python for-loops over rows/cols in effect functions will tank performance.
ffmpeg deadlock. Never stderr=subprocess.PIPE on long-running encodes. Buffer fills at ~64KB, process hangs. Redirect stderr to a file.
Font cell height. Pillow's textbbox() returns wrong height on macOS. Use font.getmetrics() for ascent + descent.
Font compatibility. Not all Unicode renders in all fonts. Palettes validated at init, blank glyphs silently removed.
Requirements
โ Python 3.10+
โ NumPy, Pillow, SciPy (audio modes)
โ ffmpeg on PATH
โ A monospace font (Menlo, Courier, Monaco, auto-detected)
โ Optional: OpenCV, ElevenLabs API key (TTS mode)
File structure
`
โโโ SKILL.md # Modes, workflow, creative direction
โโโ README.md # This file
โโโ references/
โโโ architecture.md # Grid system, fonts, palettes, color, _render_vf()
โโโ effects.md # Value fields, hue fields, backgrounds, particles
โโโ shaders.md # 38 shaders, ShaderChain, tint presets, transitions
โโโ composition.md # Blend modes, multi-grid, tonemap, FeedbackBuffer
โโโ scenes.md # Scene protocol, SCENES table, render_clip(), examples
โโโ design-patterns.md # Layer hierarchy, directional arcs, scene concepts
โโโ inputs.md # Audio analysis, video sampling, text, TTS
โโโ optimization.md # Hardware detection, vectorized patterns, parallelism
โโโ troubleshooting.md # Broadcasting traps, blend pitfalls, diagnostics
`
Projects built with this
โฆ 85-second highlight reel. 15 scenes (14ร5s + 15s crescendo finale), randomized order, directional parameter arcs, layer hierarchy composition. Showcases the full effect vocabulary: fBM, voronoi fragmentation, reaction-diffusion, cellular automata, dual counter-rotating spirals, wave collision, domain warping, tunnel descent, kaleidoscope symmetry, boid flocking, fire simulation, glitch corruption, and a 7-layer crescendo buildup.
โฆ Audio-reactive music visualizer. 3.5 min, 8 sections with distinct effects, beat-triggered particles and glitch, cycling palettes.
โฆ TTS narrated testimonial video. 23 quotes, per-quote ElevenLabs voices, background music at 15% wide stereo, per-clip re-rendering for iterative editing.