Adopt GUID-based {jobId}_{title}.ext filename convention for all downloads, ensuring unique, human-readable, and traceable files. Update DownloadController to use precise jobId-based file matching and generate user-friendly download names. Pass jobId to VideoService for consistent naming; add robust title sanitization. Remove fallback file search logic for predictability. Update README and API docs to reflect new format and workflow. Improve logging and error messages for clarity.
9.1 KiB
9.1 KiB
TuneRipper API - yt-dlp Integration
Overview
The TuneRipper API has been updated to use yt-dlp.exe for real YouTube video processing with progress monitoring. Videos are downloaded and converted to MP3 files, stored in the wwwroot/downloads directory with a GUID-based filename format, and served directly through the API.
Setup
Prerequisites
- .NET 10 installed
- yt-dlp.exe placed in
TuneRipper.Api/wwwroot/yt-dlp.exe - ffmpeg available in PATH (required by yt-dlp for audio conversion)
File Structure
TuneRipper.Api/
??? wwwroot/
? ??? yt-dlp.exe # YouTube downloader executable
? ??? downloads/ # Downloaded MP3 files (auto-created)
??? Controllers/
??? Services/
??? Program.cs
Filename Format
Downloaded files use the structured format: {jobId}_{title}.mp3
Format Breakdown:
{jobId}: GUID identifier for the processing job (e.g.,550e8400-e29b-41d4-a716-446655440000)_{title}: Sanitized video title with spaces replaced by underscores.mp3: Audio format extension
Examples:
550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp36ba7b810-9dad-11d1-80b4-00c04fd430c8_How_to_Build_a_Web_API.mp36ba7b811-9dad-11d1-80b4-00c04fd430c8_Amazing_Guitar_Solo_Performance.mp3
Benefits:
- Unique Identification: GUID ensures no filename conflicts
- Direct Job Mapping: Easy file lookup using job ID
- Human Readable: Title part provides context
- System Friendly: Sanitized for filesystem compatibility
Title Sanitization:
- Invalid filename characters are replaced with safe alternatives
- Spaces become underscores (
_) - Special characters:
< > | : * ? " /are replaced with safe chars - Maximum title length: 50 characters
- Fallback to "video" if title cannot be determined
Key Changes
1. Program.cs Updates
- Added
UseStaticFiles()middleware for serving downloaded files - Added
AddHttpClient()for VideoService HTTP requests - Updated logging and endpoint information
2. VideoService Updates
- GUID-Based Filenames: Uses job ID as primary identifier in filename
- Title Sanitization: Converts video titles to safe filenames
- Direct Job Mapping: Files can be found using
{jobId}_*.*pattern - Real yt-dlp Integration: Uses actual yt-dlp.exe with progress monitoring
- Progress Parsing: Real-time progress from yt-dlp output streams
- Error Handling: Comprehensive error handling with 5-minute timeout
3. VideoController Updates
- Passes job ID to VideoService for filename generation
- Uses actual yt-dlp processing instead of simulation
- Stores downloaded file information with GUID-based naming
- Returns real download URLs for completed files
4. DownloadController Updates
- Precise Job Lookup: Uses
{jobId}_*.*pattern for exact file matching - User-Friendly Downloads: Converts filenames back to readable format
- Example:
550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3?Rick Astley Never Gonna Give You Up.mp3 - Reliable File Operations: No ambiguity in file identification
- Serves actual MP3 files from
wwwroot/downloads/ - Proper MIME type detection for audio files
API Workflow
1. Start Processing
POST /api/video/process
Content-Type: application/json
{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"format": "mp3",
"quality": "128"
}
Response:
{
"success": true,
"message": "Processing started",
"fileName": "550e8400-e29b-41d4-a716-446655440000",
"downloadUrl": null,
"videoDetails": null
}
2. Monitor Progress
GET /api/video/status/550e8400-e29b-41d4-a716-446655440000
Response (Processing):
{
"percentageComplete": 45,
"status": "Processing",
"message": "Downloading audio...",
"videoDetails": {
"id": "dQw4w9WgXcQ",
"title": "Rick Astley - Never Gonna Give You Up",
"thumbnailUrl": "https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg"
}
}
3. Get Final Result
GET /api/video/result/550e8400-e29b-41d4-a716-446655440000
Response:
{
"success": true,
"message": "Video processed successfully",
"fileName": "550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3",
"downloadUrl": "/downloads/550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3",
"videoDetails": { ... }
}
4. Download File
GET /api/download/550e8400-e29b-41d4-a716-446655440000
Response: Binary MP3 file download with user-friendly filename
Download Name: Rick Astley Never Gonna Give You Up.mp3
Alternative Static File Access:
GET /downloads/550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3
File Management
Download Directory
- Location:
wwwroot/downloads/ - Naming Pattern:
{jobId}_{title}.ext - Job Lookup: Files found using
Directory.GetFiles(dir, "{jobId}_*.*") - User Download: Converted back to readable names
- Cleanup: Files can be deleted by job ID
File Serving Options
- API Download: Controlled access via
/api/download/{jobId}(recommended)- Uses job ID for secure file lookup
- Returns user-friendly filename
- Proper error handling
- Static Files: Direct access via
/downloads/{actual_filename}- Requires knowing the full filename
- Less secure but faster
- Content-Type: Automatic detection based on file extension
File Operations by Job ID
- Find:
GET /api/download/info/{jobId}- Get file metadata - Download:
GET /api/download/{jobId}- Download the file - Delete:
DELETE /api/download/{jobId}- Remove the file
Progress Monitoring
The VideoService monitors yt-dlp output and translates it to progress updates:
- 5-15%: Fetching video details
- 15-70%: Downloading audio (yt-dlp download progress × 0.7)
- 70-85%: Converting to MP3 (ffmpeg processing)
- 85-95%: Finalizing (cleanup)
- 100%: Complete
Error Handling
Common Errors:
- yt-dlp.exe not found: Ensure yt-dlp.exe is in wwwroot directory
- ffmpeg not available: Install ffmpeg and add to PATH
- Invalid YouTube URL: URL format validation
- Download timeout: 5-minute timeout for processing
- File not found: File may have been cleaned up or job ID invalid
Error Response Format:
{
"success": false,
"message": "Error description",
"fileName": null,
"downloadUrl": null,
"videoDetails": null
}
Configuration
appsettings.json
{
"Logging": {
"LogLevel": {
"TuneRipper.Api.Services.VideoService": "Debug"
}
}
}
yt-dlp Arguments Used:
--extract-audio: Extract audio only--audio-format mp3: Convert to MP3--audio-quality 0: Best quality--no-playlist: Single video only--no-warnings: Clean output--newline: Line-by-line progress--output "{jobId}_{title}.%(ext)s": Uses job ID-based filename
Testing
Manual Testing:
- Start the API:
dotnet run --project TuneRipper.Api - Use API testing tools or the Blazor client
- Check logs for yt-dlp progress
- Verify files in
wwwroot/downloads/with GUID-based naming
Example Test Files:
wwwroot/downloads/
??? 550e8400-e29b-41d4-a716-446655440000_Rick_Astley_Never_Gonna_Give_You_Up.mp3
??? 6ba7b810-9dad-11d1-80b4-00c04fd430c8_How_to_Build_a_Web_API.mp3
??? 6ba7b811-9dad-11d1-80b4-00c04fd430c8_Amazing_Guitar_Solo_Performance.mp3
Health Check:
GET /api/health
Job Listing:
GET /api/video/jobs
Production Considerations
- File Storage: Consider cloud storage for production
- Cleanup Strategy: Implement automatic file cleanup/retention using job completion timestamps
- Security: Job IDs provide secure file access (no directory traversal)
- Performance: Consider queue-based processing for high load
- Monitoring: Add detailed logging and metrics
- Updates: Keep yt-dlp.exe updated for compatibility
- Scalability: GUID-based naming prevents conflicts in distributed systems
Troubleshooting
Common Issues:
- Permissions: Ensure API can write to wwwroot/downloads
- Antivirus: yt-dlp.exe may be flagged by antivirus
- Network: YouTube may block requests from some IPs
- Format Support: Some videos may not support audio extraction
- Long Titles: Titles are truncated to 50 characters for filesystem compatibility
Debug Logging:
Enable debug logging for VideoService to see detailed yt-dlp output:
{
"Logging": {
"LogLevel": {
"TuneRipper.Api.Services.VideoService": "Debug"
}
}
File Lookup Issues:
- Verify job ID matches the GUID format
- Check that files exist with the
{jobId}_prefix - Look at directory contents if files are not found
- Ensure proper case sensitivity on Linux systems
Advantages of GUID-Based Naming:
- Unique: No filename conflicts possible
- Secure: Job ID acts as access token
- Traceable: Direct mapping from API calls to files
- Scalable: Works in distributed environments
- Clean: Easy cleanup by job ID pattern