Monorepo for Aesthetic.Computer
aesthetic.computer
Tape Viewer Implementation#
Overview#
Created a new tape.mjs piece that loads and plays back tape recordings from their ZIP files, similar to how painting.mjs works for paintings.
Usage#
Loading a Tape#
tape %code
Where code is the short tape code (e.g., abc, xyz, etc.)
Examples:
tape %abc- Load and view tape with code "abc"tape %abc:show- Lightbox mode (no UI)- Visit
aesthetic.computer/#%abc- Direct URL access
Visual Signifier#
The % symbol was chosen as a visual signifier for tapes because:
- Resembles a film reel / movie symbol
- Distinct from
#(used for paintings) - Indicates video/motion content
Features Implemented#
Core Functionality#
- ✅ Load tape metadata from MongoDB via
/api/get-tape?code=XXX - ✅ Download and parse ZIP files from S3 (user or guest buckets)
- ✅ Extract all frames, timing data, and metadata
- ✅ Display frames with proper scaling and centering
- ✅ Audio playback from
soundtrack.wav(Web Audio API) - ✅ Frame-accurate timing using timing.json
Playback Controls#
- ✅ Play/Pause button
- ✅ Keyboard controls:
Space- Toggle play/pauseArrow Left- Previous frame (when paused)Arrow Right- Next frame (when paused)Home- Jump to first frameEnd- Jump to last frame
- ✅ Frame counter display
- ✅ Time display (current/total duration)
- ✅ Playback indicator (▶/⏸)
UI Features#
- ✅ Download button - downloads original ZIP file
- ✅ Loading state with animated ellipsis
- ✅ Error handling with user-friendly messages
- ✅ Show mode (
:showsuffix) for lightbox/embed view - ✅ Responsive frame scaling to fit screen
Audio Integration#
- ✅ Automatic detection of
soundtrack.wavin ZIP - ✅ Web Audio API integration
- ✅ Frame-synced audio playback
- ✅ Audio offset calculation for mid-tape playback
- ✅ Audio stops on pause/end
Technical Details#
File Structure#
The tape viewer expects ZIPs with this structure:
tape-code.zip
├── frame-00000.png
├── frame-00001.png
├── ...
├── timing.json (frame durations)
├── metadata.json (piece name, duration, etc.)
└── soundtrack.wav (optional audio)
API Endpoints Used#
GET /api/get-tape?code=XXX- Fetch tape metadata from MongoDB- Returns:
{ slug, code, when, bucket, user, mp4Status, nuked }
- Returns:
ZIP Loading#
- Uses JSZip library (loaded dynamically from CDN)
- Downloads from appropriate S3 bucket (user vs guest)
- Extracts frames as ImageBitmaps for efficient rendering
- Parses JSON files for timing and metadata
Timing System#
- Uses
timing.jsonfor frame-accurate playback - Each entry:
{ frame: number, duration: number (ms) } - Advances frames based on actual duration
- Fallback to 30fps if timing data missing
Audio Synchronization#
- Decodes WAV file using Web Audio API
- Calculates playback offset based on current frame
- Syncs audio start time with frame progression
- Handles audio ending gracefully
Testing#
To test the tape viewer:
-
Record a tape (if you haven't already):
tape 3 notepatThis will generate a tape code (e.g.,
#abc) -
View the tape:
tape %abc -
Try different modes:
tape %abc:show (lightbox mode) -
Direct URL: Navigate to
https://aesthetic.computer/#%abc
Code Location#
- Piece file:
/workspaces/aesthetic-computer/system/public/aesthetic.computer/disks/tape.mjs - Backend API:
/workspaces/aesthetic-computer/system/netlify/functions/get-tape.mjs(already exists)
Comparison to painting.mjs#
Similarities#
- Short code system (
#codefor paintings,%codefor tapes) - MongoDB lookup via API
- S3 file download
- Loading states and error handling
- Show mode support
- Download button
Differences#
- File type: ZIP (tapes) vs PNG (paintings)
- Playback: Animated sequence vs static image
- Audio: Includes soundtrack vs silent
- Controls: Play/pause/scrub vs static view
- Timing: Frame-based animation vs instant load
Future Enhancements#
Planned Features#
- Scrubbing timeline/progress bar
- Speed controls (0.5x, 1x, 2x)
- Loop toggle
- Frame-by-frame download (export individual frames)
- Share button (copy link)
- Fullscreen mode
- Volume control
- Keyboard shortcuts help overlay
Integration Ideas#
- Gallery view of user's tapes
- Related tapes suggestions
- Tape annotations/comments
- MP4 fallback (when conversion service ready)
- Social sharing previews
Notes#
Browser Compatibility#
- Requires browsers with:
createImageBitmapAPI (modern browsers)- Web Audio API (for audio playback)
- Fetch API (for downloading)
Performance#
- All frames loaded into memory for smooth playback
- May use significant RAM for long tapes (100+ frames)
- Consider lazy loading for very long recordings
Audio Autoplay#
- Web Audio context may be suspended by browser autoplay policies
- First interaction (play button click) resumes audio context
- Audio starts synced with current frame position
Integration with Existing System#
The tape viewer integrates seamlessly with the existing ecosystem:
- Recording:
tape X piececreates tape → generates short code - Upload: ZIP uploaded to S3, record created in MongoDB
- Viewing:
tape %codeloads and plays back recording - Sharing: Short codes make sharing easy (
%abcvs full S3 URL)
This completes the tape workflow from creation to playback! 🎬📼