Monorepo for Aesthetic.Computer
aesthetic.computer
Tape Video Processing Setup#
Overview#
Tapes are converted from ZIP (frames + audio) to MP4 using Netlify Background Functions.
Duration Limit#
- Maximum tape duration: 30 seconds
- Client should check
metadata.totalDurationbefore allowing POST - Server validates and returns error if exceeded
Architecture#
Upload Flow#
- Client uploads ZIP to DigitalOcean Spaces
- Client POSTs to
/api/track-tapewith metadata - Server validates duration (max 30s)
- Server creates MongoDB record
- Server invokes background function (fire-and-forget)
- Client receives response immediately
Background Processing#
- Background function runs (up to 15 minutes)
- Downloads ZIP from Spaces
- Converts to MP4 using ffmpeg
- Uploads MP4 back to Spaces
- Syncs to ATProto (if user has account)
- Updates MongoDB with status
Installation#
cd system
npm install @ffmpeg-installer/ffmpeg
Configuration#
netlify.toml#
Background function is configured with:
- External modules:
@aws-sdk/client-s3,@atproto/api,adm-zip,@ffmpeg-installer/ffmpeg - Included backend files
- Required environment variables
Environment Variables#
ART_KEY/DO_SPACES_KEY- DigitalOcean Spaces access keyART_SECRET/DO_SPACES_SECRET- DigitalOcean Spaces secretMONGODB_CONNECTION_STRING- MongoDB connectionPDS_URL- ATProto PDS URL
Client-Side Duration Check#
Add to tape upload UI:
// Before showing "Post to ATProto" button
const MAX_DURATION = 30; // seconds
const duration = tapeMetadata.totalDuration;
if (duration > MAX_DURATION) {
// Hide Post button or show warning
console.log(`Tape too long: ${duration}s (max ${MAX_DURATION}s)`);
return;
}
// Show Post button
Retry Failed Conversions#
If background function fails, tapes can be reprocessed:
cd system/backend
node sync-atproto.mjs live --tapes-only --anonymous-only
Monitoring#
Check tape conversion status in MongoDB:
mp4Status: "pending" | "processing" | "complete" | "failed"mp4StartedAt: When conversion startedmp4CompletedAt: When conversion completedmp4Error: Error message if failedmp4: URL to MP4 fileatproto.rkey: ATProto record key (if synced)