Added playlist support

This commit is contained in:
2025-05-23 01:34:48 +02:00
parent fd6b3ffdf2
commit b886f0b35d
8 changed files with 320 additions and 113 deletions

61
Download.Designer.cs generated
View File

@ -28,24 +28,26 @@
/// </summary>
private void InitializeComponent()
{
this.lblStatus = new System.Windows.Forms.Label();
this.lblDownload = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.progressBar = new System.Windows.Forms.ProgressBar();
this.pbDownload = new System.Windows.Forms.ProgressBar();
this.pbConvertion = new System.Windows.Forms.ProgressBar();
this.lblConvertion = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// lblStatus
// lblDownload
//
this.lblStatus.AutoSize = true;
this.lblStatus.Location = new System.Drawing.Point(13, 13);
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(139, 25);
this.lblStatus.TabIndex = 0;
this.lblStatus.Text = "Connecting...";
this.lblDownload.AutoSize = true;
this.lblDownload.Location = new System.Drawing.Point(13, 13);
this.lblDownload.Name = "lblDownload";
this.lblDownload.Size = new System.Drawing.Size(139, 25);
this.lblDownload.TabIndex = 0;
this.lblDownload.Text = "Connecting...";
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Abort;
this.btnCancel.Location = new System.Drawing.Point(625, 41);
this.btnCancel.Location = new System.Drawing.Point(899, 127);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(110, 40);
this.btnCancel.TabIndex = 7;
@ -53,21 +55,38 @@
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// progressBar
// pbDownload
//
this.progressBar.Location = new System.Drawing.Point(18, 41);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(601, 40);
this.progressBar.TabIndex = 8;
this.pbDownload.Location = new System.Drawing.Point(18, 41);
this.pbDownload.Name = "pbDownload";
this.pbDownload.Size = new System.Drawing.Size(875, 40);
this.pbDownload.TabIndex = 8;
//
// pbConvertion
//
this.pbConvertion.Location = new System.Drawing.Point(18, 127);
this.pbConvertion.Name = "pbConvertion";
this.pbConvertion.Size = new System.Drawing.Size(875, 40);
this.pbConvertion.TabIndex = 10;
//
// lblConvertion
//
this.lblConvertion.AutoSize = true;
this.lblConvertion.Location = new System.Drawing.Point(13, 99);
this.lblConvertion.Name = "lblConvertion";
this.lblConvertion.Size = new System.Drawing.Size(0, 25);
this.lblConvertion.TabIndex = 9;
//
// Download
//
this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 25F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(747, 102);
this.Controls.Add(this.progressBar);
this.ClientSize = new System.Drawing.Size(1021, 183);
this.Controls.Add(this.pbConvertion);
this.Controls.Add(this.lblConvertion);
this.Controls.Add(this.pbDownload);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.lblStatus);
this.Controls.Add(this.lblDownload);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "Download";
this.Text = "Downloading";
@ -80,8 +99,10 @@
#endregion
private System.Windows.Forms.Label lblStatus;
private System.Windows.Forms.Label lblDownload;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.ProgressBar progressBar;
private System.Windows.Forms.ProgressBar pbDownload;
private System.Windows.Forms.ProgressBar pbConvertion;
private System.Windows.Forms.Label lblConvertion;
}
}

View File

