/// <summary> /// About window. /// </summary> /// <param name = "mainWindow"> /// The parent window. /// </param> /// <param name="programInfo"> /// This program's information (main project info). /// </param> /// <param name="assemblies"> /// Assemblies to use. /// </param> public About(MainProgramElements mainWindow, FileVersionInfo programInfo, ProjectAssemblies assemblies) { this.VersionInfo = new VersionInfo(programInfo, assemblies, disclaimer); this.DataContext = this.VersionInfo; this.mainWindow = mainWindow; InitializeComponent(); }
/// <summary> /// Url Manipulation window. /// </summary> /// <param name="add"> /// This is the Url Adding window. /// </param> /// <param name="mainWindow"> /// The parent window. /// </param> public UrlManipulation(bool add, MainProgramElements mainWindow) { this.DataContext = this.urlShapingVars; InitializeComponent(); this.defaultHeight = this.Height; this.defaultWidth = this.Width; this.videoQueue = mainWindow.Videos; this.MainWindow = mainWindow; this.persistantUrlIndex = mainWindow.CurrentlySelectedQueueIndex; this.add = add; this.Title = string.Format(CultureInfo.CurrentCulture, "{0} the Queue", add ? "Add Url(s) to" : "Modify Url(s) in"); this.basicManipulateUrlButton.Content = add ? "Add Url to the Queue" : "Modify Current Url"; if (!add && videoQueue.Any()) { this.avTextBox.Text = string.Join(string.Empty, videoQueue); this.urlShapingVars.BasicText = videoQueue[this.persistantUrlIndex].Location; this.urlShapingVars.AudioOnlyEnabled = videoQueue[this.persistantUrlIndex].IsAudioFile; this.urlShapingVars.SelectedFormat = this.formatComboBox.Items.IndexOf(videoQueue[this.persistantUrlIndex].Format); this.urlShapingVars.SelectedResolution = videoQueue[this.persistantUrlIndex].Quality; } else { this.avTextBox.Text = string.Format(CultureInfo.CurrentCulture, "{0} {1} Mp4 False (REMOVE!)", UrlShaping.ExampleText, UrlShaping.DefaultResolution); } }
/// <summary> /// About window. /// </summary> /// <param name = "mainWindow"> /// The parent window. /// </param> /// <param name="programInfo"> /// This program's information (main project info). /// </param> /// <param name="assemblies"> /// Assemblies to use. /// </param> public About (MainProgramElements mainWindow, FileVersionInfo programInfo, ProjectAssemblies assemblies) { this.VersionInfo = new VersionInfo (programInfo, assemblies, disclaimer); this.DataContext = this.VersionInfo; this.mainWindow = mainWindow; InitializeComponent(); }
/// <summary> /// Url Manipulation window. /// </summary> /// <param name="add"> /// This is the Url Adding window. /// </param> /// <param name="mainWindow"> /// The parent window. /// </param> public UrlManipulation (bool add, MainProgramElements mainWindow) { this.DataContext = this.urlShapingVars; InitializeComponent(); this.defaultHeight = this.Height; this.defaultWidth = this.Width; this.videoQueue = mainWindow.Videos; this.MainWindow = mainWindow; this.persistantUrlIndex = mainWindow.CurrentlySelectedQueueIndex; this.add = add; this.Title = string.Format(CultureInfo.CurrentCulture, "{0} the Queue", add ? "Add Url(s) to" : "Modify Url(s) in"); this.basicManipulateUrlButton.Content = add ? "Add Url to the Queue" : "Modify Current Url"; if (!add && videoQueue.Any()) { this.avTextBox.Text = string.Join(string.Empty, videoQueue); this.urlShapingVars.BasicText = videoQueue[this.persistantUrlIndex].Location; this.urlShapingVars.AudioOnlyEnabled = videoQueue[this.persistantUrlIndex].IsAudioFile; this.urlShapingVars.SelectedFormat = this.formatComboBox.Items.IndexOf(videoQueue[this.persistantUrlIndex].Format); this.urlShapingVars.SelectedResolution = videoQueue[this.persistantUrlIndex].Quality; } else this.avTextBox.Text = string.Format(CultureInfo.CurrentCulture, "{0} {1} Mp4 False (REMOVE!)", UrlShaping.ExampleText, UrlShaping.DefaultResolution); }
public void DownloadHandler (MainProgramElements mainWindow) { #region Initialization mainWindow.WindowEnabled = false; mainWindow.CurrentDownloadOutputText = "Starting Downloading Process...."; int selectedIndex = mainWindow.CurrentlySelectedQueueIndex; var urlList = mainWindow.Videos.ToList().AsReadOnly(); urlList.WriteToFile(Storage.QueueFile, ".bak"); List<Video> finishedVideos = new List<Video>(); int[] retryCount = new int[urlList.Count + 1]; const int maxRetrys = 4; Thread.Sleep(1000); #endregion #region Handle Download Cycle int position = 0, urlListCount = urlList.Count; while (position < urlListCount) { bool exceptionWasCaught = false; bool ableToRetryOnFail = retryCount[position] < maxRetrys; var video = urlList[position]; try { mainWindow.CurrentlySelectedQueueIndex = position; if (retryCount[position] <= 0) { mainWindow.CurrentDownloadOutputText = string.Format(CultureInfo.InstalledUICulture, "Beginning download from '{0}'", video.Location); } mainWindow.CurrentDownloadProgress = 0; //var result = await Task.Run(() => Download.SetupDownload(video, mainWindow)); var result = this.SetupDownload(video, mainWindow); if (result is DownloadCanceledException) { mainWindow.CurrentDownloadOutputText = result.Message; if (App.IsDebugging) result.Message.Log("Youtube Download Helper"); Thread.Sleep(!UserSettings.ContinueOnFail ? 1000 : 850); } else if (result != null) throw result; finishedVideos.Add(video); } catch (Exception ex) { exceptionWasCaught = true; var exceptionMessage = ex.Message; retryCount[position] += ex is NotSupportedException ? maxRetrys + 1 : 1; if (ableToRetryOnFail) { mainWindow.CurrentDownloadOutputText = string.Format(CultureInfo.InstalledUICulture, "URL {0}: {1}. Retrying.... ({2}/{3})", video.Position, exceptionMessage.Truncate(50), (retryCount[position]).ToString(CultureInfo.CurrentCulture), maxRetrys); } else if (!UserSettings.ContinueOnFail) { mainWindow.CurrentDownloadOutputText = exceptionMessage.Truncate(100); ex.Log(GenericCondition.None); break; } if(!UserSettings.ContinueOnFail) { Thread.Sleep(850); } } if (!exceptionWasCaught || (!ableToRetryOnFail && UserSettings.ContinueOnFail)) position++; } #endregion #region Final Steps bool noMajorErrors = retryCount.All(count => count <= maxRetrys); if (noMajorErrors || (!noMajorErrors && finishedVideos.Count() > 5)) { IEnumerable<Video> leftOverVideos = urlList.Where(url => finishedVideos.All(finishedUrl => !url.ToString().Equals(finishedUrl.ToString()))); leftOverVideos.Sort(); mainWindow.Videos = new ObservableCollection<Video>(leftOverVideos); } if (noMajorErrors) mainWindow.CurrentDownloadOutputText = "Finished!"; else if (string.IsNullOrWhiteSpace(mainWindow.CurrentDownloadOutputText)) { mainWindow.CurrentDownloadOutputText = "An Error Has Occurred!"; } if (mainWindow.Videos.Any()) { mainWindow.RefreshQueue(mainWindow.Videos, selectedIndex > mainWindow.Videos.All() ? 0 : selectedIndex); } mainWindow.Videos.WriteToFile(Storage.QueueFile); mainWindow.WindowEnabled = true; #endregion }
private void Downloader (YouTubeVideo video, MainProgramElements mainWindow, bool isAudio) { string temporaryDownloadPath = Path.Combine(this.UserSettings.TemporarySaveLocation, video.FullName); string movingPath = Path.Combine(this.UserSettings.MainSaveLocation, video.FullName); if (this.UserSettings.ValidationLocations.All(path => !File.Exists(Path.Combine(path, video.FullName)) && !File.Exists(movingPath)) { if(isAudio) { var audioDownloader = new AudioDownloader (video, temporaryDownloadPath);; audioDownloader.AudioExtractionProgressChanged += (sender, args) => mainWindow.CurrentDownloadProgress = (int)(85 + args.ProgressPercentage * 0.15); audioDownloader.Execute(); } else { var videoDownloader = new VideoDownloader (video, temporaryDownloadPath); videoDownloader.DownloadProgressChanged += ((sender, args) => mainWindow.CurrentDownloadProgress = (int)args.ProgressPercentage); videoDownloader.Execute(); } if (!temporaryDownloadPath.Equals(movingPath, StringComparison.OrdinalIgnoreCase)) File.Move(temporaryDownloadPath, movingPath); } else { throw new DownloadCanceledException(string.Format(CultureInfo.CurrentCulture, "The download of #{0} '{1}({2})' has been canceled because it already existed.", videoToUse.Position, RemoveIllegalPathCharacters(video.Title).Truncate(10), videoToUse.Location.Truncate(100))); } }
// private void DownloadThread () // { // // } private Exception SetupDownload (Video video, MainProgramElements mainWindow) { try { IEnumerable<YouTubeVideo> videos = new List<YouTubeVideo>(); using(var service = Client.For(YouTube.Default)) { videos = service.GetAllVideos(video.Location); } YouTubeVideo currentVideo = default(YouTubeVideo); if(video.IsAudioFile || video.VideoFormat != VideoFormat.Mp4 || (!video.IsAudioFile && video.VideoFormat == VideoFormat.Mp4 && video.Quality == 360)) { currentVideo = videos.FirstOrDefault(info => !video.IsAudioFile ? (info.Format == video.VideoFormat && info.Resolution == video.Quality) : (video.AudioFormat == AudioFormat.Mp3 && info.AudioFormat == video.AudioFormat && info.AudioBitrate == video.Quality)); } if (currentVideo != default(YouTubeVideo)) { mainWindow.CurrentDownloadOutputText = string.Format(CultureInfo.InstalledUICulture, "Downloading (#{0}/{1}) '{2}' at {3}{4}", video.Position, mainWindow.Videos.Count(), currentVideo.FullName.Truncate(56), !video.IsAudioFile ? currentVideo.Resolution : currentVideo.AudioBitrate, !video.IsAudioFile ? "p resolution" : " bitrate"); this.Downloader(currentVideo, mainWindow, video.IsAudioFile); return null; } else { var formatsEstablished = new List<VideoFormat> (); var qualitiesEstablished = new List<int> (); using (StreamWriter outfile = new StreamWriter ("Acceptable Options.txt")) { outfile.Write(string.Format(CultureInfo.CurrentCulture, "This file will show you all formats available for the current URL, as well as the resolutions that are acceptable for that URL.\n\n{0}:\n\nVideo Formats:\n", video.Location)); for (var position = videos.Where(info => info.Format != VideoFormat.Unknown && formatsEstablished.All(format => info.Format != format)).Select(info => info.VideoType).GetEnumerator(); position.MoveNext();) { VideoFormat format = position.Current; formatsEstablished.Add(format); switch (format) { case VideoFormat.Mp4: outfile.Write(string.Format(CultureInfo.CurrentCulture, "Format: {0} | Resolution: {1}p\n", format, "360")); break; default: var validVideos = videoInfos.Where(videoInfo => (videoInfo.Resolution >= UrlShaping.MinimumQuality[typeof(VideoType)] && videoInfo.Resolution <= UrlShaping.MaximumQuality) && videoInfo.VideoType.Equals(format) && qualitiesEstablished.All(quality => videoInfo.Resolution != quality)).Select(videoInfo => videoInfo.Resolution); foreach (int currentResolution in validVideos) { outfile.Write(string.Format(CultureInfo.CurrentCulture, "Format: {0} | Resolution: {1}p\n", format, currentResolution)); } break; } qualitiesEstablished.Clear(); } outfile.Write("\nAudio Formats:\n"); var audioQualitiesEstablished = new List<AudioType> (); for (var position = videoInfos.Where(info => info.AudioType != AudioType.Unknown && audioQualitiesEstablished.All(quality => info.AudioType != quality)).Select(info => info.AudioType).GetEnumerator(); position.MoveNext();) { AudioType format = position.Current; audioQualitiesEstablished.Add(format); var validAudioTracks = videoInfos.Where(videoInfo => (videoInfo.AudioBitrate >= UrlShaping.MinimumQuality[typeof(AudioType)] && videoInfo.AudioBitrate <= UrlShaping.MaximumQuality) && videoInfo.AudioType.Equals(format)).Select(videoInfo => videoInfo.AudioBitrate); foreach (int currentQuality in validAudioTracks) { outfile.Write(string.Format(CultureInfo.CurrentCulture, "Format: {0} | Bitrate: {1}\n", format, currentQuality)); } qualitiesEstablished.Clear(); } } throw new NotSupportedException ("An acceptable options file has been exported to the program's root folder. Check there for more information."); } } catch (Exception ex) { return ex; } }
private void Downloader (IEnumerable<VideoInfo> videoInfos, MainProgramElements mainWindow, Video videoToUse) { bool audioTrack = videoToUse.IsAudioFile; VideoInfo video = videoInfos.First(info => !audioTrack ? (info.VideoType == videoToUse.VideoFormat && info.Resolution == videoToUse.Quality) : (info.AudioType == videoToUse.AudioFormat && info.AudioBitrate == videoToUse.Quality)); if (video.RequiresDecryption) DownloadUrlResolver.DecryptDownloadUrl(video); string videoName = string.Format(CultureInfo.InvariantCulture, "{0}{1}", RemoveIllegalPathCharacters(video.Title), !audioTrack ? video.VideoExtension : video.AudioExtension); string temporaryDownloadPath = Path.Combine(this.UserSettings.TemporarySaveLocation, videoName); string movingPath = Path.Combine(this.UserSettings.MainSaveLocation, videoName); if (this.UserSettings.ValidationLocations.All(path => !File.Exists(Path.Combine(path, videoName))) && !File.Exists(movingPath)) { if(audioTrack) { var audioDownloader = new AudioDownloader (video, temporaryDownloadPath);; audioDownloader.AudioExtractionProgressChanged += (sender, args) => mainWindow.CurrentDownloadProgress = (int)(85 + args.ProgressPercentage * 0.15); audioDownloader.Execute(); } else { var videoDownloader = new VideoDownloader (video, temporaryDownloadPath); videoDownloader.DownloadProgressChanged += ((sender, args) => mainWindow.CurrentDownloadProgress = (int)args.ProgressPercentage); videoDownloader.Execute(); } if (!temporaryDownloadPath.Equals(movingPath, StringComparison.OrdinalIgnoreCase)) File.Move(temporaryDownloadPath, movingPath); } else { throw new DownloadCanceledException(string.Format(CultureInfo.CurrentCulture, "The download of #{0} '{1}({2})' has been canceled because it already existed.", videoToUse.Position, RemoveIllegalPathCharacters(video.Title).Truncate(10), videoToUse.Location.Truncate(100))); } }
/// <summary> /// Options window. /// </summary> /// <param name="mainWindow"> /// The parent window. /// </param> public Options(MainProgramElements mainWindow) { this.DataContext = this.savedSettings; InitializeComponent(); this.MainWindow = mainWindow; }
/// <summary> /// Options window. /// </summary> /// <param name="mainWindow"> /// The parent window. /// </param> public Options (MainProgramElements mainWindow) { this.DataContext = this.savedSettings; InitializeComponent(); this.MainWindow = mainWindow; }