Skip to content

Commit f225fce

Browse files
authored
Improve yt-dlp progress & post-processing event handling (#25)
- Expand and refine regex patterns for post-processing steps, supporting more yt-dlp processors and modern output formats - Remove legacy/unused regex patterns and handlers for clarity - Add and forward OnPostProcessingStart and OnPostProcessingComplete events for reliable post-processing lifecycle tracking - Improve download completion detection, especially for concurrent fragment downloads - Ensure parser state resets after post-processing completes - Update Program.cs to demonstrate new event usage and add a regex utility - Refactor event subscription/unsubscription to prevent memory leaks - General code cleanup and formatting improvements
1 parent c4f4e6c commit f225fce

4 files changed

Lines changed: 218 additions & 278 deletions

File tree

src/Ytdlp.NET.Console/Program.cs

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
11
using ManuHub.Ytdlp.NET;
22
using System.Diagnostics;
33
using System.Text;
4+
using System.Text.RegularExpressions;
45

56
internal class Program
67
{
78
private static async Task Main(string[] args)
89
{
10+
//Console.WriteLine("=== yt-dlp Output to Regex Converter ===\n");
11+
//Console.WriteLine("Paste a yt-dlp output line below (or type 'exit' to quit):\n");
12+
13+
//while (true)
14+
//{
15+
// Console.Write("> ");
16+
// string? input = Console.ReadLine();
17+
18+
// if (string.IsNullOrWhiteSpace(input) || input.Trim().ToLower() == "exit")
19+
// break;
20+
21+
// string regex = ConvertToRegex(input);
22+
// Console.WriteLine("\nGenerated Regex Pattern:");
23+
// Console.WriteLine(regex);
24+
// Console.WriteLine("\n" + new string('-', 60) + "\n");
25+
//}
26+
27+
928
// Must be the FIRST line — before any Console.WriteLine
1029
Console.OutputEncoding = Encoding.UTF8;
1130
Console.InputEncoding = Encoding.UTF8;
@@ -159,24 +178,38 @@ private static async Task TestGetLiteMetadataAsync(Ytdlp ytdlp)
159178
private static async Task TestDownloadVideoAsync(Ytdlp ytdlpBase)
160179
{
161180
Console.WriteLine("\nTest 6: Downloading a video...");
162-
var url = "https://www.youtube.com/watch?v=89-i4aPOMrc";
181+
var url = "https://www.youtube.com/watch?v=89-i4aPOMrc"; //"https://www.dailymotion.com/video/xa3ron2";
163182

164183
var ytdlp = ytdlpBase
165-
.With720pOrBest()
184+
.WithFormat("95+ba/b")
166185
.WithConcurrentFragments(8)
167186
.WithHomeFolder("./downloads")
168187
.WithTempFolder("./downloads/temp")
169-
.WithOutputTemplate("%(title)s.%(ext)s")
170-
.WithMtime()
171-
.WithTrimFilenames(100);
188+
.WithOutputTemplate("%(title)s.%(ext)s");
189+
//.WithEmbedMetadata()
190+
//.WithEmbedThumbnail()
191+
//.WithRemuxVideo(MediaFormat.Mp4);
172192

173193
// Subscribe to events
194+
ytdlp.OnCommandCompleted += (sender, args) =>
195+
{
196+
if (args.Success)
197+
Console.WriteLine("Process completed successfully.");
198+
else if (args.Message.Contains("cancelled", StringComparison.OrdinalIgnoreCase))
199+
Console.WriteLine("Process was cancelled.");
200+
else
201+
Console.WriteLine($"Process failed: {args.Message}");
202+
};
203+
174204
ytdlp.OnProgressDownload += (sender, args) =>
175205
Console.WriteLine($"Progress: {args.Percent:F2}% - {args.Speed} - ETA {args.ETA} - Size {args.Size}");
176206

177207
ytdlp.OnCompleteDownload += (sender, message) =>
178208
Console.WriteLine($"Download complete: {message}");
179209

210+
ytdlp.OnPostProcessingStart += (sender, message) =>
211+
Console.WriteLine($"Post-processing started: {message}");
212+
180213
ytdlp.OnPostProcessingComplete += (sender, message) =>
181214
Console.WriteLine($"Post-processing done: {message}");
182215

@@ -381,4 +414,33 @@ public static void Complete(string message = "Done!")
381414
}
382415
}
383416

417+
static string ConvertToRegex(string line)
418+
{
419+
if (string.IsNullOrWhiteSpace(line))
420+
return "// Empty line";
421+
422+
// Escape special regex characters
423+
string escaped = Regex.Escape(line);
424+
425+
// Replace variable parts with capture groups
426+
escaped = Regex.Replace(escaped, @"\\\[([^\\\]]+)\\\]", @"\\[(?<processor>$1)\\]"); // [ProcessorName]
427+
escaped = Regex.Replace(escaped, @"(\d+\.\d+)%", @"(?<percent>\d+\.\d+)%");
428+
escaped = Regex.Replace(escaped, @"of\s+~?\s*([\d\.]+\s*[A-Za-z]+B)", @"of ~?(?<size>[\d\.]+\s*[A-Za-z]+B)");
429+
escaped = Regex.Replace(escaped, @"at\s+([\d\.]+\s*[A-Za-z]+/s)", @"at (?<speed>[\d\.]+\s*[A-Za-z]+/s)");
430+
escaped = Regex.Replace(escaped, @"ETA\s+([\d:]+)", @"ETA (?<eta>[\d:]+)");
431+
escaped = Regex.Replace(escaped, @"frag\s*(\d+/\d+)", @"frag (?<frag>\d+/\d+)");
432+
escaped = Regex.Replace(escaped, @"(\d+/\d+)", @"(?<item>\d+)/(?<total>\d+)"); // for playlists etc.
433+
434+
// Common paths and filenames
435+
escaped = Regex.Replace(escaped, @"(""[^""]+"")", @"(?<path>$1)");
436+
escaped = Regex.Replace(escaped, @"'([^']+)'", @"(?<path>'$1')");
437+
438+
// Make it more flexible
439+
escaped = escaped.Replace(@"\[download\]", @"\[download\]");
440+
escaped = escaped.Replace(@"\[info\]", @"\[info\]");
441+
442+
// Add ^ and $ for full line match (recommended for yt-dlp)
443+
return $"^{escaped}$";
444+
}
445+
384446
}

0 commit comments

Comments
 (0)