@ -5,6 +5,7 @@ using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.Remoting.Contexts;
using System.Security.AccessControl;
using System.Security.Policy;
@ -25,22 +26,34 @@ namespace ytdlp_gui
InitializeComponent();
}
private void Download_Load(object sender, EventArgs e)
private async void Download_Load(object sender, EventArgs e)
{
process.Start += (_sender, start_event) =>
{
lblStatus.Text = String.Format(
lblDownload.Text = String.Format(
"Connecting to %s...",
start_event.provider
);
};
process.Error += (_sender, error_event) =>
{
MessageBox.Show(this, error_event.error, "yt-dlp error", MessageBoxButtons.OK, MessageBoxIcon.Error );
this.Close();
};
process.Progress += (_sender, prog_event) =>
{
int progress = (int)(prog_event.progress * 100 + 0.5);
this.Text = "Downloading - " + progress.ToString() + "%";
lblStatus.Text = prog_event.file;
progressBar.Value = progress;
this.Text = String.Format(
"Downloading {0}/{1} {2}% - {3}",
prog_event.playlist_current,
prog_event.playlist_total,
progress,
prog_event.file
);
lblDownload.Text = this.Text;
pbDownload.Value = progress;
};
process.Finished += (_sender, finish_event) =>
@ -66,33 +79,41 @@ namespace ytdlp_gui
{
System.IO.File.Move(filePath, newFilePath);
System.IO.File.SetLastWriteTime(newFilePath, DateTime.Now);
this.Close();
}
else
{
newFile = Path.ChangeExtension(newFile, convert_to);
newFilePath = Path.ChangeExtension(newFilePath, convert_to);
convertion = (new FFmpeg()).Convert(filePath, newFilePath);
FFmpegProcess convertion = (new FFmpeg()).Convert(filePath, newFilePath);
convertion.Progress += (_ffmpeg, progress_event) =>
convertion.Progress += (_ffmpeg, prog_event) =>
{
int progress = (int)(progress_event.progress * 100 + 0.5);
this.Text = "Converting - " + progress.ToString() + "%";
lblStatus.Text = "Converting to " + convert_to;
progressBar.Value = progress;
int progress = (int)(prog_event.progress * 100 + 0.5);
// this.Text = "Converting - " + progress.ToString() + "%";
lblConvertion.Text = String.Format(
"Converting {0}/{1} {2}% - {3}",
convertion_current,
convertion_total,
progress,
newFile
);
pbConvertion.Value = progress;
};
convertion.Finished += (_ffmpeg, _ffmpeg_e) =>
{
System.IO.File.Delete(filePath);
this.Close();
triggerConvertionQueue();
};
convertion.Run().ContinueWith(t => { MessageBox.Show(t.Exception.ToString(), "Error"); }, TaskContinuationOptions.OnlyOnFaulted); ;
convertion_queue.Enqueue(convertion);
convertion_total += 1;
triggerConvertionQueue();
}
};
// Can run in background :)
process.Run().ContinueWith(t => { MessageBox.Show(t.Exception.ToString(), "Error"); }, TaskContinuationOptions.OnlyOnFaulted);
_ = await process.Run();
}
private void btnCancel_Click(object sender, EventArgs e)
@ -102,12 +123,30 @@ namespace ytdlp_gui
private void Download_FormClosing(object sender, FormClosingEventArgs e)
{
if (convertion != null)
convertion.Cancel();
process.Cancel();
foreach (FFmpegProcess conversion in convertion_queue)
conversion.Cancel();
}
protected async void triggerConvertionQueue()
{
if (converting)
return;
if (convertion_queue.Count() == 0)
return;
converting = true;
convertion_current += 1;
await convertion_queue.Dequeue().Run();
converting = false;
}
protected readonly YTdlpProcess process;
protected FFmpegProcess convertion;
protected int convertion_current = 0;
protected int convertion_total = 0;
protected Queue<FFmpegProcess> convertion_queue = new Queue<FFmpegProcess>();
private bool converting = false;
protected readonly string workdir;
protected readonly string convert_to;
}

View File

