/// <summary> /// Asynchronously retrieve video / playlist information /// </summary> /// <param name="ydl"> /// The client /// </param> /// <param name="cancellationToken"> /// The cancellation token /// </param> /// <returns> /// An object containing the download information /// </returns> internal static async Task <DownloadInfo> GetDownloadInfoAsync(this YoutubeDL ydl, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(ydl.VideoUrl)) { return(null); } List <DownloadInfo> infos = new List <DownloadInfo>(); string rawOutput = null; // Save the original options and set the ones we need string originalOptions = ydl.Options.Serialize(); SetInfoOptions(ydl); // Save the original event delegates and clear the event handler Delegate[] originalDelegates = null; if (ydl.stdOutputEvent != null) { originalDelegates = ydl.stdOutputEvent.GetInvocationList(); ydl.stdOutputEvent = null; } // Local function for easier event handling void ParseInfoJson(object sender, string output) { if (!cancellationToken.IsCancellationRequested) { infos.Add(DownloadInfo.CreateDownloadInfo(output)); } rawOutput = output; } ydl.StandardOutputEvent += ParseInfoJson; // Set up the command PreparationService.SetupPrepare(ydl); // Download the info await DownloadService.DownloadAsync(ydl, cancellationToken); while ((!ydl.process.HasExited || infos.Count == 0) && !cancellationToken.IsCancellationRequested) { await Task.Delay(1); } if (cancellationToken.IsCancellationRequested) { return(null); } // Set the info object ydl.Info = infos.Count > 1 ? new MultiDownloadInfo(infos) : infos[0]; if (ydl.Info == null) { throw new Exception("Error parsing youtube-dl output. Raw Output:\n" + rawOutput); } // Set options back to what they were ydl.Options = Options.Deserialize(originalOptions); // Clear the event handler ydl.stdOutputEvent = null; // Re-subscribe to each event delegate if (originalDelegates != null) { foreach (Delegate del in originalDelegates) { ydl.StandardOutputEvent += (EventHandler <string>)del; } } return(ydl.Info); }
/// <summary> /// Synchronously retrieve video / playlist information /// </summary> /// <param name="ydl"> /// The client /// </param> /// <returns> /// An object containing the download information /// </returns> internal static DownloadInfo GetDownloadInfo(this YoutubeDL ydl) { if (string.IsNullOrWhiteSpace(ydl.VideoUrl)) { return(null); } List <DownloadInfo> infos = new List <DownloadInfo>(); // Save the original options and set the ones we need string originalOptions = ydl.Options.Serialize(); SetInfoOptions(ydl); // Save the original event delegates and clear the event handler Delegate[] originalDelegates = null; if (ydl.stdOutputEvent != null) { originalDelegates = ydl.stdOutputEvent.GetInvocationList(); ydl.stdOutputEvent = null; } // Local function for easier event handling void ParseInfoJson(object sender, string output) { infos.Add(DownloadInfo.CreateDownloadInfo(output)); } ydl.StandardOutputEvent += ParseInfoJson; // Set up the command PreparationService.SetupPrepare(ydl); // Download the info DownloadService.Download(ydl); while (ydl.ProcessRunning || infos.Count == 0) { Thread.Sleep(1); } // Set the info object ydl.Info = infos.Count > 1 ? new MultiDownloadInfo(infos) : infos[0]; // Set options back to what they were ydl.Options = Options.Deserialize(originalOptions); // Clear the event handler ydl.stdOutputEvent = null; // Re-subscribe to each event delegate if (originalDelegates != null) { foreach (Delegate del in originalDelegates) { ydl.StandardOutputEvent += (EventHandler <string>)del; } } return(ydl.Info); }