private IEnumerator DownloadVideo() { downloading = true; IncrementDownloadCount(); if (!updated) { yield return(new WaitUntil(() => updated)); } VideoDownload download = videoQueue.Peek(); VideoData video = download.video; // Plugin.logger.Debug($"Starting Download with {video.title}"); if (video.downloadState == DownloadState.Cancelled || download.downloadAttempts > MaxRetries) { // skip videoQueue.Dequeue(); if (videoQueue.Count > 0) { // Plugin.logger.Debug($"Starting Next Download"); // Start next download DownloadVideo(); } else { // Plugin.logger.Debug($"Done Download"); // queue empty downloading = false; yield break; } } Plugin.logger.Info("Downloading: " + video.title); IEnumerator countdown = Countdown(download); StopCoroutine(countdown); video.downloadState = DownloadState.Downloading; downloadProgress?.Invoke(video); download.Update(); ydl = MakeYoutubeProcessAndReturnIt(video); Plugin.logger.Info($"yt command: \"{ydl.StartInfo.FileName}\" {ydl.StartInfo.Arguments}"); ydl.Start(); // Hook up our output to console ydl.BeginOutputReadLine(); ydl.BeginErrorReadLine(); int logCount = 0; ydl.OutputDataReceived += (sender, e) => { if (e.Data != null) { Regex rx = new Regex(@"(\d*).\d%+"); Match match = rx.Match(e.Data); if (match.Success) { video.downloadProgress = Single.Parse(match.Value.Substring(0, match.Value.Length - 1)) / 100; downloadProgress?.Invoke(video); download.Update(); if (video.downloadState == DownloadState.Cancelled) { DownloadCancelled((Process)sender, video); } } if (++logCount % 10 == 0 || video.downloadProgress > .95) { Plugin.logger.Info(e.Data); } } }; ydl.ErrorDataReceived += (sender, e) => { if (e.Data.Length < 3) { return; } Plugin.logger.Error(e.Data); //TODO: check these errors are problems - re-download or skip file when an error occurs //video.downloadState = DownloadState.Cancelled; downloadProgress?.Invoke(video); download.Update(); if (video.downloadState == DownloadState.Cancelled || e.Data.Contains("Unable to extract video data")) { DownloadCancelled((Process)sender, video); } }; ydl.Exited += (sender, e) => { StopCoroutine(countdown); if (video.downloadState == DownloadState.Cancelled) { Plugin.logger.Info("Cancelled"); VideoLoader.DeleteVideo(video); } else { // video.downloadState = DownloadState.Downloaded; video.UpdateDownloadState(); VideoLoader.SaveVideoToDisk(video); StartCoroutine(VerifyDownload(video)); } videoQueue.Dequeue(); if (videoQueue.Count > 0) { // Start next download // Plugin.logger.Debug("Starting Next Download"); DownloadVideo(); } else { // queue empty downloading = false; } try { ydl?.Dispose(); } catch { } DecrementDownloadCount(); }; }
//Must Call using StartCoroutine private IEnumerator DownloadVideo(VideoData video, bool logProgress = true) { Plugin.logger.Info($"Starting Download with {video.title}"); IncrementDownloadCount(); if (!updated) { yield return(new WaitUntil(() => updated)); } //Plugin.logger.Debug("Update Finished"); if (video.downloadState == DownloadState.Cancelled) { // Plugin.logger.Debug("Download Cancelled"); yield return(null); } else { Plugin.logger.Info("Downloading: " + video.title); video.downloadState = DownloadState.Downloading; // Plugin.logger.Debug("Set State"); downloadProgress?.Invoke(video); // Plugin.logger.Debug("Invoked"); Process localDownloader = MakeYoutubeProcessAndReturnIt(video); Plugin.logger.Info( $"yt command: \"{localDownloader.StartInfo.FileName}\" {localDownloader.StartInfo.Arguments}"); var countdown = Countdown(localDownloader, new TimeSpan(0, 1, 0)); // var outputCount = 0; var timer = new Timer(250); timer.Elapsed += (sender, args) => downloadProgress?.Invoke(video); localDownloader.OutputDataReceived += (sender, e) => { if (video.downloadState == DownloadState.Cancelled) { try { ((Process)sender)?.Kill(); } catch { } Plugin.logger.Info("Cancelled"); VideoLoader.DeleteVideo(video, false); YouTubeDownloader.externalProcesses.Remove(sender as Process); } // if(++outputCount % 10 != 0) return; ParseDownload(video, logProgress, e); }; localDownloader.ErrorDataReceived += (sender, e) => { if (e.Data.Length < 3) { return; } Plugin.logger.Error(e.Data); //TODO: check these errors are problems - re-download or skip file when an error occurs //video.downloadState = DownloadState.Cancelled; downloadProgress?.Invoke(video); if (video.downloadState == DownloadState.Cancelled || e.Data.Contains("Unable to extract video data")) { DownloadCancelled((Process)sender, video); } }; localDownloader.Exited += (sender, e) => { timer.Stop(); timer.Close(); StopCoroutine(countdown); DecrementDownloadCount(); if (video.downloadState == DownloadState.Cancelled) { Plugin.logger.Info("Cancelled"); VideoLoader.DeleteVideo(video, false); } else { video.downloadState = DownloadState.Downloaded; VideoLoader.SaveVideoToDisk(video); StartCoroutine(VerifyDownload(video)); Plugin.logger.Info( $"Done Downloading {video.title} with {VideosDownloading} remaining downloads"); } try { localDownloader?.Dispose(); } catch { } YouTubeDownloader.externalProcesses.Remove(localDownloader); // Don't load video since it will be loaded (or not) after VerifyDownload }; timer.Start(); yield return(localDownloader.Start()); StartCoroutine(countdown); // Plugin.logger.Debug("Started Downloaded For Realsies"); // Hook up our output to console localDownloader.BeginOutputReadLine(); localDownloader.BeginErrorReadLine(); } }