@ -29,9 +29,6 @@ namespace ytdlp_gui
this.output_file = output_file;
ci = (CultureInfo)CultureInfo.CurrentCulture.Clone();
ci.NumberFormat.CurrencyDecimalSeparator = ".";
this.header_regex = new Regex(@"Duration: (\d+):(\d+):(\d+)\.(\d+)");
this.progress_regex = new Regex(@"time=(\d+):(\d+):(\d+)\.(\d+)");
}
~FFmpegProcess()
@ -39,7 +36,7 @@ namespace ytdlp_gui
Cancel();
}
public async Task<string> Run()
public async Task Run()
{
if (File.Exists(output_file))
System.IO.File.Delete(output_file);
@ -71,37 +68,33 @@ namespace ytdlp_gui
+ int.Parse(groups[2].Value) * 60
+ int.Parse(groups[3].Value);
Progress?.Invoke(this, new FFmpegProgressEventArgs((float)progress / duration));
Progress?.Invoke(this, new FFmpegProgressEventArgs(Math.Min((float)progress / duration, 1)));
}
}
if (stop)
return;
process.WaitForExit();
process.Close();
Finished?.Invoke(this, new EventArgs());
return null;
return;
}
public void Cancel()
{
bool finished = true;
try // to kill the process before deleting the file
{
finished = process.HasExited;
stop = true;
if (!process.HasExited)
process.Kill();
process.WaitForExit();
process.Close();
}
catch { }
// if (!finished && File.Exists(output_file))
// System.IO.File.Delete(output_file);
process.WaitForExit();
}
private readonly Process process;
private readonly string output_file;
private readonly CultureInfo ci;
private readonly Regex header_regex;
private readonly Regex progress_regex;
private readonly Regex header_regex = new Regex(@"Duration: (\d+):(\d+):(\d+)\.(\d+)");
private readonly Regex progress_regex = new Regex(@"time=(\d+):(\d+):(\d+)\.(\d+)");
private bool stop = false;
public event EventHandler<FFmpegProgressEventArgs> Progress;
public event EventHandler Finished;
}
@ -124,7 +117,7 @@ namespace ytdlp_gui
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
// process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
return new FFmpegProcess(process, to);

57
Main.Designer.cs generated
View File

@ -31,9 +31,9 @@
this.label1 = new System.Windows.Forms.Label();
this.textUrl = new System.Windows.Forms.TextBox();
this.checkDownloadPlaylist = new System.Windows.Forms.CheckBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.groupPlaylist = new System.Windows.Forms.GroupBox();
this.textPlaylistFolder = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.lblPlaylistFolder = new System.Windows.Forms.Label();
this.checkPlaylistFolder = new System.Windows.Forms.CheckBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label3 = new System.Windows.Forms.Label();
@ -42,7 +42,7 @@
this.btnDownload = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.checkAudioOnly = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
this.groupPlaylist.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
@ -65,42 +65,44 @@
// checkDownloadPlaylist
//
this.checkDownloadPlaylist.AutoSize = true;
this.checkDownloadPlaylist.Enabled = false;
this.checkDownloadPlaylist.Location = new System.Drawing.Point(25, 178);
this.checkDownloadPlaylist.Name = "checkDownloadPlaylist";
this.checkDownloadPlaylist.Size = new System.Drawing.Size(212, 29);
this.checkDownloadPlaylist.TabIndex = 2;
this.checkDownloadPlaylist.Text = "Download playlist";
this.checkDownloadPlaylist.UseVisualStyleBackColor = true;
this.checkDownloadPlaylist.CheckedChanged += new System.EventHandler(this.checkDownloadPlaylist_CheckedChanged);
//
// groupBox1
// groupPlaylist
//
this.groupBox1.Controls.Add(this.textPlaylistFolder);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.checkPlaylistFolder);
this.groupBox1.Enabled = false;
this.groupBox1.Location = new System.Drawing.Point(18, 58);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(373, 108);
this.groupBox1.TabIndex = 3;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Playlist";
this.groupPlaylist.Controls.Add(this.textPlaylistFolder);
this.groupPlaylist.Controls.Add(this.lblPlaylistFolder);
this.groupPlaylist.Controls.Add(this.checkPlaylistFolder);
this.groupPlaylist.Enabled = false;
this.groupPlaylist.Location = new System.Drawing.Point(18, 58);
this.groupPlaylist.Name = "groupPlaylist";
this.groupPlaylist.Size = new System.Drawing.Size(373, 108);
this.groupPlaylist.TabIndex = 3;
this.groupPlaylist.TabStop = false;
this.groupPlaylist.Text = "Playlist";
//
// textPlaylistFolder
//
this.textPlaylistFolder.Enabled = false;
this.textPlaylistFolder.Location = new System.Drawing.Point(94, 60);
this.textPlaylistFolder.Name = "textPlaylistFolder";
this.textPlaylistFolder.Size = new System.Drawing.Size(273, 31);
this.textPlaylistFolder.TabIndex = 2;
//
// label2
// lblPlaylistFolder
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(7, 67);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(80, 25);
this.label2.TabIndex = 1;
this.label2.Text = "Name: ";
this.lblPlaylistFolder.AutoSize = true;
this.lblPlaylistFolder.Enabled = false;
this.lblPlaylistFolder.Location = new System.Drawing.Point(7, 67);
this.lblPlaylistFolder.Name = "lblPlaylistFolder";
this.lblPlaylistFolder.Size = new System.Drawing.Size(80, 25);
this.lblPlaylistFolder.TabIndex = 1;
this.lblPlaylistFolder.Text = "Name: ";
//
// checkPlaylistFolder
//
@ -111,6 +113,7 @@
this.checkPlaylistFolder.TabIndex = 0;
this.checkPlaylistFolder.Text = "Save to folder";
this.checkPlaylistFolder.UseVisualStyleBackColor = true;
this.checkPlaylistFolder.CheckedChanged += new System.EventHandler(this.checkPlaylistFolder_CheckedChanged);
//
// groupBox2
//
@ -201,7 +204,7 @@
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnDownload);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.groupPlaylist);
this.Controls.Add(this.checkDownloadPlaylist);
this.Controls.Add(this.textUrl);
this.Controls.Add(this.label1);
@ -211,8 +214,8 @@
this.Name = "Main";
this.Text = "Youtube Downloader";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Main_FormClosing);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupPlaylist.ResumeLayout(false);
this.groupPlaylist.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.ResumeLayout(false);
@ -225,10 +228,10 @@
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textUrl;
private System.Windows.Forms.CheckBox checkDownloadPlaylist;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupPlaylist;
private System.Windows.Forms.CheckBox checkPlaylistFolder;
private System.Windows.Forms.TextBox textPlaylistFolder;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label lblPlaylistFolder;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.ComboBox comboConvertFormat;
private System.Windows.Forms.CheckBox checkConvert;

