private IEnumerator DownloadVideo() { downloading = true; if (!updated) { yield return(new WaitUntil(() => updated)); } VideoDownload download = videoQueue.Peek(); VideoData video = download.video; if (video.downloadState == DownloadState.Cancelled || download.downloadAttempts > MaxRetries) { // skip videoQueue.Dequeue(); if (videoQueue.Count > 0) { // Start next download DownloadVideo(); } else { // queue empty downloading = false; yield break; } } StopCoroutine(Countdown(download)); video.downloadState = DownloadState.Downloading; downloadProgress?.Invoke(video); download.Update(); string levelPath = VideoLoader.GetLevelPath(video.level); if (!Directory.Exists(levelPath)) { Directory.CreateDirectory(levelPath); } string videoFileName = video.title; // Strip invalid characters foreach (var c in Path.GetInvalidFileNameChars()) { videoFileName = videoFileName.Replace(c, '-'); } videoFileName = videoFileName.Replace('\\', '-'); videoFileName = videoFileName.Replace('/', '-'); video.videoPath = videoFileName + ".mp4"; // Download the video via youtube-dl ydl = new Process(); ydl.StartInfo.FileName = Environment.CurrentDirectory + "\\Youtube-dl\\youtube-dl.exe"; ydl.StartInfo.Arguments = "https://www.youtube.com" + video.URL + " -f \"" + VideoQualitySetting.Format(quality) + "\"" + // Formats " --no-cache-dir" + // Don't use temp storage " -o \"" + levelPath + $"\\{videoFileName}.%(ext)s\"" + " --no-playlist" + // Don't download playlists, only the first video " --no-part"; // Don't store download in parts, write directly to file ydl.StartInfo.RedirectStandardOutput = true; ydl.StartInfo.RedirectStandardError = true; ydl.StartInfo.UseShellExecute = false; ydl.StartInfo.CreateNoWindow = true; ydl.EnableRaisingEvents = true; ydl.Start(); // Hook up our output to console ydl.BeginOutputReadLine(); ydl.BeginErrorReadLine(); 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 = float.Parse(match.Value.Substring(0, match.Value.Length - 1)) / 100; downloadProgress?.Invoke(video); download.Update(); } } }; ydl.ErrorDataReceived += (sender, e) => { if (e.Data.Length < 3) { return; } //to do: check these errors are problems - redownload or skip file when an error occurs //video.downloadState = DownloadState.Cancelled; downloadProgress?.Invoke(video); download.Update(); }; ydl.Exited += (sender, e) => { StopCoroutine(Countdown(download)); if (video.downloadState == DownloadState.Cancelled) { VideoLoader.Instance.DeleteVideo(video); } else { video.downloadState = DownloadState.Downloaded; VideoLoader.SaveVideoToDisk(video); StartCoroutine(VerifyDownload(video)); } videoQueue.Dequeue(); if (videoQueue.Count > 0) { // Start next download DownloadVideo(); } else { // queue empty downloading = false; } ydl.Dispose(); }; }
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(); }; }
private IEnumerator DownloadVideo() { Plugin.logger.Debug($"Starting Download"); downloading = true; Plugin.logger.Debug($"Starting Download"); if (!updated) { yield return(new WaitUntil(() => updated)); } Plugin.logger.Debug($"Starting Download2"); VideoDownload download = videoQueue.Peek(); Plugin.logger.Debug($"Starting Download3"); VideoData video = download.video; Plugin.logger.Debug($"Starting Download with {download.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); StopCoroutine(Countdown(download)); Plugin.logger.Debug($"Counting"); video.downloadState = DownloadState.Downloading; downloadProgress?.Invoke(video); Plugin.logger.Debug($"Invoked"); download.Update(); Plugin.logger.Debug($"Updated"); ydl = MakeYoutubeProcessAndReturnIt(video); Plugin.logger.Debug($"yt command: {ydl.StartInfo.FileName} {ydl.StartInfo.Arguments}"); ydl.Start(); // Hook up our output to console ydl.BeginOutputReadLine(); ydl.BeginErrorReadLine(); 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 = float.Parse(match.Value.Substring(0, match.Value.Length - 1)) / 100; downloadProgress?.Invoke(video); download.Update(); if (video.downloadState == DownloadState.Cancelled) { (sender as Process).Kill(); } } Plugin.logger.Info(e.Data); } }; ydl.ErrorDataReceived += (sender, e) => { if (e.Data.Length < 3) { return; } //TODO: check these errors are problems - re-download or skip file when an error occurs //video.downloadState = DownloadState.Cancelled; downloadProgress?.Invoke(video); download.Update(); }; ydl.Exited += (sender, e) => { StopCoroutine(Countdown(download)); if (video.downloadState == DownloadState.Cancelled) { Plugin.logger.Debug("Cancelled"); VideoLoader.Instance.DeleteVideo(video); } else { video.downloadState = DownloadState.Downloaded; 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; } ydl.Dispose(); }; }