From 74446bb88c5d4d77b15044b4132c07eabc171680 Mon Sep 17 00:00:00 2001 From: manusoft Date: Sun, 12 Apr 2026 19:36:27 +0400 Subject: [PATCH 1/3] Cleanup code. --- src/Ytdlp.NET/Core/DownloadRunner.cs | 141 ++------------------------- 1 file changed, 9 insertions(+), 132 deletions(-) diff --git a/src/Ytdlp.NET/Core/DownloadRunner.cs b/src/Ytdlp.NET/Core/DownloadRunner.cs index 682cd6b..3f26d7f 100644 --- a/src/Ytdlp.NET/Core/DownloadRunner.cs +++ b/src/Ytdlp.NET/Core/DownloadRunner.cs @@ -23,15 +23,12 @@ public DownloadRunner(ProcessFactory factory, ProgressParser parser, ILogger log public async Task RunAsync(string arguments, CancellationToken ct, bool tuneProcess = true) { using var process = _factory.Create(arguments); - int completed = 0; void Complete(bool success, string message) { if (Interlocked.Exchange(ref completed, 1) == 0) - { OnCommandCompleted?.Invoke(this, new CommandCompletedEventArgs(success, message)); - } } try @@ -57,15 +54,11 @@ void Complete(bool success, string message) while (!ct.IsCancellationRequested) { var readTask = reader.ReadLineAsync(); - var completedTask = await Task.WhenAny(readTask, Task.Delay(Timeout.Infinite, ct)); - - if (completedTask != readTask) - break; + if (completedTask != readTask) break; var line = await readTask; - if (line == null) - break; + if (line == null) break; try { @@ -95,15 +88,11 @@ void Complete(bool success, string message) while (!ct.IsCancellationRequested) { var readTask = reader.ReadLineAsync(); - var completedTask = await Task.WhenAny(readTask, Task.Delay(Timeout.Infinite, ct)); - - if (completedTask != readTask) - break; + if (completedTask != readTask) break; var line = await readTask; - if (line == null) - break; + if (line == null) break; OnError?.Invoke(this, line); _logger.Log(LogType.Error, line); @@ -117,9 +106,7 @@ void Complete(bool success, string message) { if (!process.HasExited) { - _logger.Log(LogType.Info, - "Cancellation requested β†’ killing process tree"); - + _logger.Log(LogType.Info, "Cancellation requested β†’ killing process tree"); ProcessFactory.SafeKill(process, _logger); } }); @@ -136,12 +123,9 @@ void Complete(bool success, string message) ProcessFactory.SafeKill(process); var success = process.ExitCode == 0 && !ct.IsCancellationRequested; - - var message = success - ? "Completed successfully" - : ct.IsCancellationRequested - ? "Cancelled by user" - : $"Failed with exit code {process.ExitCode}"; + var message = success ? "Completed successfully" + : ct.IsCancellationRequested ? "Cancelled by user" + : $"Failed with exit code {process.ExitCode}"; Complete(success, message); } @@ -158,112 +142,5 @@ void Complete(bool success, string message) throw new YtdlpException(msg, ex); } - } - - // Working code - old method - //public async Task RunAsync(string arguments, CancellationToken ct, bool tuneProcess = true) - //{ - // using var process = _factory.Create(arguments); - - // int completed = 0; - - // void Complete(bool success, string message) - // { - // if (Interlocked.Exchange(ref completed, 1) == 0) - // { - // OnCommandCompleted?.Invoke(this, new CommandCompletedEventArgs(success, message)); - // } - // } - - // try - // { - // var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - - // // βœ… Attach BEFORE Start (fix race condition) - // process.Exited += (_, _) => tcs.TrySetResult(true); - - // process.OutputDataReceived += (s, e) => - // { - // if (e.Data == null) return; - - // try - // { - // _progressParser.ParseProgress(e.Data); - // OnProgress?.Invoke(this, e.Data); - // } - // catch (Exception ex) - // { - // _logger.Log(LogType.Error, $"Parse error: {ex.Message}"); - // } - // }; - - // process.ErrorDataReceived += (s, e) => - // { - // if (e.Data == null) return; - - // OnErrorMessage?.Invoke(this, e.Data); - // _logger.Log(LogType.Error, e.Data); - // }; - - // if (!process.Start()) - // throw new YtdlpException("Failed to start yt-dlp process."); - - // if (tuneProcess) - // ProcessFactory.Tune(process); - - // // βœ… Start reading AFTER handlers - // process.BeginOutputReadLine(); - // process.BeginErrorReadLine(); - - // // πŸ”₯ Cancellation - // using var registration = ct.Register(() => - // { - // if (!process.HasExited) - // { - // _logger.Log(LogType.Info, "Cancellation requested β†’ killing process tree"); - // ProcessFactory.SafeKill(process, _logger); - // } - // }); - - // // Wait for exit OR cancellation - // await Task.WhenAny(tcs.Task, Task.Delay(Timeout.Infinite, ct)); - - // // Ensure process is dead - // if (!process.HasExited) - // ProcessFactory.SafeKill(process); - - // try - // { - // await process.WaitForExitAsync(ct); - // } - // catch (OperationCanceledException) - // { - // if (!process.HasExited) - // ProcessFactory.SafeKill(process); - // } - - // var success = process.ExitCode == 0 && !ct.IsCancellationRequested; - - // var message = success - // ? "Completed successfully" - // : ct.IsCancellationRequested - // ? "Cancelled by user" - // : $"Failed with exit code {process.ExitCode}"; - - // Complete(success, message); - // } - // catch (OperationCanceledException) - // { - // Complete(false, "Cancelled by user"); - // throw; - // } - // catch (Exception ex) - // { - // var msg = $"Error executing yt-dlp: {ex.Message}"; - // _logger.Log(LogType.Error, msg); - // OnErrorMessage?.Invoke(this, msg); - - // throw new YtdlpException(msg, ex); - // } - //} + } } \ No newline at end of file From 72e46d388da020a77adf6ec3aa98aa2eacd80be6 Mon Sep 17 00:00:00 2001 From: manusoft Date: Sun, 3 May 2026 14:04:49 +0400 Subject: [PATCH 2/3] Update runners, models, parser. --- src/Ytdlp.NET/Core/DownloadRunner.cs | 4 ++-- src/Ytdlp.NET/Core/ProbeRunner.cs | 4 ---- src/Ytdlp.NET/Models/MetadataLight.cs | 14 +++++++------- src/Ytdlp.NET/Parsing/ProgressParser.cs | 3 +-- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/Ytdlp.NET/Core/DownloadRunner.cs b/src/Ytdlp.NET/Core/DownloadRunner.cs index 3f26d7f..56b3de2 100644 --- a/src/Ytdlp.NET/Core/DownloadRunner.cs +++ b/src/Ytdlp.NET/Core/DownloadRunner.cs @@ -20,9 +20,9 @@ public DownloadRunner(ProcessFactory factory, ProgressParser parser, ILogger log _logger = logger; } - public async Task RunAsync(string arguments, CancellationToken ct, bool tuneProcess = true) + public async Task RunAsync(string args, CancellationToken ct, bool tuneProcess = true) { - using var process = _factory.Create(arguments); + using var process = _factory.Create(args); int completed = 0; void Complete(bool success, string message) diff --git a/src/Ytdlp.NET/Core/ProbeRunner.cs b/src/Ytdlp.NET/Core/ProbeRunner.cs index 50bbde4..259fcb0 100644 --- a/src/Ytdlp.NET/Core/ProbeRunner.cs +++ b/src/Ytdlp.NET/Core/ProbeRunner.cs @@ -7,7 +7,6 @@ public sealed class ProbeRunner private readonly ProcessFactory _factory; private readonly ILogger _logger; - public event EventHandler? OnOutput; // optional: for live output if needed public event EventHandler? OnErrorMessage; public event EventHandler? OnCommandCompleted; @@ -19,9 +18,6 @@ public ProbeRunner(ProcessFactory factory, ILogger logger) public async Task RunAsync(string args, CancellationToken ct = default, bool tuneProcess = true, int bufferKb = 256) { - if (string.IsNullOrWhiteSpace(args)) - throw new ArgumentException("Arguments cannot be empty", nameof(args)); - // Reasonable buffer: 256 KB default (good for large JSON), min 64 KB if (bufferKb < 64) bufferKb = 64; int bufferSize = bufferKb * 1024; diff --git a/src/Ytdlp.NET/Models/MetadataLight.cs b/src/Ytdlp.NET/Models/MetadataLight.cs index 2555666..eb574d7 100644 --- a/src/Ytdlp.NET/Models/MetadataLight.cs +++ b/src/Ytdlp.NET/Models/MetadataLight.cs @@ -9,37 +9,37 @@ public class MetadataLight /// /// Video ID (e.g. "Xt50Sodg7sA") /// - public string? Id { get; init; } + public string? Id { get; set; } /// /// Video title (supports Unicode / emoji / special characters) /// - public string? Title { get; init; } + public string? Title { get; set; } /// /// Video duration in seconds (null if not available) /// - public double? Duration { get; init; } + public double? Duration { get; set; } /// /// Primary thumbnail URL /// - public string? Thumbnail { get; init; } + public string? Thumbnail { get; set; } /// /// View count (null if not available) /// - public long? ViewCount { get; init; } + public long? ViewCount { get; set; } /// /// Approximate file size of best format (bytes, null if not available) /// - public long? FileSize { get; init; } + public long? FileSize { get; set; } /// /// Video description (first ~500 characters, supports Unicode) /// - public string? Description { get; init; } + public string? Description { get; set; } /// /// Convenience: Duration as TimeSpan diff --git a/src/Ytdlp.NET/Parsing/ProgressParser.cs b/src/Ytdlp.NET/Parsing/ProgressParser.cs index 1ffbb3a..ad040c2 100644 --- a/src/Ytdlp.NET/Parsing/ProgressParser.cs +++ b/src/Ytdlp.NET/Parsing/ProgressParser.cs @@ -1,5 +1,4 @@ -ο»Ώusing System.Diagnostics; -using System.Text.RegularExpressions; +ο»Ώusing System.Text.RegularExpressions; namespace ManuHub.Ytdlp.NET; From f2a580ebb24fc5055fa9fadc5f501eb7767b61d9 Mon Sep 17 00:00:00 2001 From: manusoft Date: Sun, 3 May 2026 14:35:10 +0400 Subject: [PATCH 3/3] Minor update in codes. --- src/Ytdlp.NET.Console/Program.cs | 24 ++++++++++++------------ src/Ytdlp.NET/Parsing/ProgressParser.cs | 22 ++++++++++------------ src/Ytdlp.NET/Ytdlp.NET.csproj | 2 +- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/Ytdlp.NET.Console/Program.cs b/src/Ytdlp.NET.Console/Program.cs index 35f719e..6060754 100644 --- a/src/Ytdlp.NET.Console/Program.cs +++ b/src/Ytdlp.NET.Console/Program.cs @@ -20,20 +20,20 @@ private static async Task Main(string[] args) .WithFFmpegLocation("tools"); // Run all demos/tests sequentially - await TestGetVersionAsync(baseYtdlp); - await TestUpdateAsync(baseYtdlp); + //await TestGetVersionAsync(baseYtdlp); + //await TestUpdateAsync(baseYtdlp); - await TestGetFormatsAsync(baseYtdlp); - await TestGetMetadataAsync(baseYtdlp); - await TestGetLiteMetadataAsync(baseYtdlp); - await TestGetTitleAsync(baseYtdlp); + //await TestGetFormatsAsync(baseYtdlp); + //await TestGetMetadataAsync(baseYtdlp); + //await TestGetLiteMetadataAsync(baseYtdlp); + //await TestGetTitleAsync(baseYtdlp); await TestDownloadVideoAsync(baseYtdlp); - await TestDownloadAudioAsync(baseYtdlp); - await TestBatchDownloadAsync(baseYtdlp); - await TestSponsorBlockAsync(baseYtdlp); - await TestConcurrentFragmentsAsync(baseYtdlp); - await TestCancellationAsync(baseYtdlp); + //await TestDownloadAudioAsync(baseYtdlp); + //await TestBatchDownloadAsync(baseYtdlp); + //await TestSponsorBlockAsync(baseYtdlp); + //await TestConcurrentFragmentsAsync(baseYtdlp); + //await TestCancellationAsync(baseYtdlp); var lists = await baseYtdlp.ExtractorsAsync(); @@ -164,7 +164,7 @@ private static async Task TestDownloadVideoAsync(Ytdlp ytdlpBase) var ytdlp = ytdlpBase .WithFormat("ba/b") - .WithExtractAudio(AudioFormat.Mp3) + //.WithExtractAudio(AudioFormat.Mp3) .WithConcurrentFragments(8) .WithHomeFolder("./downloads") .WithTempFolder("./downloads/temp") diff --git a/src/Ytdlp.NET/Parsing/ProgressParser.cs b/src/Ytdlp.NET/Parsing/ProgressParser.cs index ad040c2..8950e6f 100644 --- a/src/Ytdlp.NET/Parsing/ProgressParser.cs +++ b/src/Ytdlp.NET/Parsing/ProgressParser.cs @@ -15,6 +15,15 @@ public sealed class ProgressParser private int _postProcessStepCount; private int _deleteCount; + // ───────────── Events (unchanged) ───────────── + #region Events + public event EventHandler? OnProgressMessage; + public event EventHandler? OnProgressDownload; + public event EventHandler? OnCompleteDownload; + public event EventHandler? OnPostProcessingStart; + public event EventHandler? OnPostProcessingComplete; + #endregion + public ProgressParser(ILogger? logger = null) { _logger = logger ?? new DefaultLogger(); @@ -56,8 +65,6 @@ public void ParseProgress(string? output) if (string.IsNullOrWhiteSpace(output)) return; - //OnOutputMessage?.Invoke(this, output.TrimEnd()); - foreach (var (regex, handler) in _regexHandlers) { var match = regex.Match(output); @@ -283,14 +290,5 @@ private void LogAndNotifyComplete(string message) _logger.Log(LogType.Info, message); OnCompleteDownload?.Invoke(this, message); } - #endregion - - // ───────────── Events (unchanged) ───────────── - #region Events - public event EventHandler? OnProgressMessage; - public event EventHandler? OnProgressDownload; - public event EventHandler? OnCompleteDownload; - public event EventHandler? OnPostProcessingStart; - public event EventHandler? OnPostProcessingComplete; - #endregion + #endregion } \ No newline at end of file diff --git a/src/Ytdlp.NET/Ytdlp.NET.csproj b/src/Ytdlp.NET/Ytdlp.NET.csproj index a6db933..385a6a9 100644 --- a/src/Ytdlp.NET/Ytdlp.NET.csproj +++ b/src/Ytdlp.NET/Ytdlp.NET.csproj @@ -7,7 +7,7 @@ Ytdlp.NET Ytdlp.NET ManuHub.Ytdlp.NET - 3.0.3 + 3.0.4 ManuHub Manojbabu A .NET wrapper for yt-dlp with advanced features like concurrent downloads, SponsorBlock, and improved format parsing Β© 2025-2026 ManuHub. Allrights researved