21
Main.cs
View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -30,10 +31,17 @@ namespace ytdlp_gui
string user = Environment.GetEnvironmentVariable("USERNAME");
string workdir = @"C:\Users\" + user + @"\Downloads\";
if (checkDownloadPlaylist.Checked && checkPlaylistFolder.Checked)
{
workdir = Path.Combine(workdir, textPlaylistFolder.Text);
if (!Directory.Exists(workdir))
System.IO.Directory.CreateDirectory(workdir);
}
YTdlpProcess process = ytdlp.Download(
textUrl.Text,
checkAudioOnly.Checked,
false,
checkDownloadPlaylist.Checked,
workdir
);
Download download = new Download(
@ -75,6 +83,17 @@ namespace ytdlp_gui
comboConvertFormat.Enabled = checkConvert.Checked;
}
private void checkDownloadPlaylist_CheckedChanged(object sender, EventArgs e)
{
groupPlaylist.Enabled = checkDownloadPlaylist.Checked;
}
private void checkPlaylistFolder_CheckedChanged(object sender, EventArgs e)
{
textPlaylistFolder.Enabled = checkPlaylistFolder.Checked;
lblPlaylistFolder.Enabled = checkPlaylistFolder.Checked;
}
protected List<Download> downloads;
protected YTdlp ytdlp;
}

43
ProcessUtil.cs Normal file
View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
namespace ytdlp_gui
{
internal static class ProcessUtil
{
/// https://stackoverflow.com/questions/5901679/kill-process-tree-programmatically-in-c-sharp#answer-10402906
/// <summary>
/// Kill a process, and all of its children, grandchildren, etc.
/// </summary>
/// <param name="pid">Process ID.</param>
public static void KillProcessAndChildren(int pid)
{
// Cannot close 'system idle process'.
if (pid == 0)
{
return;
}
ManagementObjectSearcher searcher = new ManagementObjectSearcher
("Select * From Win32_Process Where ParentProcessID=" + pid);
ManagementObjectCollection moc = searcher.Get();
foreach (ManagementObject mo in moc)
{
KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
}
try
{
Process proc = Process.GetProcessById(pid);
proc.Kill();
}
catch (ArgumentException)
{
// Process already exited.
}
}
}
}

