sardonic
v1.0.3
Published
Corner-dwelling chaos creature inspired with a glitchy aesthetic
Readme
sardonic 📺
Corner-dwelling chaos cat inspired by Max Headroom's glitchy aesthetic
"M-M-M-sardonic reporting for d-d-duty!"
The Philosophy
Max Headroom was groundbreaking. In 1985, that stuttering, glitching, rotating talking head was like nothing else on television. The genius wasn't just the character—it was the chaos:
- Random rotation angles
- Unpredictable pauses
- Visual noise and distortion
- That VHS aesthetic
- The feeling that reality was breaking down
Nobody has ever beaten Max Headroom. All we can do is pay homage.
sardonic brings that aesthetic to your narration videos. A corner-dwelling cat that seems to be talking, glitching, existing in that liminal space between signal and noise.
What It Does
Takes multiple image frames (like different cat expressions generated by Midjourney) and creates a chaotic talking head animation by:
- Random Selection: Picks frames randomly
- Random Duration: Each frame plays 0.1-2 seconds (configurable)
- Random Rotation: Rotates ±15° (configurable) around center
- Glitch Effects: Scanlines, noise, chromatic aberration
- Corner Overlay: Places in video corner with alpha transparency
The result: A cat that looks like it's talking, with Max Headroom's signature chaos.
Quick Start
# Create sardonic animation
sardonic --frames "cat-*.jpg"
# Overlay on existing video
sardonic --overlay narration.mp4 --position bottom-right
# Full glitch chaos
sardonic --glitch 3 --rotation 30 --duration 45Installation
Requires:
- Node.js
- ffmpeg
- ImageMagick (for rotation)
npm install # (no dependencies needed!)Usage
Basic Animation
sardonic \
--frames "sunglasses-kitten*.jpg" \
--duration 30 \
--size 320 \
--glitch 2Overlay on Video
# Two-step process
sardonic --frames "cat*.jpg" -o headroom.mp4
sardonic --overlay my-narration.mp4 -o final.mp4
# One-step process
sardonic --frames "cat*.jpg" \
--overlay my-narration.mp4 \
--position bottom-left \
--margin 40 \
-o final.mp4Command Line Options
Basic Options
-f, --frames <pattern>- Frame file pattern (default:sunglasses-kitten*.jpg)-D, --dir <path>- Directory with frames (default:.)-d, --duration <sec>- Animation duration (default: 15)-s, --size <pixels>- Output size, square (default: 320)-r, --rotation <deg>- Max rotation angle (default: 15)-g, --glitch <0-3>- Glitch level (default: 1)-o, --output <file>- Output filename
Overlay Options
-O, --overlay <video>- Input video to overlay on-p, --position <pos>- Position:bottom-right,bottom-left,top-right,top-left-m, --margin <pixels>- Margin from edges (default: 20)
Glitch Levels
Level 0: Clean
- No effects
- Just rotation and timing
- Good for professional contexts
Level 1: Classic (Default)
- Scanlines (the Max Headroom signature)
- Subtle but recognizable
- Perfect balance
Level 2: Medium Chaos
- Scanlines
- Temporal noise
- VHS feel
Level 3: MAXIMUM CHAOS
- Scanlines
- Heavy noise
- Chromatic aberration
- Full 1980s video breakdown
The Midjourney Workflow
This is where it gets powerful. Here's the strategy:
1. Generate Base Character
sunglasses cat portrait, 80s aesthetic, neon colors,
pixelated background, VHS quality, Max Headroom style
--ar 1:1 --stylize 7502. Generate Expressions (using Character Reference)
[paste image URL] --cref [character URL] --cw 100
Variations to generate:
- mouth open
- mouth closed
- eyes wide
- eyes squinting
- tongue out
- winking
- side glance
- surprised look3. Generate Glitch Frames (optional)
[paste image URL] VHS distortion, signal interference,
scan lines, color bleeding, tracking errors --cref [character URL]4. Name Your Files
sunglasses-kitten-open.jpg
sunglasses-kitten-closed.jpg
sunglasses-kitten-wink.jpg
sunglasses-kitten-surprise.jpg
sunglasses-kitten-glitch1.jpg
sunglasses-kitten-glitch2.jpg5. Run sardonic
sardonic --frames "sunglasses-kitten*.jpg" \
--duration 60 --glitch 2 --rotation 20The magic: Random selection + random rotation + random timing = talking head
Why This Works
The human brain is incredible at pattern recognition. When we see:
- An image rotating slightly
- Changing at irregular intervals
- Different mouth positions
- All synced roughly to audio rhythm
We perceive: "This character is talking!"
Add scanlines and glitch? "This character is from 1985!"
It's the same principle that made Max Headroom work. The chaos approximates life.
Technical Details
How Rotation Works
Uses ImageMagick to rotate each frame around its center:
convert input.jpg \
-resize 320x320^ \
-gravity center \
-extent 320x320 \
-background none \
-rotate 12.5 \
-extent 320x320 \
output.pngThe double extent ensures the rotated image stays centered and doesn't get cropped.
How Glitches Work
Scanlines (Level 1+):
geq='r=r(X,Y):g=g(X,Y):b=b(X,Y):a=if(not(mod(Y\,3)),255,a(X,Y))'Makes every 3rd line more opaque.
Noise (Level 2+):
noise=alls=10:allf=t+uTemporal noise that varies per frame.
Chromatic Aberration (Level 3):
split, offset red/green channels, overlaySimulates lens distortion.
How Overlay Works
ffmpeg's overlay filter with alpha channel:
[1:v]format=yuva420p[overlay];
[0:v][overlay]overlay=x:y:shortest=1Positions calculated dynamically based on video size.
Creative Tips
Syncing to Narration
For best results:
- Generate sardonic to match narration length
- Edit your narration with clear phrases
- The random cuts will naturally sync to speech patterns
- Works surprisingly well without explicit timing!
Multiple Characters
# Generate separate headrooms for different speakers
sardonic --frames "host*.jpg" -o host.mp4
sardonic --frames "guest*.jpg" -o guest.mp4
# Overlay both (requires manual ffmpeg)
ffmpeg -i video.mp4 -i host.mp4 -i guest.mp4 \
-filter_complex "[0:v][1:v]overlay=W-w-20:H-h-20[tmp];[tmp][2:v]overlay=20:H-h-20" \
output.mp4Match Your Aesthetic
Corporate/Professional:
--glitch 0- No effects--rotation 5- Subtle movement- Clean frames, neutral expressions
Retro/Fun:
--glitch 2- Medium chaos--rotation 15- Default energy- Neon colors, sunglasses
Experimental/Art:
--glitch 3- Maximum chaos--rotation 45- Wild rotation- Include glitch frames, distorted expressions
Frame Count Sweet Spot
- 2-3 frames: Minimal, clean cuts
- 4-6 frames: Good variety (recommended)
- 8-12 frames: Lots of expression
- 15+ frames: May become too chaotic
More frames = more unique moments = more apparent "talking"
Examples
Example 1: Educational Video
# Generate professor cat expressions
# sunglasses-prof-explaining.jpg
# sunglasses-prof-thinking.jpg
# sunglasses-prof-pointing.jpg
sardonic \
--frames "sunglasses-prof*.jpg" \
--duration 180 \
--glitch 1 \
--rotation 10 \
--overlay lecture.mp4 \
--position top-right \
-o lecture-with-prof.mp4Example 2: Podcast
# Generate multiple emotion frames
sardonic \
--frames "podcast-cat*.jpg" \
--duration 3600 \
--glitch 2 \
--rotation 15 \
--size 400 \
-o podcast.mp4Example 3: Live Stream Overlay
# Create looping headroom for OBS
sardonic \
--frames "stream-cat*.jpg" \
--duration 600 \
--glitch 1 \
--size 256 \
-o stream.mp4
# Import into OBS as video source
# Set to loop
# Position in corner
# Done!Advanced: Custom Effects
The code is designed to be hackable. Want more effects?
Add Video Distortion
In buildGlitchFilter():
// VHS tracking errors
filters.push('hue=H=2*PI*t');
// RGB shift
filters.push('split[a][b],[a]lutrgb=g=0:b=0[r],[b]lutrgb=r=0:b=0[g]');Add Frame Stuttering
In generateSequence():
// Repeat same frame 2-3 times (Max Headroom stutter)
if (Math.random() > 0.7) {
sequence.push({
...previousFrame,
duration: 0.1
});
}Add Random Zoom
In createRotatedFrame():
const zoom = 100 + (Math.random() * 20 - 10); // 90-110%
args.push('-resize', `${zoom}%`);The Max Headroom Legacy
Max Headroom (1985-1987) wasn't just a character. It was a statement about media, reality, and the future.
What made Max special:
- Artificial but relatable
- Glitchy but coherent
- Chaotic but intentional
- Funny but unsettling
sardonic captures that spirit in miniature. A small chaos agent in your video corner, reminding viewers that media is constructed, reality is malleable, and cats in sunglasses are timeless.
Troubleshooting
"No frames found"
- Check your
--framespattern - Make sure files exist in current directory
- Try absolute path:
--dir /full/path/to/frames
"ImageMagick failed"
- Install ImageMagick:
apt install imagemagickorbrew install imagemagick - Check image files aren't corrupted
"Overlay looks wrong"
- Ensure input video and headroom have compatible durations
- Try different positions:
--position bottom-left - Adjust margin:
--margin 50
"Not glitchy enough"
- Increase glitch level:
--glitch 3 - Increase rotation:
--rotation 30 - Add more distorted frames to your image set
"Too glitchy"
- Decrease glitch level:
--glitch 0or--glitch 1 - Decrease rotation:
--rotation 5 - Use cleaner source images
