Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

Tape MP4 Conversion - Success Report#

Summary#

Successfully implemented and tested MP4 video conversion for aesthetic.computer tapes with ATProto blob uploads.

Problem Solved#

H.264 encoding requires video dimensions divisible by 2. Many tapes have odd-width canvases (e.g., 337x160).

Solution#

Added ffmpeg scale filter: scale=trunc(iw/2)*2:trunc(ih/2)*2

  • Rounds down to nearest even number
  • Preserves aspect ratio
  • Minimal quality impact (1px maximum width/height adjustment)

Test Results#

Date: 2025-01-25 Test Set: 32 anonymous tapes from art.at.aesthetic.computer

Metrics#

  • 100% success rate (32/32 conversions)
  • MP4 sizes: 27.71 KB - 439.04 KB (average ~180 KB)
  • Frame rate: 60 fps (calculated from timing.json)
  • Codec: H.264 with yuv420p pixel format
  • Optimization: faststart flag enabled for web streaming
  • All blobs uploaded to ATProto successfully
  • All MongoDB records updated with rkeys

Sample Conversions#

Tape Code ZIP Size MP4 Size Dimensions
9Yo Unknown 108.89 KB 640x480 (even)
eKZ Unknown 343.71 KB 337x176 → 336x176
3Pt Unknown 27.71 KB Small tape
oSm Unknown 439.04 KB Longest tape

Implementation Details#

ffmpeg Arguments#

-r 60                                      # Frame rate (from timing.json)
-i /tmp/tape-xxx/frame-%05d.png           # Input frames (5-digit padded)
-vf scale=trunc(iw/2)*2:trunc(ih/2)*2     # Ensure even dimensions
-c:v libx264                               # H.264 codec
-pix_fmt yuv420p                           # Compatible pixel format
-movflags +faststart                       # Web streaming optimization
-y output.mp4                              # Overwrite output

Error Handling#

  • Falls back to no blob if conversion fails
  • Record still created with zipUrl and acUrl
  • Cleanup of temp directories guaranteed

Files Modified#

  1. tape-to-mp4.mjs (line 92)

    • Added scale filter to ffmpeg arguments
  2. media-atproto.mjs (lines 167-215)

    • TAPE buildRecord with MP4 conversion
    • Dynamic import of tape-to-mp4.mjs
    • Blob upload logic
  3. sync-atproto.mjs

    • Added --tapes-only flag
    • Anonymous content support

Next Steps#

  1. ✅ Test complete - all 32 anonymous tapes synced
  2. 🔄 Sync Jeffrey's content (~3,000 items)
  3. 🔄 Deploy to production
  4. 🔄 Full sync of 4,201 users

Performance Notes#

  • Conversion time: ~3-5 seconds per tape
  • Batch size: 10 concurrent conversions
  • Total time for 32 tapes: ~2 minutes
  • No rate limiting issues with ATProto blob uploads

Storage Impact#

  • Average MP4 size: ~180 KB
  • 32 tapes: ~5.76 MB total
  • Extrapolated for all users: Estimated 50-100 MB (assuming ~300-500 tapes total)

Conclusion#

MP4 conversion implementation is production-ready