141
YTdlp.cs
View File

@ -3,9 +3,12 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Deployment.Application;
using System.Diagnostics;
using System.Drawing.Printing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@ -24,18 +27,31 @@ namespace ytdlp_gui
public class YTdlpProgressEventArgs : EventArgs
{
public YTdlpProgressEventArgs(string provider, string action, string file, float progress)
{
public YTdlpProgressEventArgs(
string provider,
string action,
string file,
float progress,
string playlist,
int playlist_current,
int playlist_total
){
this.provider = provider;
this.action = action;
this.file = file;
this.progress = progress;
this.playlist = playlist;
this.playlist_current = playlist_current;
this.playlist_total = playlist_total;
}
public readonly string provider;
public readonly string action;
public readonly string file;
public readonly float progress;
public readonly string playlist;
public readonly int playlist_current;
public readonly int playlist_total;
}
public class YTdlpErrorEventArgs : EventArgs
@ -74,21 +90,20 @@ namespace ytdlp_gui
ci.NumberFormat.CurrencyDecimalSeparator = ".";
files = new List<string>();
this.already_downloaded_regex = new Regex(@"\[download\]\s+(.+) has already been downloaded");
this.download_regex = new Regex(@"([0-9.]+)%\s+of\s+([0-9.]+)(\w+)\s+at\s+([0-9.]+)(\w+\/\w+)\sETA\s(\d+:\d+)");
this.download_finish_regex = new Regex(@"([0-9.]+)%\s+of\s+([0-9.]+)(\w+)\s+in\s+(\d+:\d+:\d+)\s+at\s+([0-9.]+)(\w+\/\w+)");
this.merge_regex = new Regex(@"Merging formats into ""(.+)""");
}
public async Task<string> Run()
public async Task<string[]> Run()
{
process.Start();
string line = null;
string stdout = "";
int playlist_last = playlist_current;
string line;
bool first = true;
while ((line = await process.StandardOutput.ReadLineAsync()) != null)
{
Console.WriteLine(line);
stdout += line;
if (first)
{
provider = (new Regex(@"\w+")).Match(line).Value;
@ -96,12 +111,14 @@ namespace ytdlp_gui
}
line = line.Trim();
/*
Match match = this.already_downloaded_regex.Match(line);
if (match.Success)
{
file = match.Groups[1].Value;
break;
}
*/
if (line.StartsWith("[info] "))
ProgInfo(line.Substring("[info] ".Length).TrimStart());
@ -111,15 +128,47 @@ namespace ytdlp_gui
if (line.StartsWith("[Merger] "))
ProgMerger(line.Substring("[Merger] ".Length).TrimStart());
if (line.StartsWith("[youtube:tab] "))
ProgYoutube(line.Substring("[youtube:tab] ".Length).TrimStart());
if (playlist_last != playlist_current)
{
playlist_last = playlist_current;
if (File != null)
Finished?.Invoke(this, new YTdlpFinishedEventArgs(provider, File, files.ToArray()));
}
}
process.WaitForExit();
process.Close();
Finished?.Invoke(this, new YTdlpFinishedEventArgs(provider, File, files.ToArray()));
if (stop)
return new string[0];
return null;
process.WaitForExit();
if (process.ExitCode == 0)
{
if (File != null)
Finished?.Invoke(this, new YTdlpFinishedEventArgs(provider, File, files.ToArray()));
}
else
Error?.Invoke(this, new YTdlpErrorEventArgs(provider, stdout));
return files.ToArray();
}
public void Cancel()
{
stop = true;
if (!process.HasExited) try
{
ProcessUtil.KillProcessAndChildren(process.Id);
}
catch (Exception) { /* We tried ¯\_(ツ)_/¯ */ }
process.WaitForExit();
}
[DllImport("kernel32.dll")]
private static extern int GetParentProcessId(int processId);
protected void ProgInfo(string line)
{
}
@ -147,7 +196,10 @@ namespace ytdlp_gui
provider,
"download",
File,
progress
progress,
playlist,
playlist_current,
playlist_total
);
Progress?.Invoke(this, args);
}
@ -156,21 +208,32 @@ namespace ytdlp_gui
if (match.Success)
{
GroupCollection groups = match.Groups;
float progress = ParseFloat( groups[1].Value ) / 100 ;
float total = ParseFloat( groups[2].Value ) ;
string total_unit = groups[3].Value ;
string total_time = groups[4].Value ;
float speed = ParseFloat( groups[5].Value ) ;
string speed_unit = groups[6].Value ;
float progress = ParseFloat(groups[1].Value) / 100;
float total = ParseFloat(groups[2].Value);
string total_unit = groups[3].Value;
string total_time = groups[4].Value;
float speed = ParseFloat(groups[5].Value);
string speed_unit = groups[6].Value;
YTdlpProgressEventArgs args = new YTdlpProgressEventArgs(
provider,
"download",
File,
progress
progress,
playlist,
playlist_current,
playlist_total
);
Progress?.Invoke(this, args);
}
match = download_playlist_item_regex.Match(line);
if (match.Success)
{
GroupCollection groups = match.Groups;
playlist_current = int.Parse(groups[1].Value);
playlist_total = int.Parse(groups[2].Value);
}
}
protected void ProgMerger(string line)
@ -186,12 +249,30 @@ namespace ytdlp_gui
provider,
"merge",
file,
1
1,
playlist,
playlist_current,
playlist_total
);
Progress?.Invoke(this, args);
}
}
protected void ProgYoutube(string line)
{
Match match;
match = download_playlist_regex.Match(line);
if (match.Success)
{
playlist = match.Groups[1].Value;
// How much we downloading
playlist_total = int.Parse(match.Groups[2].Value);
// How much there is
// playlist_total = int.Parse(match.Groups[3].Value);
}
}
private float ParseFloat(string str)
{
return float.Parse(str, NumberStyles.Any, ci);
@ -199,11 +280,17 @@ namespace ytdlp_gui
private readonly Process process;
private readonly CultureInfo ci;
private readonly Regex already_downloaded_regex;
private readonly Regex download_regex;
private readonly Regex download_finish_regex;
private readonly Regex merge_regex;
private readonly Regex download_playlist_regex = new Regex(@"Playlist (.+):\s+Downloading\s+(\d+)\s+items\s+of\s+(\d+)");
private readonly Regex download_playlist_item_regex = new Regex(@"Downloading\s+item\s(\d+)\s+of\s+(\d+)");
private readonly Regex already_downloaded_regex = new Regex(@"\[download\]\s+(.+) has already been downloaded");
private readonly Regex download_regex = new Regex(@"([0-9.]+)%\s+of\s*~?\s+([0-9.]+)(\w+)\s+at\s+([0-9.]+)(\w+\/\w+)\sETA\s(\d+:\d+)");
private readonly Regex download_finish_regex = new Regex(@"([0-9.]+)%\s+of\s+([0-9.]+)(\w+)\s+in\s+(\d+:\d+:\d+)\s+at\s+([0-9.]+)(\w+\/\w+)");
private readonly Regex merge_regex = new Regex(@"Merging formats into ""(.+)""");
private string provider;
private string playlist;
private int playlist_current = 1;
private int playlist_total = 1;
private bool stop = false;
private string File {
get { return file; }
set { file = value; if (!files.Contains(value)) files.Add(value); }
@ -237,7 +324,7 @@ namespace ytdlp_gui
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
// process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = workdir;
return new YTdlpProcess(process);

View File

@ -35,6 +35,7 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -60,6 +61,7 @@
<DependentUpon>Main.cs</DependentUpon>
</Compile>
<Compile Include="App.cs" />
<Compile Include="ProcessUtil.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="YTdlp.cs" />