Real YouTube download & MP3 conversion with yt-dlp
- Integrate yt-dlp.exe for real YouTube audio download/conversion - Serve actual MP3 files from wwwroot/downloads via API and static files - Report real-time progress from yt-dlp to frontend - Enhance DownloadController: file serving, metadata, deletion endpoints - Update VideoController to track and return real file info/URLs - Enable static file serving in Program.cs; update API info/logging - Update Blazor frontend to use real download URLs and remove old JS logic - Add README_UPDATED.md with new workflow and troubleshooting - Improve error handling, logging, and file cleanup throughout backend - Update .gitignore for downloads and yt-dlp.exe
This commit is contained in:
@@ -22,6 +22,7 @@ public class VideoController : ControllerBase
|
||||
public DownloadProgress Progress { get; set; } = new();
|
||||
public ProcessVideoResponse? Result { get; set; }
|
||||
public YouTubeVideoDetails? VideoDetails { get; set; } // Add video details to job
|
||||
public string? DownloadedFileName { get; set; } // Store actual downloaded file name
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
@@ -165,7 +166,7 @@ public class VideoController : ControllerBase
|
||||
{
|
||||
_logger.LogInformation("Processing video for job {JobId}", jobId);
|
||||
|
||||
// Step 1: Fetch video details (NEW FIRST STEP)
|
||||
// Step 1: Fetch video details
|
||||
job.Progress.Status = "Processing";
|
||||
job.Progress.Message = "Fetching video details...";
|
||||
job.Progress.PercentageComplete = 5;
|
||||
@@ -186,41 +187,48 @@ public class VideoController : ControllerBase
|
||||
|
||||
_logger.LogInformation("Job {JobId}: Video details retrieved - Title: {Title}", jobId, videoDetails.Title);
|
||||
|
||||
// Continue with remaining processing steps
|
||||
var remainingSteps = new[]
|
||||
{
|
||||
("Analyzing audio stream", 30),
|
||||
("Downloading audio data", 60),
|
||||
("Converting to MP3", 85),
|
||||
("Finalizing", 100)
|
||||
};
|
||||
// Step 2: Process video with yt-dlp
|
||||
job.Progress.Message = "Starting download and conversion...";
|
||||
job.Progress.PercentageComplete = 20;
|
||||
|
||||
var downloadedFileName = await _videoService.ProcessVideoWithProgressAsync(
|
||||
job.Request.Url!,
|
||||
job.Request.Format ?? "mp3",
|
||||
(percentage, message) =>
|
||||
{
|
||||
// Update progress from yt-dlp
|
||||
job.Progress.PercentageComplete = Math.Max(20, percentage); // Ensure minimum 20%
|
||||
job.Progress.Message = message;
|
||||
_logger.LogDebug("Job {JobId}: Progress {Percentage}% - {Message}", jobId, percentage, message);
|
||||
}
|
||||
);
|
||||
|
||||
foreach (var (message, percentage) in remainingSteps)
|
||||
if (string.IsNullOrEmpty(downloadedFileName))
|
||||
{
|
||||
job.Progress.Message = message;
|
||||
job.Progress.PercentageComplete = percentage;
|
||||
|
||||
_logger.LogInformation("Job {JobId}: {Message} ({Percentage}%)", jobId, message, percentage);
|
||||
|
||||
// Simulate processing time
|
||||
await Task.Delay(Random.Shared.Next(1000, 3000));
|
||||
throw new Exception("Processing completed but no file was generated");
|
||||
}
|
||||
|
||||
// Store the downloaded file name
|
||||
job.DownloadedFileName = downloadedFileName;
|
||||
|
||||
// Complete processing
|
||||
job.Progress.Status = "Completed";
|
||||
job.Progress.Message = "Processing completed successfully";
|
||||
job.Progress.PercentageComplete = 100;
|
||||
|
||||
// Create download URL for the actual file
|
||||
var downloadUrl = $"/downloads/{Uri.EscapeDataString(downloadedFileName)}";
|
||||
|
||||
job.Result = new ProcessVideoResponse
|
||||
{
|
||||
Success = true,
|
||||
Message = "Video processed successfully",
|
||||
FileName = $"{videoDetails.Title?.Replace(" ", "_") ?? "video"}.{job.Request.Format ?? "mp3"}",
|
||||
DownloadUrl = $"/api/download/{jobId}",
|
||||
FileName = downloadedFileName,
|
||||
DownloadUrl = downloadUrl,
|
||||
VideoDetails = videoDetails
|
||||
};
|
||||
|
||||
_logger.LogInformation("Successfully completed processing for job {JobId}", jobId);
|
||||
_logger.LogInformation("Successfully completed processing for job {JobId}. File: {FileName}", jobId, downloadedFileName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user