Monorepo for Aesthetic.Computer
aesthetic.computer
1# Video Capture - Future Work
2
3## Context
4
5Animated GIF/video capture was explored using Cloudflare Workers' Browser Rendering API but proved unsuitable for this infrastructure.
6
7## What Was Tried
8
9### Approach: CDP Screencast API
10- Used Chrome DevTools Protocol `Page.startScreencast`
11- Captured frames as PNG from browser rendering
12- Decoded PNG to RGBA using `fast-png`
13- Encoded to animated GIF using `gifenc`
14
15### Results
16- ✅ **Technical Success**: Full pipeline worked correctly
17- ❌ **Frame Rate**: Only 0.4 FPS (2 frames per 5 seconds)
18- ❌ **Performance**: Too slow for practical video capture
19
20### Investigation
21Tested all available CDP parameters:
22- `format`: PNG, JPEG
23- `quality`: 60-80
24- `maxWidth`/`maxHeight`: Various resolutions
25- `everyNthFrame`: 1 (capture every frame)
26- Navigation timing: Before/after page load
27- Event listener ordering: Confirmed correct
28
29**Conclusion**: CDP screencast in Cloudflare Workers Browser Rendering is heavily throttled, making it unsuitable for video capture.
30
31## Recommended Approach
32
33### Infrastructure: Dedicated Video Server
34
35Similar to the `/at` ATProto PDS deployment, video capture should use a **dedicated Digital Ocean VPS**:
36
37#### Why Digital Ocean VPS?
381. **GPU Support**: For hardware-accelerated encoding (H.264, VP9, etc.)
392. **Persistent Resources**: Can maintain browser instances efficiently
403. **Full Control**: No serverless limitations
414. **Cost Effective**: Pay for what you use, not per request
42
43#### Suggested Stack
44```
45┌─────────────────────────────────────────┐
46│ Cloudflare Worker (grab.aesthetic.com)│
47│ - Screenshot generation (current) │
48│ - Request routing │
49└─────────────────┬───────────────────────┘
50 │
51 ├─> Icon/Preview → Browser Rendering API
52 │
53 └─> Video → Forward to VPS
54 ↓
55┌─────────────────────────────────────────┐
56│ Digital Ocean VPS │
57│ - Headless Chrome/Puppeteer │
58│ - FFmpeg with GPU encoding │
59│ - Frame capture at 30-60 FPS │
60│ - R2/S3 storage for rendered videos │
61└─────────────────────────────────────────┘
62```
63
64#### Implementation Options
65
66**Option A: Real-time Capture**
67```javascript
68// VPS server with Puppeteer
69const browser = await puppeteer.launch({
70 args: ['--enable-gpu-rasterization']
71});
72const page = await browser.newPage();
73
74// Capture frames at 30 FPS
75const frames = [];
76const frameInterval = 1000 / 30;
77for (let i = 0; i < targetFrames; i++) {
78 const screenshot = await page.screenshot({ encoding: 'binary' });
79 frames.push(screenshot);
80 await page.waitForTimeout(frameInterval);
81}
82
83// Encode with FFmpeg
84execSync(`ffmpeg -framerate 30 -i frame_%d.png output.mp4`);
85```
86
87**Option B: Canvas Recording**
88```javascript
89// Client-side in aesthetic.computer pieces
90const canvas = document.querySelector('canvas');
91const stream = canvas.captureStream(30); // 30 FPS
92const recorder = new MediaRecorder(stream);
93
94// Upload chunks to VPS for processing
95recorder.ondataavailable = async (e) => {
96 await fetch('https://video.aesthetic.computer/upload', {
97 method: 'POST',
98 body: e.data
99 });
100};
101```
102
103**Option C: Hybrid Approach**
1041. Cloudflare Worker initiates request
1052. VPS spawns browser and captures frames
1063. Store frames in R2/S3
1074. Return signed URL to client
1085. Async encode video in background
109
110### Cost Estimates
111
112#### Digital Ocean Droplet
113- **Basic**: $12/month (2GB RAM, 1 vCPU) - Light usage
114- **Standard**: $24/month (4GB RAM, 2 vCPUs) - Medium usage
115- **GPU**: ~$200/month (GPU-enabled droplet) - High performance
116
117#### Cloudflare R2 Storage
118- First 10GB free
119- $0.015/GB/month thereafter
120- No egress fees
121
122### Similar Infrastructure
123
124Reference the `/at` PDS deployment:
125- **Location**: `/workspaces/aesthetic-computer/at/`
126- **Setup**: Digital Ocean VPS running ATProto PDS
127- **Deployment**: Automated with `at/deploy.fish`
128- **Model**: Long-running service on dedicated hardware
129
130## Archive
131
132Experimental video code saved in:
133- `ANIMATED-GIF-STATUS.md` - Full investigation results
134- `VIDEO-RECORDING.md` - Original POC documentation (if exists)
135- Git history: Commits leading up to `ea5c6ace-b0da-4891-88ce-d1d9c158e0d5`
136
137## Next Steps
138
139When video capture is needed:
140
1411. **Provision VPS**
142 - Digital Ocean account setup
143 - Choose droplet size based on usage
144 - Consider GPU if budget allows
145
1462. **Install Software**
147 - Node.js + Puppeteer
148 - FFmpeg with GPU support
149 - Nginx for request handling
150
1513. **Implement Capture Service**
152 - API endpoint for capture requests
153 - Frame capture at target FPS
154 - Video encoding pipeline
155 - Upload to R2/CDN
156
1574. **Update grab Worker**
158 - Add `/video/` endpoint routing
159 - Forward to VPS
160 - Handle async responses
161 - Return CDN URLs
162
1635. **Monitor & Scale**
164 - Track encoding times
165 - Monitor CPU/GPU usage
166 - Scale vertically or horizontally as needed
167
168## References
169
170- ATProto PDS: `/workspaces/aesthetic-computer/at/`
171- Cloudflare Browser Rendering: https://developers.cloudflare.com/browser-rendering/
172- Digital Ocean VPS: https://www.digitalocean.com/products/droplets
173- FFmpeg GPU: https://trac.ffmpeg.org/wiki/HWAccelIntro
174- Puppeteer: https://pptr.dev/