initial commit

This commit is contained in:
2025-12-21 11:43:22 -06:00
parent 1f7eb01afb
commit d28de69bcb
28 changed files with 4067 additions and 108 deletions

223
docs/architecture.md Normal file
View File

@@ -0,0 +1,223 @@
# 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