Skip to content

Instantly share code, notes, and snippets.

@JKamsker
Created December 29, 2016 21:14
Show Gist options
  • Save JKamsker/077c0bcba996cdb32602895e73237f59 to your computer and use it in GitHub Desktop.
Save JKamsker/077c0bcba996cdb32602895e73237f59 to your computer and use it in GitHub Desktop.
Downloads a youtube video with ytdl asyncronously
class YoutubeProvider
{
public float percentage { get; set; }
public string size { get; set; } = string.Empty;
public string speed { get; set; } = string.Empty;
public TimeSpan eta { get; set; }
public string rawResponse { get; set; } = string.Empty;
public bool hasFinished { get; private set; }
public string saveto { get; private set; } = string.Empty;
public AutoResetEvent waiter { get { return _waiter; } private set { _waiter = value; } }
Thread _workThread;
AutoResetEvent _waiter;
private static Random random = new Random();
static readonly Regex rgxPercentage = new Regex(@"(\d+\.\d+|\d+)%", RegexOptions.Compiled | RegexOptions.ECMAScript);
static readonly Regex rgxSize = new Regex(@"of ((\d+\.\d+|\d+).*?) at", RegexOptions.Compiled | RegexOptions.ECMAScript);
static readonly Regex rgxSpeed = new Regex(@"at[ ]+((\d+\.\d+|\d+).*?\/s)", RegexOptions.Compiled | RegexOptions.ECMAScript);
static readonly Regex rgxETA = new Regex(@"ETA[ ]+((\d+\:\d+))", RegexOptions.Compiled | RegexOptions.ECMAScript);
private static string RandomString(int length) { return new string(Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", length).Select(s => s[random.Next(s.Length)]).ToArray()); }
public YoutubeProvider(string uri)
{
eta = TimeSpan.FromSeconds(0);
_waiter = new AutoResetEvent(false);
hasFinished = false;
_workThread = new Thread(() =>
{
try
{
string tmp = dlVid(uri);
lock (rawResponse) { rawResponse = tmp; }
}
catch (Exception ex)
{ Console.WriteLine(ex.Message); }
hasFinished = true;
_waiter.Set();
});
_workThread.Start();
}
public void WaitOne()
{
_waiter.WaitOne();
}
void parseDat(string input)
{
try { percentage = Convert.ToSingle(rgxPercentage.Match(input).Groups[1].Value); } catch { }
lock (size) { try { size = rgxSize.Match(input).Groups[1].Value.Replace(".", ","); } catch { } }
lock (speed) { try { speed = rgxSpeed.Match(input).Groups[1].Value; } catch { } }
try { eta = TimeSpan.ParseExact(rgxETA.Match(input).Groups[1].Value, @"mm\:ss", CultureInfo.InvariantCulture); } catch { }
if (_waiter != null)
_waiter.Set();
}
private string dlVid(string uri)
{
List<string> outPutLog = new List<string>();
lock (saveto)
{
while (true)
{
saveto = RandomString(10);
if (!File.Exists(saveto + ".mp4") &&
!File.Exists(saveto + ".mp3") &&
!File.Exists(saveto + ".webm"))
{
break;
}
Thread.SpinWait(5);
}
}
string strCommand = string.Format(Settings.ytDLarguments, saveto, uri);
DataReceivedEventHandler strHand = new DataReceivedEventHandler((sender, e) =>
{
string strMessage = e.Data;
if (strMessage != null && strMessage.Length > 0)
{
outPutLog.Add(strMessage);
parseDat(strMessage);
}
});
Process processFfmpeg = new Process()
{
EnableRaisingEvents = true,
StartInfo = new ProcessStartInfo()
{
Arguments = strCommand,
FileName = Settings.youtubeDLPath,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
processFfmpeg.ErrorDataReceived += strHand;
processFfmpeg.OutputDataReceived += strHand;
processFfmpeg.Start();
processFfmpeg.BeginOutputReadLine();
processFfmpeg.BeginErrorReadLine();
processFfmpeg.WaitForExit();
return string.Join("\n", outPutLog);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment