Conversation
- Add migration 006_proxy_workflow.sql: extend media_files with proxy metadata, create media-proxies/exports buckets - Implement server-side proxy generation (lib/media/proxy.ts) with automatic transcoding to 720p - Replace browser export with Supabase-backed FFmpeg pipeline (app/api/render/route.ts, lib/export/server.ts) - Add Node.js FFmpeg wrapper (lib/ffmpeg/node.ts) using fluent-ffmpeg - Update media actions to trigger proxy generation and prefer proxy URLs for playback - Update EditorClient to use new server-side export API - Add dependencies: fluent-ffmpeg, @ffmpeg-installer/ffmpeg, @types/fluent-ffmpeg Tests: - npm run type-check ✓ Next steps: - Backfill proxies for existing media files - Extend renderer to handle layered audio tracks and transitions
|
The latest updates on your projects. Learn more about Vercel for GitHub.
💡 Enable Vercel Agent with $100 free credit for automated AI reviews |
- Add webpack externals configuration for @ffmpeg-installer/ffmpeg and fluent-ffmpeg (next.config.ts:78-101) - Explicitly set nodejs runtime for render API route (app/api/render/route.ts:6) - Prevents Next.js from bundling platform-specific FFmpeg binaries - Resolves MODULE_NOT_FOUND error for @ffmpeg-installer/linux-x64 on Vercel Verification: - npm run type-check ✓ - npm run build ✓ (FFmpeg modules now resolve correctly)
PR Review: Server-side FFmpeg Rendering with Proxy WorkflowSummaryThis PR implements a critical architectural enhancement by moving video rendering from client-side (FFmpeg.wasm) to server-side (Node.js FFmpeg), along with automatic proxy generation for media files. This is a significant improvement for scalability and performance. ✅ Strengths1. Architecture Design
2. Database Design
3. Code Quality
4. User Experience
🔴 Critical Issues1. Security: Potential Resource Exhaustion (HIGH)Location: app/api/render/route.ts:45-51, lib/media/proxy.ts:118 Both operations run synchronously in the API route handler, which can cause:
Recommendation: Queue jobs for background processing instead of awaiting processExportJob synchronously. Return jobId immediately and implement polling endpoint for status updates. 2. Race Condition in Proxy Generation (MEDIUM)Location: lib/media/proxy.ts:149-151 The proxy_status check is not atomic. Two concurrent requests could both pass this check and start duplicate transcoding jobs. Recommendation: Use database-level conditional update with proxy_status = 'pending' in WHERE clause to ensure only one process starts transcoding. 3. Missing Input Validation (MEDIUM)Location: lib/export/server.ts:277 Project names could contain very long strings, causing filesystem issues. Recommend limiting filename length and adding timestamp for uniqueness. 4. Signed URL Expiration Too Short (MEDIUM)Location: lib/export/server.ts:299 1-hour expiration may be insufficient for large exports (2GB) on slow connections. Recommend 24-hour expiration. 🟡 Bugs & Edge Cases5. Missing Cleanup on Concat File (LOW)Location: lib/export/server.ts:128 If concatClips throws between creating the concat file and running ffmpeg, the .txt file won't be cleaned up. Add try/finally block. 6. Proxy Generation Never Retries (MEDIUM)Location: lib/media/proxy.ts:171-178 Once a proxy fails, it stays in failed state forever. Consider adding retry logic or UI button to regenerate. 7. Incomplete Error Context (LOW)Location: lib/export/server.ts:154 Failed job progress updates log to console but continue silently, potentially leaving job status stale. ⚡ Performance Considerations8. FFmpeg Preset Trade-offLocations: lib/export/server.ts:93, lib/media/proxy.ts:51 Using veryfast preset is good for speed, but consider monitoring CPU usage and costs under load. 9. No Concurrency LimitsMissing rate limiting for concurrent exports and proxy generations per user and server-wide. Recommendation: Check active export count before creating new jobs and return 429 if limit exceeded. 10. Memory-Inefficient File Reading (MEDIUM)Location: lib/export/server.ts:283 Reading entire export file into memory before upload could cause OOM errors for large files. Use streaming upload instead. 🧪 Test CoverageMissing Tests:
Recommendation: Add unit tests for processExportJob, generateProxyForMedia, and edge cases. 📝 Minor Issues11. Inconsistent Error MessagesMix of English and Japanese error messages. Recommend standardizing on English for error messages. 12. Missing JSDoc CommentsFunctions like transcodeClip, concatClips lack documentation for parameters. 13. Hardcoded Magic NumbersValues like 1280x720 (proxy dimensions) and audio bitrates should be constants or configurable. 🎯 Recommendations SummaryMust Fix Before Merge:
Should Fix Soon:
Nice to Have:
🎉 Overall AssessmentThis is a well-architected implementation that moves the project in the right direction. The code is clean, well-organized, and follows good practices. However, the synchronous processing in API routes is a critical blocker for production use. Grade: B+ (after fixing critical issues, would be A) Recommendation: Request changes to address critical issues #1, #2, and #10 before merging. Great work on this foundational feature! The migration to server-side rendering will pay dividends in scalability and reliability. 🚀 |
Address PR review feedback with production-ready enhancements: ## Core Improvements ### 1. Async Job Processing (Critical Fix #1) - Add background job queue with concurrency controls (lib/export/queue.ts) - Implement global (default: 2) and per-user (default: 1) export limits - Queue state persists across requests using globalThis - API returns jobId immediately, client polls for status ### 2. Proxy Generation Race Condition Fix (Critical Fix #2) - Implement atomic DB lock with conditional update (lib/media/proxy.ts:169-192) - Use .neq('proxy_status', 'processing') to prevent duplicate jobs - Add retry logic with configurable max attempts (default: 3) - Support force regeneration via options parameter ### 3. Resource Management - Stream-based file uploads to prevent OOM (lib/export/server.ts:335-361) - Proper cleanup of concat files in finally block (lib/export/server.ts:113-126) - Service role client for background operations (lib/supabase/admin.ts) ### 4. Data Validation & Security - Sanitize export filenames with length limit (lib/export/server.ts:157-167) - Extend signed URL expiration to 24h (lib/export/server.ts:15) - Add user_id to export_jobs with RLS policies (007_export_job_enhancements.sql) - Rate limiting: return 429 when limits exceeded ### 5. API Enhancements - New polling endpoint: GET /api/render/[jobId] (app/api/render/[jobId]/route.ts) - POST /api/render now enqueues jobs instead of blocking - Fix Next.js 15 async params compatibility - Export progress tracking with real-time updates ### 6. Configuration - Externalize magic numbers as env variables: - PROXY_TARGET_WIDTH/HEIGHT (default: 1280x720) - PROXY_MAX_ATTEMPTS (default: 3) - EXPORT_MAX_CONCURRENT (default: 2) - EXPORT_MAX_PER_USER (default: 1) - EXPORT_SIGNED_URL_TTL (default: 86400) - EXPORT_AUDIO_BITRATE (default: 192000) - EXPORT_MAX_FILENAME_LENGTH (default: 80) Tests: - npm run type-check ✓ - Supabase migration 007 applied ✓ Migration Status: - 006_proxy_workflow.sql: Applied ✓ - 007_export_job_enhancements.sql: Applied ✓ Next Steps: 1. Set SUPABASE_SERVICE_ROLE_KEY in Vercel environment 2. Test export queue under concurrent load 3. Monitor FFmpeg resource usage in production
Pull Request Review: Server-side FFmpeg Rendering with Proxy WorkflowSummaryThis PR implements a significant architectural improvement by migrating from browser-based export (WebCodecs/FFmpeg.wasm) to server-side FFmpeg rendering with automatic proxy generation. The implementation is comprehensive and addresses critical scalability concerns. Code Quality & Best Practices✅ Strengths
Potential Issues & Recommendations🔴 Critical Issues
🟡 Important Concerns
🟢 Minor Issues
Performance Considerations✅ Optimizations
|
概要
サーバーサイドでのFFmpegレンダリングとプロキシワークフローを実装しました。
主な変更点
1. データベースマイグレーション (006_proxy_workflow.sql)
2. プロキシ生成機能 (lib/media/proxy.ts)
3. サーバーサイドエクスポート (lib/export/server.ts, app/api/render/route.ts)
exportsバケットにアップロード4. Node.js FFmpegラッパー (lib/ffmpeg/node.ts)
5. メディアアクション更新 (app/actions/media.ts)
6. エディタクライアント更新 (app/editor/[projectId]/EditorClient.tsx)
テスト
次のステップ
関連リンク
supabase/migrations/006_proxy_workflow.sql