Created
December 22, 2016 21:46
-
-
Save JKamsker/fae79a2ba8b2fb06e957bc618671376e to your computer and use it in GitHub Desktop.
Async youtube-dl wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Globalization; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using System.Threading; | |
using System.Threading.Tasks; | |
namespace MediaProviderWorker.Helpers.Youtube | |
{ | |
class usage | |
{ | |
public static void use(string[] args) | |
{ | |
var dat = new YoutubeProvider(args.Length != 0 ? args[0] : "https://www.youtube.com/watch?v=IxuEtL7gxoM"); | |
var dat1 = new YoutubeProvider(args.Length > 1 ? args[1] : "https://www.youtube.com/watch?v=VmUGe8KDdGI"); | |
while (!dat.hasFinished || !dat1.hasFinished) | |
{ | |
WaitHandle.WaitAny(new[] { dat.waiter, dat1.waiter }, -1); | |
// dat.WaitOne(); for one or "WaitHandle.WaitAny(new[] { dat.waiter, dat1.waiter }, -1);" for multible downloads | |
Console.WriteLine("1: {0}%, {1} secs remaining", dat.percentage.ToString("0.0"), dat.eta.TotalSeconds); | |
Console.WriteLine("2: {0}%, {1} secs remaining", dat1.percentage.ToString("0.0"), dat1.eta.TotalSeconds); | |
} | |
File.WriteAllText(dat.saveto + ".log", dat.rawResponse); | |
Console.WriteLine("Finished"); | |
Console.ReadLine(); | |
} | |
} | |
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