# Architecture Documentation ## Overview Downlink is a Next.js application that provides a web interface for downloading YouTube videos and audio files. The application uses server-side processing with yt-dlp and provides a modern, responsive UI built with shadcn/ui. ## System Architecture ``` ┌─────────────┐ │ Browser │ │ (Client) │ └──────┬──────┘ │ HTTP Requests ▼ ┌─────────────────────────────────┐ │ Next.js App Router │ │ ┌───────────────────────────┐ │ │ │ UI Components (React) │ │ │ └───────────────────────────┘ │ │ ┌───────────────────────────┐ │ │ │ API Routes │ │ │ │ - /api/info │ │ │ │ - /api/download │ │ │ └───────────┬───────────────┘ │ └──────────────┼──────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ Business Logic Layer │ │ ┌───────────────────────────┐ │ │ │ lib/youtube.ts │ │ │ │ - getVideoInfo() │ │ │ │ - downloadVideo() │ │ │ └───────────┬───────────────┘ │ └──────────────┼──────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ External Tools │ │ ┌───────────────────────────┐ │ │ │ yt-dlp (Python) │ │ │ │ - Video download │ │ │ │ - Format conversion │ │ │ └───────────────────────────┘ │ │ ┌───────────────────────────┐ │ │ │ ffmpeg (via yt-dlp) │ │ │ │ - Audio transcoding │ │ │ └───────────────────────────┘ │ └─────────────────────────────────┘ ``` ## Component Structure ### Frontend Components #### `app/page.tsx` Main page component containing: - URL input field - Video information display - Format selection (video/audio) - Download button - Error handling and success states #### UI Components (`components/ui/`) shadcn/ui components: - `button.tsx`: Button component - `input.tsx`: Input field component - `card.tsx`: Card container component - `label.tsx`: Form label component - `select.tsx`: Dropdown select component ### Backend Components #### API Routes **`app/api/info/route.ts`** - Handles POST requests for video information - Validates YouTube URL - Calls `getVideoInfo()` from `lib/youtube.ts` - Returns video metadata **`app/api/download/route.ts`** - Handles POST requests for downloads - Validates request body (url, format, formatType) - Calls `downloadVideo()` from `lib/youtube.ts` - Returns download URL and file information #### Business Logic **`lib/youtube.ts`** Core functionality: - `getVideoInfo(url)`: Fetches video metadata using yt-dlp - `downloadVideo(request)`: Downloads and processes video/audio - `ensureDirectories()`: Creates necessary directories - `sanitizeFilename()`: Sanitizes filenames for safe storage **`lib/types.ts`** Centralized TypeScript type definitions: - `VideoFormat`, `AudioFormat`: Format type unions - `DownloadRequest`, `DownloadResponse`: API request/response types - `VideoInfo`, `FormatOption`: Video metadata types **`lib/utils.ts`** Utility functions: - `cn()`: Tailwind class name merger - `isValidYouTubeUrl()`: URL validation - `extractYouTubeId()`: Extract video ID from URL ## Data Flow ### Video Information Flow 1. User enters YouTube URL and clicks "Get Info" 2. Frontend sends POST request to `/api/info` 3. API route validates URL and calls `getVideoInfo()` 4. `getVideoInfo()` executes `yt-dlp --dump-json` 5. JSON response is parsed and formatted 6. Video info (title, thumbnail, duration) returned to frontend 7. Frontend displays video information ### Download Flow 1. User selects format and clicks "Download" 2. Frontend sends POST request to `/api/download` 3. API route validates request and calls `downloadVideo()` 4. `downloadVideo()`: - Generates unique file ID - Constructs yt-dlp command based on format - Executes download command - Moves file to `/public/downloads/` - Returns download URL 5. Frontend receives download URL 6. User can download file via provided link ## File Storage ### Directory Structure ``` Downlink/ ├── downloads/ # Temporary storage (gitignored) │ └── [fileId].[ext] # Downloaded files before processing ├── public/ │ └── downloads/ # Public downloads (gitignored) │ └── [fileId].[ext] # Final files served to users ``` ### File Naming - Format: `[timestamp]-[randomId].[extension]` - Example: `1234567890-abc123.mp4` - Prevents filename conflicts - Timestamp enables cleanup of old files ## Dependencies ### Runtime Dependencies - **next**: Next.js framework - **react**: React library - **react-dom**: React DOM rendering - **lucide-react**: Icon library - **@radix-ui/***: UI component primitives - **tailwind-merge**: Tailwind class merging - **clsx**: Conditional class names ### System Dependencies - **yt-dlp**: Python-based YouTube downloader - **ffmpeg**: Media conversion tool (used by yt-dlp) ### Development Dependencies - **typescript**: TypeScript compiler - **tailwindcss**: CSS framework - **eslint**: Code linting ## Security Considerations ### Current Implementation - URL validation to ensure YouTube URLs only - Filename sanitization to prevent directory traversal - Server-side processing (no client-side download logic) ### Recommended Enhancements - Rate limiting to prevent abuse - File size limits - User authentication/authorization - Download quotas per user/IP - Automatic file cleanup - CORS configuration - Input sanitization for all user inputs ## Performance Considerations ### Current Limitations - Synchronous file operations (could block for large files) - No progress tracking during downloads - Files stored in memory during copy operations - No caching of video information ### Optimization Opportunities - Stream large files instead of loading into memory - Implement download progress tracking - Cache video metadata - Use background jobs for long-running downloads - Implement CDN for file serving - Add database for download history ## Deployment Considerations ### Requirements - Node.js 18+ runtime - Python 3.6+ (for yt-dlp) - ffmpeg installed on server - Sufficient disk space for downloads - Network access to YouTube ### Environment Variables Currently none required, but consider: - `MAX_FILE_SIZE`: Maximum file size limit - `CLEANUP_INTERVAL`: File cleanup schedule - `ALLOWED_DOMAINS`: Allowed video platforms - `STORAGE_PATH`: Custom storage location ### Scaling Considerations - Stateless API design (can scale horizontally) - File storage should be shared (S3, etc.) for multi-instance deployments - Consider message queue for download processing - Implement caching layer for video metadata